Jump to content
IGNORED

First steps in TI9900 assembly language with prior knowledge of 6502


Dexter

Recommended Posts

Workflow to real hardware is less than convenient. I think the HDX solution is probably the best, but that requires a real PEB. If I ever get around to doing more hardware, fixing this problem is high on the list.

 

I'm glad you like the Textpad highlighting. I like a dark background for coding which does not always appeal to some people. Unfortunately I'm growing too dependent on intelligent editors these days, so I'm searching for an alternative editor.

Link to comment
Share on other sites

Don't forget the new comand line tools from ralphb here

 

You should be able to assemble and copy the object files to the CF card in one step.

 

I only tested the GPL assembler and it works perfectly, so I suppose the other tools too.

Edited by lucien2
Link to comment
Share on other sites

The assembler is creating object files without any header. One way around it is to create a disk image using TI99Dir and let the assembler copy the object file to the disk image. Then you can open the disk image in TI99Dir and copy the file to your HDX dir, this time with a header. You can also copy the disk image directly to your CF card using TI99Dir, which is probably the easiest.

 

It's not just a question of header - they are actually Windows text files with an OBJ extension. ;)

 

So yeah, what you've done is the easiest workaround.

Link to comment
Share on other sites

@ Matthew

Unfortunately I'm growing too dependent on intelligent editors these days, so I'm searching for an alternative editor.

 

Perhaps this could be interesting:

http://blog.3d-logic.com/2012/05/12/introducing-vintage-studio/

 

 

@ lucien2

Don't forget the new comand line tools from ralphb here

 

Thanks, hadn’t found them yet, I’ll have a look at it...

 

Link to comment
Share on other sites

I’ve been watching Tursi’s debug video. :thumbsup:

When I write a EA3 program without using AORG >XXXX, i.e. not specifying a start address, how do I find the actual location of the program? I know the REF/DEF Table starts at >3FFF backwards. But how do I find the code in the debugger? Perhaps I have to clarify that the program in question does use the infamous KSCAN routine, and stopping the program, mostly ends up somewhere in the ROM routines.

 

 

And two trivial questions:

Are ; and * the same in E/A and WinAsm99?

What does “step over”, F3 actually do in the debugger in Classic99?

bal068.a99

Edited by Dexter
Link to comment
Share on other sites

If it's not at >A000 it's probably somewhere in the >2000s, but unless you want to load your program together with other assembly routines you can just specify AORG >A000 to be safe. I think I have done that in almost every program I have written.

 

A comment at the beginning of a line must start with *. After the opcode and a white space anything goes. You can use ; or * or nothing. I always use * for consistency but I think it's more popular to use ;.

 

The difference between F2 and F3 in Classic99 is that if you're currently at a subroutine call instruction (BL or BLWP) F3 will step over (and execute) the entire routine but F2 will step into it.

 

[Edit: Organizing your code into short subroutines is, of course, essential for preventing your assembly project from becoming a mess, but it is also really important with respect to debugging and profiling. If you organize your main loop as a sequence of subroutine calls you can easily try to run you code without some of them, and you can easily measure how long each call takes (using Classic99's T(XXXX-YYYY) feature. I have always timed my games and demos so that the main loop runs within one video frame, which corresponds to 50000 CPU cycles on NTSC machines.]

Link to comment
Share on other sites

The REF/DEF table is something like 8-bytes per entry (I think) consisting of a 6-byte name and two-bytes for the address of the routine.

 

Before you load your code you can put a break point at >A000, which is where your code will be loaded unless there are other routines / programs there were loaded in memory before your code. You can also inspect the REF/DEF table before your program is loaded to see if anything else is loaded.

 

You can look at various types of memory in Classic99, so you want to make sure you select CPU memory for the REF/DEF table and set the address to something like >3F00, which should let you easily see 32 entries.

 

After your code is loaded and stopped on the break point you set, open the listing generated by the assembler and follow along as you step through the code.

Link to comment
Share on other sites

you can just specify AORG >A000 to be safe.

Yeah, that’s just what I’m going to do. On the C64 it’s mandatory anyway.

The difference between F2 and F3 in Classic99 is that if you're currently at a subroutine call instruction

Ah, that’s very convenient, that KSCAN routine is awfully long. :)

Organizing your code into short subroutines...

I totally agree, it’s like putting building block together!

I have always timed my games and demos so that the main loop runs within one video frame, which corresponds to 50000 CPU cycles on NTSC machines.

Very nice! Have to try that feature. Although my console is PAL, I’m guessing, after putting in an F18A, I also will have the 60Hz, like NTSC has. For now, I should have 60000 CPU cycles. :D

The REF/DEF table is something like 8-bytes per entry (I think) consisting of a 6-byte name and two-bytes for the address of the routine.

I found out when I do a RAM Dump (F10), I can easily inspect that file with a hex editor.

 

 

The whole puzzle is beginning to make sense now, although I really always need a reference for the command syntax, especially when I’m going to switch to 65816 or AVR assembly again. Perhaps it could be an age related thing. ;)

 

Can’t wait to put something together, but I’m still going through the Lottrup book.

Link to comment
Share on other sites

The Lottrup book is great and was the main text that allowed me to actually start writing useful assembly programs back when I was learning. That said, the code examples are also some of the most inefficient you would write. Be mindful about what you decide to pick up and take away from the book. I covered a few examples (clearing the screen, setting "bitmap mode") in my assembly thread.

Link to comment
Share on other sites

The Lottrup book is great and was the main text that allowed me to actually start writing useful assembly programs back when I was learning. That said, the code examples are also some of the most inefficient you would write. Be mindful about what you decide to pick up and take away from the book. I covered a few examples (clearing the screen, setting "bitmap mode") in my assembly thread.

Yes, I understand what you mean, I'm studying the book and your thread in parallel. The book gives me the basic knowledge, but I see why to use your fast alternative code. The three main cartridges involving the use of Machine Language:

 

· Extended BASIC

· Editor/Assembler

· MiniMemory

 

have different addresses for those “common” routines. Also a source of confusion, but I found a small comparison list. In some of your code (viewport), there is the joystick addressed without the use of KSCAN. At the moment I have no knowledge of the CRU, so I don’t know how the keyboard is read, but I already experienced that it is sluggish. Even in PARSEC there is a delay, or doesn’t PARSEC use the KSCAN routine?

Link to comment
Share on other sites

Here is a general routine for reading joystick 1 using CRU:

*********************************************************************
*
* Read joystick
*
JOYST  LI   R12,>0024              * CRU address of the column decoder 
       LI   R0,>0600               * Column 6, i.e joystick #1
       LDCR R0,3                   * Select it
       LI   R12,>0006              * Base CRU address for joystick 1
*      Init variables       
       CLR  R0                     * Fire flag
       CLR  R1                     * DX
       CLR  R2                     * DY
*      Fire button
       TB   0
       JEQ  JOYST0
       SETO R0                     * Set fire flag
*      Left
JOYST0 TB   1
       JEQ  JOYST1
       SETO R1                     * DX=-1
       JMP  JOYST2
*      Right
JOYST1 TB   2
       JEQ  JOYST2
       LI   R1,1                   * DX=1
*      Down
JOYST2 TB   3
       JEQ  JOYST3
       LI   R2,1                   * DY=1
       JMP  JOYST4
*      Up
JOYST3 TB   4
       JEQ  JOYST4
       SETO R2                     * DY=-1
JOYST4 NOP                         * Here you should do something with R0, R1 and R2...
       B    *R11
*// JOYST
  • Like 1
Link to comment
Share on other sites

Working with the CRU lines is less difficult that it seems at first sight. In fact, the TI keyboard and the joysticks are simple switches that you can test with the CRU operations. Here is a drawing that I created when I implemented the Arduino USB interface.

 

