If you're working on the 99/4A, there are two unused pins on the 9901 that you could program as outputs, and I believe that reading these pins will return the last data output. (Need to ensure that you write to the pins before reading from them in order to program them as outputs). There are another couple of pins you could use as flags but as these control the keyboard scanning and tape operation, you could only use them if not using the keyboard/tape, and you'd have to ensure that the console code did not change them when you're not looking.

The TMS9995 processor has an internal CRU flag register with 11 bits available for user-defined application. There is no internal CRU memory in the 9900 in the /4A.

You could of course use a bitmask with CPU memory to store 16 flags per word, but that would obviously require more instructions, and your example seems to have a-need-for-speed ...

The trick to remember with CRU bits is that they are hardware, not memory. The abiity to read them back is dependent on how the hardware is wired (with the bits in the 9901, I believe you can read them all back). It may not be a good idea to use the spare 9901 bits, though, as a lot of modifications use them. (Now, how many consoles are modded, I don't know).

In general, it's a neat idea, but probably not a safe operation. I don't think I'd count on it personally.

As for performance, you can look up the 9900 datasheet. CRU is not really very efficient since it needs to perform special operations on the bus and you only get a single bit.

TB n JNE adr

faster than

:

MOV Rn,Rnjne adr

All else being equal, TB takes the same number of cycles as MOV (14) but half the memory accesses (4:2). It's not clear to me whether CRU accesses trigger the wait state generator, I don't think they do. That means if your MOV is in fast RAM (as registers usually are), that TB and MOV Rn,Rn should take the same amount of time.

However, SBO and SBZ take 12 cycles to set the bit, while CLR and SETO are only 10. Of course, if you're saving memory, you probably don't want to waste 16 bits on a flag, so that difference may be moot.

If you need more than one bit, though, MOV totally wins, since you have to LDCR at a cost of 20+ cycles and then compare anyway.

Since there's no notable speed benefit and risk of hardware interference, it's probably not a good idea to store data in CRU bits. But you may be able to find a few safe spots to sneak data away if you're desperate.

Are you using multiple flags? Instead of one flag per byte or word, why not pack multiple bit flags into the same space? Not sure off the top of my head how you would implement bit flags in 9900, but in 6502 we would do something like

(where the +6 is because you wanted bit 3). It costs you 32 bytes for the table, but you could only store the flags you actually use. The test itself is one instruction, and while it'll be slower than the TB, not by much. (Especially if you can get the table into scratchpad, though I would not do that unless you do a LOT of bit tests). Still costs 6 bytes, though. You can make it four bytes by keeping FLAGS in a dedicated register, though -- with 15 GP registers that's more possible than on some machines.

(where the +6 is because you wanted bit 3). It costs you 32 bytes for the table, but you could only store the flags you actually use. The test itself is one instruction, and while it'll be slower than the TB, not by much. (Especially if you can get the table into scratchpad, though I would not do that unless you do a LOT of bit tests). Still costs 6 bytes, though. You can make it four bytes by keeping FLAGS in a dedicated register, though -- with 15 GP registers that's more possible than on some machines.

Hi,

Yes, I though of that, but the table is large!Another thing: COC must have a register for the second operand,so:

Nevertheless, that 8 bytes plus the table for ONE usage (where you wouldn't use a table if that was all you were doing.) Still, 8 bytes is still less than 10, and if your program used 16 bitflag operations, it evens out. More than that and it wins. It depends what the program does.

Also, your examples assume there is a single 16-bit @FLAGS variable... keep it in a register instead. Then you don't need to do the move and it works with COC. Does your compiler need all 16 registers?

Alternately, rather than having dedicated flags, just let the user have bitwise operations on their own variables.

All just suggestions, anyway. Looks like you've done great things with this!

(where the +6 is because you wanted bit 3). It costs you 32 bytes for the table, but you could only store the flags you actually use. The test itself is one instruction, and while it'll be slower than the TB, not by much. (Especially if you can get the table into scratchpad, though I would not do that unless you do a LOT of bit tests). Still costs 6 bytes, though. You can make it four bytes by keeping FLAGS in a dedicated register, though -- with 15 GP registers that's more possible than on some machines.

If you are using an assembler, can you do something like this (again, what I did in 6502):

Then you AND or ORA the appropriate equate in the code I provided earlier. This way the table is in the assembler and does not take up space in the final executable. This would assume that you can compare a register directly against a constant, which ISTR can be done in 9900?

I think CRU bits 22 and 23 are the cassette motor, correct? Can those be read back in for status? If people aren't using those (I don't know that many that still use cassettes), those might be pretty easy ones to set. Worst case scenario is someone's casette motor will turn on and off if the unit is set to play and the remote plug is plugged into the deck...

. ..Then you AND or ORA the appropriate equate in the code I provided earlier. This way the table is in the assembler and does not take up space in the final executable. This would assume that you can compare a register directly against a constant, which ISTR can be done in 9900?

AND IMMEDIATE for the constant >0C00 (bits 10 and 11 set) with Register 2: