Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

1 hour ago, PeteE said:

Thanks, Tursi.  I've grown to trust Classic99 based on how much work you've done to make it cycle accurate.

Well, to make the cycle counts accurate, anyway. It doesn't emulate every internal cycle like MAME does... though it's getting closer all the damn time. ;)

 

I think it's fixed, so I'll push the new version shortly.

  • Like 3
Link to comment
Share on other sites

In reviewing how CLR @VDPSTA works on the 9900 versus 9995 and what @PeteE is trying to do, I thought about using ABS @VDPSTA instead which requires reading VDPSTA with both CPU’s.

 

In reviewing ABS, I note that it is the original value (source operand) that sets the status register bits 0-4 and not the result.  Is this how MAME, @mizapf, and Classic99, @Tursi, work?

Link to comment
Share on other sites

55 minutes ago, Jeff White said:

@Tursi, I think ABS is rarely used.  Do we have a chart of instruction frequency?  ABS is special.  Is there any other assembly instruction that sets status bits on source operand?

 

All of the immediate instructions except LIMI and LWPI do: AI ANDI ORI LI CI(not sure how you would characterize this one?)

 

...lee

Link to comment
Share on other sites

Got a question.

 

Does the LOAD opcode >05 return anything to the PAB in VRAM beyond the status byte for a Program Image file?  Would the Myarc HFDC return anything more?  Perhaps the program start address and length of file?  This may be something very specific to the Myarc HFDC.

 

I've not been able to find any specific notes on the LOAD opcode, and an example of a file I am using suggests there is more going on.

 

Beery

Link to comment
Share on other sites

35 minutes ago, Jeff White said:

In reviewing how CLR @VDPSTA works on the 9900 versus 9995 and what @PeteE is trying to do, I thought about using ABS @VDPSTA instead which requires reading VDPSTA with both CPU’s.

I looked at ABS also, but initially dismissed it because the number of clock cycles isn't constant based on the source argument: (MSB=0) 12 cycles, (MSB=1) 14 cycles.  The MSB in the VDPSTA register (interrupt flag) will be 0 during scanout, so it would actually be fine.  Thanks!

 

Link to comment
Share on other sites

6 hours ago, Jeff White said:

@Tursi, I think ABS is rarely used.  Do we have a chart of instruction frequency?  ABS is special.  Is there any other assembly instruction that sets status bits on source operand?

My point is it's documented to operate that way even in the Editor/Assembler manual, which is light on detail. ;)

 

We did have someone run a summary of instruction frequency a few years ago, at least I think it was here on AA...

 

Link to comment
Share on other sites

12 hours ago, BeeryMiller said:

Does the LOAD opcode >05 return anything to the PAB in VRAM beyond the status byte for a Program Image file?  Would the Myarc HFDC return anything more?  Perhaps the program start address and length of file?  This may be something very specific to the Myarc HFDC.

Just recently (it was in the context of copying Adventure files from cassette to disk) I learned that LOAD does not deliver the number of actually loaded bytes, which really surprised me. This would have been trivial to achieve in the DSR; the GeneveOS XOP, however, does return the image size.

Link to comment
Share on other sites

  • 2 months later...
On 1/1/2021 at 6:50 AM, Asmusr said:

No you don't, you can use a hybrid mode sometimes referred to as 'half bitmap mode', see:

 

http://www.unige.ch/medecine/nouspikel/ti99/tms9918a.htm#hybrid bitmap

 

In this mode you have the advantage of bitmap mode colors but the same characters can be used all over the screen.  So you only need 4 KiB VDP memory instead of 12 KiB.

 

The downside is that you can only use sprites 0-7. If you use sprites 8-31 they will be duplicated (JS99er is the only emulator that emulates the sprite duplication, AFAIK). If you want to avoid the duplication but save some memory, you can use 3 pattern tables but only one color table - that will use 8 KiB. Flying Shark and Titanium, for instance, are using that mode. 

@Asmusr Which of the following hybrid-mode arrangements are you using in Flying Shark and Titanium?

 

Which VR3 and VR4 settings, please?

 

...trying to piece it together along with nouspikel's notes:

 

In summary, these would be the addresses of the tables in 8 possible situations:

VR3 VR4 Mask Top 3rd Middle 3rd Bottom 3rd
>1F >00 >07FF >0000 >0000 >0000
>9F >04 >07FF >2000 >2000 >2000
>3F >01 >0FFF >0000 >0800 >0000
>BF >05 >0FFF >2000 >2800 >2000
>5F >02 >17FF >0000 >0000 >1000
>DF >06 >17FF >2000 >2000 >3000
>7F >03 >1FFF >0000 >0800 >1000
>FF >07 >1FFF >2000 >2800 >3000

To group characters within a table, we could further alter the color table mask:

  • VR3 = >0F results in >400-byte tables. This means that characters >80-FF will have the same colors and definitions than characters >00-7F.
  • VR3 = >07 results in >200-byte tables. This means that characters >40-7F, >80-BF and >C0-FF will have the same colors and definitions than characters >00-3F.
  • At the extreme, VR3 = >00 results in >40-byte tables. As there are 8 bytes per characters, this means characters are arranged in 8 groups of 32 identical characters: chars 0-7 are identical to chars 8-15, 16-23, etc.
  • We could even get weird grouping schemes by using values like >02, >04, >55, etc.

The table below lists the six most logical values, plus two goofy ones (just for fun).

VR3 Mask Character grouping Chars Repeats
>00 >003F 0=8=16...=248
1=9=17...=249
7=15=23...=255
8 32
>01 >007F 0=16=32...=240
1=17=33...=241
15=31=47..=255
16 16
>03 >00FF 0=32=64...=216
1=33=65...=217
31=63=95...=255
32 8
>07 >01FF 0=64=128=192
1=65=129=193
63=127=191=255
64 4
>0F >03FF 0=128
1=129
127=255
128 2
>1F >07FF Each char is unique 256 1
>02 >00BF 0=8=32=40...
4=12=36=44...
16 16
>04 >013F 0=8=16=24=64...
32=40=48=56=96...
16 16

 

Link to comment
Share on other sites

The table on Thierry's page "In summary, these would be the addresses..." is always confusing me. If you consider the values in column 1 (VR3) the last three columns show the addresses of the color tables. If you consider the values in column 2 (VR4) the last three columns show the addresses of the pattern tables. But you shouldn't use the values in columns 1 and 2 together because that would place the color and pattern tables on top of each other. Bit value >80 of VR3 should usually always be the inverse of bit value >04 of VR4.    

Link to comment
Share on other sites

5 hours ago, Asmusr said:

But you shouldn't use the values in columns 1 and 2 together because that would place the color and pattern tables on top of each other.

That’s exactly what I find confusing. There needs to be two separate tables. One for V3 and another for V4. That will clarify things. His V3/V4 table does unnecessarily confuse.

Link to comment
Share on other sites

Unfortunately, both registers impact the masking as a whole, rather than being hard split for one table or the other.

 

I don't know if this helps, but my notes give me something like this:

 

Reg3 MSB (mask >80) determines the base address of the color table, either >2000 or 0. Obviously this is a shift internally, but there are only two legal values. ;) 

 

The rest of Reg3 (mask >7F) sets the mask for the color table. It is shifted up 6 bits with all the new bits being 1. This is an address mask, so the smallest value (>00) would shift the zeros up 6 bits and end up with xx00 0000 0011 1111, or >03F. That allows a 64 byte color table (so, just 8 characters). The biggest value, >7F, becomes xx01 1111 1111 1111, or >1FFF. That's an 8k color table, or 1024 characters (but, of course it's only possible to access 6k or 768 characters.)

 

Reg4 mask >04 specifies the base of the pattern table, either >2000 or 0, again.

The mask for the pattern table comes from two places. Just two bits from Reg4 (the two least significant), and 11 bits from Reg3's mask (after the shift, and again, the least significant). The two bits from Reg4 are shifted 11 places, and the bits from Reg3's are used in place, so something like: xx04 4333 3333 3333. So this is the most confusing part -- that Reg3's mask affects the pattern table as well, except for the top two bits, which come from Reg4. But this makes for some strange combinations being possible, but also guarantees that at least the lowest level, the pattern table will follow the color table. It's probably rare these bits from Reg4 would be anything other than 11 or 00.

 

Again, it's an address mask... so you calculate the offset of the character you are interested in (character code * 8), then AND the mask, then add the base address.

 

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...
On 4/2/2021 at 4:57 PM, Tursi said:

Reg3 (mask >7F) sets the mask for the color table. It is shifted up 6 bits with all the new bits being 1. This is an address mask, so the smallest value (>00) would shift the zeros up 6 bits and end up with xx00 0000 0011 1111, or >03F. That allows a 64 byte color table (so, just 8 characters). The biggest value, >7F, becomes xx01 1111 1111 1111, or >1FFF. That's an 8k color table, or 1024 characters (but, of course it's only possible to access 6k or 768 characters.)

@TursiThanks for this great clarification post. Before reading this I didn’t really understand that the shifted value represented the actual size of the color table, after dividing by 8 (bytes per character). Big thank you for this!
 

Thierry’s site is a great reference yet this detail was difficult for me to grasp.

 

”...the result...which is ANDed with the address of a character in the table.” 
 

  After reading that I am admittedly still confused.

Link to comment
Share on other sites

On 4/1/2021 at 9:35 AM, Asmusr said:

The table on Thierry's page "In summary, these would be the addresses..." is always confusing me. If you consider the values in column 1 (VR3) the last three columns show the addresses of the color tables. If you consider the values in column 2 (VR4) the last three columns show the addresses of the pattern tables. But you shouldn't use the values in columns 1 and 2 together because that would place the color and pattern tables on top of each other. Bit value >80 of VR3 should usually always be the inverse of bit value >04 of VR4

This part is clear to me now. No longer confused by Thierry’s tables. Thanks!

Link to comment
Share on other sites

On 3/31/2021 at 12:49 AM, Asmusr said:

VR4=>03 (three pattern tables at >0000, >0800 and >1000)

Is this essentially overlapping the screen image table at >0000 with the three pattern tables? 
 

if not, where do you put the screen image table with the color table residing at >2000, and the three pattern tables at >0000 to >1800?

Link to comment
Share on other sites

8 hours ago, Airshack said:

Is this essentially overlapping the screen image table at >0000 with the three pattern tables? 
 

if not, where do you put the screen image table with the color table residing at >2000, and the three pattern tables at >0000 to >1800?

 

You have the following options:

>1800

>1C00

>2800

>2C00

>3000

>3400

>3800

>3C00

 

  • Thanks 1
Link to comment
Share on other sites

23 hours ago, Airshack said:

@TursiThanks for this great clarification post. Before reading this I didn’t really understand that the shifted value represented the actual size of the color table, after dividing by 8 (bytes per character). Big thank you for this!
 

Thierry’s site is a great reference yet this detail was difficult for me to grasp.

 

”...the result...which is ANDed with the address of a character in the table.” 
 

  After reading that I am admittedly still confused.

It's only when the mask is all ones that you can interpret it as the size of the table (minus one). The AND explanation covers all cases.  If the mask is 01 0111 1111 1111, for instance, you have a 4K pattern table with a 2K hole in the middle. When the VDP tries to read a pattern at an address with bit 1000 0000 0000 set (address range >1000 - >1FFF>0800->0FFF) the AND of the mask will clear the bit and it will read from >0000 - >0FFF instead.

Edited by Asmusr
Fixed error
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Asmusr said:

 

You have the following options:

>1800

>1C00

>2800

>2C00

>3000

>3400

>3800

>3C00

   Oh, okay. So with VDP Reg 2 set to say...>06, I can establish the screen image table at >1800. Right after the three pattern tables, and before the color table. 


VR2 establishes the location of the Screen Image Table as a multiple of >400. Yes.

Link to comment
Share on other sites

1 hour ago, Asmusr said:

It's only when the mask is all ones that you can interpret it as the size of the table (minus one). The AND explanation covers all cases.  If the mask is 01 0111 1111 1111, for instance, you have a 4K pattern table with a 2K hole in the middle. When the VDP tries to read a pattern at an address with bit 1000 0000 0000 set (address range >1000 - >1FFF) the AND of the mask will clear the bit and it will read from >0000 - >0FFF instead.

@AsmusrPerhaps you meant (“address range >0800 to 0FFF)” in this case?
 

I see where the mask forms a 4K pattern table with a 2K hole (of undefined patterns) in the middle.
 

Mask:0001 0111 1111 1111 = >17FF

>17FF = 6,143 or 6K (6,144) space.

 

Pattern address trying to read:>0800

is in the 2K “hole” created by this zero in the mask.

 

Hole: 0000 1000 0000 0000 = >0800

>0800 = 2,048 or 2K from (>0800 to >0FFF)

 

Therefor, 4K table with 2K hole within the 6K space.

 

Next, we try to read a pattern at address with bit 1000 0000 0000 set. 
 

So the AND is applied this way:

 

EX1: trying to read pattern at >0800

Which is located at the lower limit/edge of the hole of non-existent/undefined characters.

 

Pattern: 0000 1000 0000 0000

Mask.  : 0001 0111 1111 1111

   <apply AND>
Result. : 0000 0000 0000 0000 

We’ve cleared the bit and will read the defined pattern at location >0000 instead.

 

EX2: trying to read pattern >0FFF which is located at the upper edge of the hole.

 

Pattern: 0000 1111 1111 1111

Mask.  : 0001 0111 1111 1111

  <apply AND>
Result : 0000 0111 1111 1111

We will read the defined pattern located at >07FF instead. 
 

Thus, the defined pattern table range >0000 to >07FF, which is 2K in size to perfectly fill in the 2K undefined “hole.”

 

Correct?

 

 

Link to comment
Share on other sites

On 3/31/2021 at 3:49 AM, Asmusr said:

VR3=>9F (one color table at >2000) 

VR4=>03 (three pattern tables at >0000, >0800 and >1000)

With this arrangement plus VR2 set to >06, the 768-byte screen image table may safely reside from >1800 to >1AFF.

 

So the overhead for this hybrid mode looks like this: 

 

>0000 to >07FF, pattern table 1 (2K)

>0800 to >0FFF, pattern table 2 (2K)

>1000 to >17FF, pattern table 3 (2K)

>1800 to 1AFF, screen image table     

>1B00 to >1FFF, unused (1.25K)

>2000 to >27FF, color table (2K)

 

@rasmus I another thread you mentioned how this type of arrangement slowed down your scrolling routine.
 

Why?

  • Like 1
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...