The lines P2 to P5 are the selector lines. When you set them according to the values shown at the top, you activate a column in this figure. When you press the a key, the respective INT line is pulled down to 0.

 

P2 is CRU address 0024 (bit 18), P3 is CRU address 0026 (bit 19) ... keep in mind that the CRU addresses increase by 2. You can load the lines by a LDCR command or by single SBO/SBZ.

 

The INT3-INT10 lines are CRU bits 3 - 10 (i.e. addresses 0006 to 0014).

post-35000-0-99915200-1429394869_thumb.png

Link to comment
Share on other sites

Working with the CRU lines is less difficult that it seems at first sight. In fact, the TI keyboard and the joysticks are simple switches that you can test with the CRU operations. Here is a drawing that I created when I implemented the Arduino USB interface.

 

The lines P2 to P5 are the selector lines. When you set them according to the values shown at the top, you activate a column in this figure. When you press the a key, the respective INT line is pulled down to 0.

 

P2 is CRU address 0024 (bit 18), P3 is CRU address 0026 (bit 19) ... keep in mind that the CRU addresses increase by 2. You can load the lines by a LDCR command or by single SBO/SBZ.

 

The INT3-INT10 lines are CRU bits 3 - 10 (i.e. addresses 0006 to 0014).

That answer took a long time, but deliberately. Before just asking, I tried to wrap my head around the whole CRU concept. It’s certainly not as easy to understand as the 6522 VIA. I read about the CRU in

· “Fundamentals of TI-99/4A Assembly Language by M.S. Morley”,

· “HARDWARE MANUAL for the Texas Instruments 99/4A by M.L. Bunyard” and

· “TMS9901 Programmable Systems Interface Data Manual”.

 

On the hardware side, I believe the interface between the 9900 and 9901 is serial, while the interface between the keyboard, joystick, cassette and the 9901 is through the 2-Line to 4-Line Decoders (LS156) and direct I/O ports. They also talk about Latches, are they embedded in the 9901? P5 is *only* Alpha Lock?

post-41771-0-28482400-1429547612_thumb.png

 

post-41771-0-52737500-1429547638_thumb.png

However, from the software side, there are a few CRU commands and workspace register R12.

 

post-41771-0-42147000-1429547607_thumb.png

post-41771-0-88244900-1429547609_thumb.png

There is no data bus involved, just the address bits. Unfortunately, I don’t understand how to “get” or “put” data to “what” storage (R12?). Could you explain what the code does with the hardware on the previously posted joystick example?

*********************************************************************
*
* Read joystick
*
JOYST  LI   R12,>0024         * CRU address of the column decoder
       LI   R0,>0600          * Column 6, i.e joystick #1
       LDCR R0,3              * Select it
       LI   R12,>0006         * Base CRU address for joystick 1
*      Init variables      
       CLR  R0                * Fire flag
       CLR  R1                * DX
       CLR  R2                * DY
*      Fire button
       TB   0
       JEQ  JOYST0
       SETO R0                * Set fire flag
*      Left
JOYST0 TB   1
       JEQ  JOYST1
       SETO R1                * DX=-1
       JMP  JOYST2
*      Right
JOYST1 TB   2
       JEQ  JOYST2
       LI   R1,1              * DX=1
*      Down
JOYST2 TB   3
       JEQ  JOYST3
       LI   R2,1              * DY=1
       JMP  JOYST4
*      Up
JOYST3 TB   4
       JEQ  JOYST4
       SETO R2                * DY=-1
JOYST4 NOP                    * Here you should do something with R0, R1 and R2...
       B    *R11
*// JOYST

As I understand, this is just polling, no interrupts involved?

Link to comment
Share on other sites

I'm likely going to have the opposite problem here.

I recently picked up an Apple IIe system and the first thing I did was obtain this book Apple II Assembly Language De Jong Blacksburg First Edition First Print 1982

I am anticipating that it's going to be hard to learn 6502 assembly coming from the TMS9900...

And no, I'm not abandoning the TI, just broadening my horizons :)

Link to comment
Share on other sites




I'm likely going to have the opposite problem here.


I’m not an expert, but if you need any help or advice, I’m glad to help, as far as I can. There are also non computer brand specific books which are excellent, with the basics, but also with very useful standard sub routines.

 

Probably the best book is:

“6502 Assembly Language Programming - by Lance A. Leventhal”

followed by

“Programming the 6502 – by Rodnay Zaks”

And tons more, all available as PDF. OTOH, a real book is often more appealing.

 

A great asset is that the Apple II has a built in monitor.

 

If you need to set up a tool chain with editor and cross assembler, just give the word. The binaries are instantly usable on the C64, so I also expect them to be on the Apple II.

 

First is to determine if you’re encountering the MOS6502 or the 65C02. I don’t know much about the Apple II in particular, but I know that much, that at a certain point they “enhanced” their model with the 65C02 and a ROM update. The latter has some extra useful opcodes, but lack the illegal ones. It also uses much less energy and won’t get that hot.

 




I am anticipating that it's going to be hard to learn 6502 assembly coming from the TMS9900...

 

 

Except for the things I encounter, You might be right, in terms of dealing with 8-bit boundaries. Especially setting up loops greater than 256, you’d need nested loops.

 

A few differences between the 6502 and 9900 I could come up with:

6502                             <->      9900
A, X, Y registers                <->      16 relocatable general purpose registers
8-bit                            <->      16-bit
little endean                    <->      big endean
branches are short, relative     <->      branches are long
jumps are long                   <->      jumps are short, relative
bit 7 = MSB                      <->      bit 0 = MSB
VIA 6522                         <->      CRU

Edited by Dexter
  • Like 1
Link to comment
Share on other sites

Thanks for the overview. It feels weird to only have 3 registers compared to 16. Almost like taking an evolutionary step back :)

We'll see how things go.

My first encounter with an Apple II was in college when one of my neurobiology professors brought his Apple II system to class and demonstrated his simulation of the neuron membrane depolarization/repolarization (action potential) circa 1984. From the speed of execution as I recall it, I believe it was programmed in Applesoft Basic. I was fascinated with computer simulations ever since. At the time I already had a TI 99/4A, but it was barebone without even Extended Basic and only a cassette cable, and I didn't think I could reproduce that simulation on it without high res graphics. Well, now I know I can by simply redefining characters like what Tursi or myself have done with the Archimedes spiral demo, and I'm going to program it as soon as I re-familiarize myself with the basic electrophysiology equations (I still have my original texbook!).

In any case, I have lusted for an Apple II computer since that college demo, and finally broke down and got one on Ebay a few decades later :D. I have visions of interfacing it to the TI, possibly for a 2 player networked game. Should be feasible.

Link to comment
Share on other sites

 

In any case, I have lusted for an Apple II computer since...

I know that feeling for the TI... :love:

IIRC, all the II computers ran the 6502 until the IIGS. It was the last in the line and did not allow the illegal opcodes. That must have been when they switched to the 65C02.

 

 

Well, I’m sure the IIGS has my beloved 65816 :), the 16-bit successor of the 6502. I don’t know how common the “enhanced” update was, but you can perform the update by yourself, by getting a CMOS 65C02 and burning the enhanced ROMs on EPROMs.

http://applemuseum.bott.org/sections/computers/IIe.html

 

Edit

Found it:

http://en.wikipedia.org/wiki/Apple_IIe#The_Enhanced_IIe

 

http://www.reactivemicro.com/product_info.php?products_id=55

Edited by Dexter
Link to comment
Share on other sites

@Dexter: I've been considering to put the following into ninerpedia and put a pointer here, but I'll try a start here and probably add some more words later on ninerpedia.

 

First of all, many people (including me) were thinking of the TMS9901 when talking about the "CRU". I do not know how this happened; maybe there were some ambiguous formulations in the documents from Texas Instruments. In fact, the CRU is an integral part of the TMS9900 CPU (and of other CPUs from TI). The CRU is a bit-serial interface with an own address space, but sharing the address bus with the memory space.

 

The CRU uses a clock line (CRUCLK), an output line, and an input line. Via the latter two lines, bits are transferred between the CPU and devices that are connected to them. For instance, the TMS9901 is a programmable system interface (official name) which is controlled via CRU; to some extend this reminds of circuits like the 8574 in I²C systems.

 

In order to address a device on the CRU bus, the memory address bus is re-used. When a bit shall be read or set, the current value of R12 is put on the address bus. You can now use some decoder to activate a device, for instance, when address 0x1100 appears on the address bus, and in that case, get the bit from the CRUOUT line.

 

One thing that must be considered is that there are only even CRU addresses (aka port addresses). The first address is 0000, then we have 0002, 0004, etc. The reason for that is pretty simple: The address bus cannot have an odd value, because the CPU does not have an A15 line. The A15 that you can find on the board is a fake A15 which is generated by the chipset.

 

Now that you have a value in R12, when you do a SBO 0, you send a 1 bit over the CRUOUT line. When you do a SBZ 0, you send a 0 bit.

 

When you do a SBO x with x=1...+127 or -1...-128, this offset x is added on the address bus value, but it is multiplied by 2 before (otherwise odd values would again not be allowed). So if R12=0x1100, when you do a SBO 3, this has the same effect as if you had R12=0x1106, and you did a SBO 0.

 

In the opposite direction, in order to read a bit from the given address, you do a TB x. The bit is put into the EQ bit of the status register, which means you can do a JEQ / JNE after TB.

 

These examples are for single bit transfer. There are two commands that serve to do a multiple bit transfer from / into subsequent locations. In order to set multiple bits by one command, you use the Load CRU command (LDCR). However, you cannot use an address offset, so the address is taken from R12 unchanged. In order to read multiple bits you use the Store CRU command (STCR).

 

----

 

So now for the TMS9901. This circuit is mapped into port addresses 0x0000 - 0x003e for a total of 32 ports (0x40 / 2). The first 16 ports are named CONTROL / INT1 / INT2 ... / INT15. These ports can be used as input lines. When you call TB 1, for example, you get the current value of INT1.

 

Another interesting detail is that these lines can be configured to trigger an interrupt. When you do a SBO 1, the INT1 line will trigger an interrupt when the value becomes 0 (the lines are actually called /INTx). The 9901 has four interrupt priority signals: When an interrupt shall be raised, the lines IC0 - IC3 tell the CPU which INT line caused the interrupt (the lowest number when there are more than one). These four lines give a value 0 - 15, and you could now - theoretically - mask those interrupts with an appropriate LIMI instruction. However, TI decided to go for a simpler design and did not use the IC0-IC3 lines; thus, every external interrupt in the CPU has level 1, unless it is RESET or LOAD. Hence, the only useful LIMIs are LIMI 0 and LIMI 1, and for some reason they use LIMI 2 instead.

 

Back to the 9901. You need not configure those lines to raise interrupts and still be able to read them, either bit by bit using TB, or a sequence of bits with STCR.

 

The next 16 ports of the 9901 are programmable inputs / outputs, labeled P0-P15. They are latched, so they keep the value that you write into them by SBZ, SBO, or LDCR. If you have a look at the above keyboard circuit you see that some of these P ports are used to activate a column. This is done by a decoder that is fed from the P lines.

 

When you press a key, the level of the column shows up on the respective row. This can then be read with TB or STCR.

 

The Alpha Lock key has its own line P5, and I think you should set the other lines to 0 (but I have to check that). When you do a SBO 21 (this is mapped to P5) you can then do a TB 7 (which is mapped to INT7). You can already guess why Alpha Lock affects the Joystick Up direction.

 

ähm ... maybe I should stop here and you tell me whether this made sense to you. :)

  • Like 2
Link to comment
Share on other sites

hey mizapf, don't stop there ;-)

 

Makes a very interesting read. CRU and 9901 always have been a bit of a mistery to me, although I used some of its functionality. That was mainly by reusing existing code snippets.

 

If only I'll be able to find this post when I need it in a couple of months... :-)

Link to comment
Share on other sites

Thank you! This is an EXCELLENT explanation. I’m going to use some colors to clarify.

 

BLACK, my own comments / questions

RED, I don’t understand

GREEN, perfectly clear

BLUE, don’t agree ;)

 

First of all, many people (including me) were thinking of the TMS9901 when talking about the "CRU". I do not know how this happened; maybe there were some ambiguous formulations in the documents from Texas Instruments. In fact, the CRU is an integral part of the TMS9900 CPU (and of other CPUs from TI). Indeed, that’s why it surprised me that the CRU interface has its own opcodes. The CRU is a bit-serial interface with an own address space, but sharing the address bus with the memory space. That’s a little weird, but perhaps I get it eventually.

 

The CRU uses a clock line (CRUCLK), an output line, and an input line. Via the latter two lines, bits are transferred between the CPU and devices that are connected to them. For instance, the TMS9901 is a programmable system interface (official name) which is controlled via CRU; to some extend this reminds of circuits like the 8574 in I²C systems.

 

In order to address a device on the CRU bus, the memory address bus is re-used. When a bit shall be read or set, the current value of R12 is put on the address bus. You can now use some decoder to activate a device, for instance, when address 0x1100 appears on the address bus, and in that case, get the bit from the CRUOUT line.

 

One thing that must be considered is that there are only even CRU addresses (aka port addresses). The first address is 0000, then we have 0002, 0004, etc. The reason for that is pretty simple: The address bus cannot have an odd value, because the CPU does not have an A15 line. The A15 that you can find on the board is a fake A15 which is generated by the chipset.

 

Now that you have a value in R12, when you do a SBO 0, you send a 1 bit over the CRUOUT line. When you do a SBZ 0, you send a 0 bit.

 

When you do a SBO x with x=1...+127 or -1...-128, this offset x is added on the address bus value, but it is multiplied by 2 before (otherwise odd values would again not be allowed). So if R12=0x1100, when you do a SBO 3, this has the same effect as if you had R12=0x1106, and you did a SBO 0. So one doesn’t need to set R12 all the time.

 

In the opposite direction, in order to read a bit from the given address, you do a TB x. The bit is put into the EQ bit of the status register, which means you can do a JEQ / JNE after TB. OK that’s an eye opener.

 

These examples are for single bit transfer. There are two commands that serve to do a multiple bit transfer from / into subsequent locations. In order to set multiple bits by one command, you use the Load CRU command (LDCR). However, you cannot use an address offset, so the address is taken from R12 unchanged. In order to read multiple bits you use the Store CRU command (STCR). Now I get it, how the LDCR and STCR commands work, explained in the scan a few posts earlier.

 

----

 

So now for the TMS9901. This circuit is mapped into port addresses 0x0000 - 0x003e for a total of 32 ports (0x40 / 2). The first 16 ports are named CONTROL / INT1 / INT2 ... / INT15. These ports can be used as input lines. When you call TB 1, for example, you get the current value of INT1.

 

Another interesting detail is that these lines can be configured to trigger an interrupt. When you do a SBO 1, the INT1 line will trigger an interrupt when the value becomes 0 (the lines are actually called /INTx). I understand: active low. The 9901 has four interrupt priority signals: When an interrupt shall be raised, the lines IC0 - IC3 tell the CPU which INT line caused the interrupt (the lowest number when there are more than one). These four lines give a value 0 - 15, and you could now - theoretically - mask those interrupts with an appropriate LIMI instruction. However, TI decided to go for a simpler design and did not use the IC0-IC3 lines; thus, every external interrupt in the CPU has level 1, unless it is RESET or LOAD. Hence, the only useful LIMIs are LIMI 0 and LIMI 1, and for some reason they use LIMI 2 instead. So the lines IC0 – IC3 only tell us which interrupt has occurred, while LIMI 0 masks out (disable) all interrupts except for RESET (not FNCT=) or LOAD. Bummer, but such design decisions happen, for instance with Commodore, the terribly slow IEC bus protocol. (cost and time pressure)

 

Back to the 9901. You need not configure those lines to raise interrupts and still be able to read them, either bit by bit using TB, or a sequence of bits with STCR. “raise” as in use?

 

The next 16 ports of the 9901 are programmable inputs / outputs, labeled P0-P15. They are latched, so they keep the value that you write into them by SBZ, SBO, or LDCR. If you have a look at the above keyboard circuit you see that some of these P ports are used to activate a column. This is done by a decoder that is fed from the P lines.

 

When you press a key, the level of the column shows up on the respective row. This can then be read with TB or STCR. Column: P2 – P5 Row: INTx.

 

The Alpha Lock key has its own line P5, and I think you should set the other lines to 0 (I’d guess so too) (but I have to check that). When you do a SBO 21 (this is mapped to P5) you can then do a TB 7 (which is mapped to INT7). You can already guess why Alpha Lock affects the Joystick Up direction. Yes, Up is shared with INT7.

 

ähm ... maybe I should stop here and you tell me whether this made sense to you. :)

Although, I’m not sure what you could explain more or better about the subject. :D

 

Next, I’m going to analyze the joystick code, and see if I understand everything.

 

Marco

 

Link to comment
Share on other sites

As for the input lines of the 9901: There are two ways to make use of them.

 

1. You can configure them to raise an interrupt. When the line becomes active (low), the 9901 will assert the INTREQ line towards the CPU. Also, it delivers the number of the input line that caused the interrupt via IC0-IC3 (and if there are multiple lines, the lowest number will be delivered). As I said, TI hard-wired the IC3-IC0 inputs on the CPU to 0001, so that when an interrupt is signaled, it is always level 1 (unless it is RESET or LOAD, which are level 0).

 

On the other hand, having 16 interrupt levels is less useful than you believe at first thought. The TMS9995, accordingly, dropped these lines and replaced them by INT1 and INT4, i.e. only two levels for external interrupts, which is already sufficient.

 

So if every input from the 9901 is sensed as level 1, how can you tell what line actually caused the interrupt? This is option 2.

 

2. You can read the level of the input line with TB or STCR. This is what I wanted to express above: When you choose not to arm the lines for interrupting, they are not dead but can still be read with the CRU commands.

 

Sharing the address bus is not so rare, as I found. The Z80 CPU (which I use in my lectures, sorry, TMS 9900 :) ) uses address lines A7-A0 for input/output operations. In case of such an operation you would decode those lines to find out which device shall be accessed; the value on A7-A0 is the port number.

 

The TMS9900 uses the whole address bus, but A0-A2 are set to 0 for the 9900 (can be used in the 9995).

 

Finally, as for the AlphaLock issue with Joystick up: Yes, the problem is that they are on the same line, but this should then happen for other combinations as well. I suppose there is another particularity with the Joystick, maybe a higher resistance.

 

This is what happens: When a column (of the figure shown above) is not selected, it is pulled high; when selected, the column becomes low. Now when you press a key, that level is put on the respective INT line, otherwise the line is pulled high (on the other side of the key). AlphaLock is usually depressed and therefore pulls up the INT7 line when not selected. Obviously the Joysticks resistance is too high, and it fails to lower the INT7 line sufficiently enough so that the 9901 reads a 1 instead of a 0.

 

I'd expect the same effect when you press and hold FCTN or 1,2,3,4, or 5, but I don't remember any report on that. Maybe no one tried yet.

Edited by mizapf
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...