Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

42 minutes ago, TheBF said:

Smallest way to invert EQ flag?

 

In my work on a native code Forth compiler I am calling the BREAK key routine at >0020.

It works great but the status register EQ flag logic for the code is opposite to what I need for typical  Forth loop structure.

 

Does anybody know the smallest amount of code it takes to reverse the logic of the EQ bit? 

I ended up using jumps and LI instructions to a random register, but that seems verbose.

 

How about ...

 

      JNE  JMP1

      C     @>0000, @>0002 'Set EQ to not equal.

      JMP  JMP2

JMP1 C  R0,R0 'Set EQ to equal.

JMP2 ...

 

Or ...

 

XXX  EQU >2000

STST  R1

CZC  @XXX,R1

 

 

Edited by Stuart
  • Thanks 1
Link to comment
Share on other sites

On 11/16/2020 at 6:07 AM, apersson850 said:

The opcode >4E4F disassembles to SZC R15,*R9+. It's executable, for sure. A different reason could be that the USCD p-system doesn't start on a reset, if a "NO" is stored at >38FA. The p-system stores "99" here when running, "GO" if stopped by a fatal error and "NO" if stopped by a Halt command.

By filling the low expansion with "NO" chances are good that the p-code card remains silent when you want to run Forth. Early p-code cards didn't have the hardware disable switch at the rear, as far as I've read. I've only seen cards with the switch, though.

I've never seen a p-Code PEB card without the switch, but the sidecar version always grabs the system on startup (you then have to eXit to get to normal TI mode).

Link to comment
Share on other sites

43 minutes ago, TheBF said:

Smallest way to invert EQ flag?

 

In my work on a native code Forth compiler I am calling the BREAK key routine at >0020. It works great but the status register EQ flag logic for the code is opposite to what I need for typical  Forth loop structure.

 

Does anybody know the smallest amount of code it takes to reverse the logic of the EQ bit? I ended up using jumps and LI instructions to a random register, but that seems verbose.

 

How about

       STST R1
       ANDI R1,>2000

 

...lee

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

 

How about


       STST R1
       ANDI R1,>2000

...lee

Thank you Stuart and Lee.  I had considered using the STST instruction but had not figured out what to do with it. :)

 

For context for the Assembly Language gang I am exploring something called Machine Forth which was developed by Chuck Moore when he started building his own CPUs.

The attached paper by Reuben (AKA Jet) Thomas gives you a sense of it.  It is essentially a way to make an assembler that  uses Forth-like syntax that can be quickly written for different CPUs quickly.

This in theory allows one to make reasonably efficient programs without learning all the ins and outs of a new CPU's instruction set.

 

Jet seems to be of the opinion that for ARM it has little advantage versus just writing an ANS Forth system that runs native code. (For him that is simple I guess)

I am coming to a similar conclusion with 9900.

The limited instruction set of Machine Forth,  which used the 21 .. 30ish instructions in Chucks CPUs,  just does not let one get full advantage of the 9900 so I am "fleshing out" the compiler intrinsic instructions quite a bit.

There are so many Forth operations that are just one instruction on the 9900 that it makes it very worthwhile. And many that are two instructions when you add some stack cleanup.

 

For your interest here is the demo program that prompted my question, with a video showing some speed and me "breaking" out of the program with your help:

Thanks again guys.

\ MFORTH DEMO #10 
NEEDS TARGET:   FROM DSK2.MFORTH

COMPILER:  \ preamble to set up target image
  NEW.
  HEX 2000 ORIGIN.

\ load libraries here
INCLUDE DSK2.VDPLIB

\ User program begins
COMPILER: DECIMAL
TARGET:
 40 CONSTANT C/L     \ chars per line
 32 CONSTANT BL     \ space character (blank)
960 CONSTANT C/SCR  \ chars per screen

: PAGE  ( -- ) 0 #  C/SCR  BL VFILL ;

: FILLSCREEN ( -- )
      96 # FOR
         0 #  C/SCR  R@ BL +  VFILL  \ R@ returns loop index
      NEXT
;
  PROG: DEMOTEXT
        PAGE
        BEGIN
          FILLSCREEN
          ?TERMINAL
        UNTIL

        NEXT,         \ return to Camel99 Forth
  END.

HOST:    \ reset search order to Camel99 FORTH

 

 

 

 

thomas99a.pdf

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Today I was reading up on the BIT-MAP Mode in the E/A Manual, p.334, section 21.5. I have some questions for the experts:

 

Why is the Screen Image Table divided up into three sections? 

 

Is it indeed a common practice to initialize the Screen Image Table from >00 to >FF repeated three times, and then alter the entries in the Pattern Descriptor Table and the Color Table as read in 21.5.4 Bit-Map Mode Discussion?

 

 

  • Like 1
Link to comment
Share on other sites

3 minutes ago, GDMike said:

I think on whtech there's a tms9918A pdf file. It may give some good info

Thanks! I'm trying to wrap my head around why I can't define a character and then use it anywhere on the screen? Is it common to define redundant character patterns for objects movable around the entire screen? Seems really tedious.

  • Like 1
Link to comment
Share on other sites

Thanks @GDMike

 

   I see in section 2.4.2 of the data sheet a better explanation of what's going on. You have a larger library of patterns in Graphics Mode II (Bit-Map) so that each of the 768 tiles on the screen (Pattern Name Table/Screen Image Table)  may have a unique image. In graphics mode-I there's only 256 images in the Pattern Descriptor Table vs 768 images for graphics mode II. Okay, I see the advantage of that for maybe drawing a large 32*24 tiled image where each tile needs to be unique. 

 

   What I really look forward to doing is taking advantage of eight bytes of color data per character in the character descriptor table. I'm trying to figure out if I can get away with simply defining 256 characters each with eight bytes of color information? 

Link to comment
Share on other sites

26 minutes ago, GDMike said:

Are you working in assembly,forth, extended basic? Or none of them

Assembly. I'm assuming it's not necessary to define more characters than I need thus avoiding reserving up to 12.75K of memory for graphics information. Just...the three-way pane/divided screen concept has me confused. I'll spend more time with the data sheet. Thank you! 

 

Surely I won't have to define 6K of character data and another 6K of color data just to exploit the advantages of Graphics Mode-II (Bit-Map)?

 

Example: Lets say I wish to move a character of a football from the top of the screen to the bottom of the screen. Must I define it three times in memory at a cost of an additional 16 bytes? If so will I also have to define the 8-byte color information three times? 

  • Like 1
Link to comment
Share on other sites

3 hours ago, Airshack said:

Surely I won't have to define 6K of character data and another 6K of color data just to exploit the advantages of Graphics Mode-II (Bit-Map)?

 

Indeed, you do! As you noted, each is 6 KiB in size. The color table must be at address >0000 or >2000 and the pattern descriptor table at the other (>2000 or >0000). Those are the only options you can set in the VDP registers for those two bitmap mode (graphics 2) tables. Sprites, on the other hand, are normal definitions as in graphics 1 mode—you just need to locate the sprite descriptor table at an available location and watch that you do not overrun another table somewhere.

 

...lee

  • Like 1
Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

Indeed, you do!

Say it ain’t so Lee! Damn. 
 

Is it true I must triple-redundantly define each character if I vertically scroll the entire play field? Or in other words, if a wall tile character is drawn from top of the screen to bottom, must I define that tile once for each of the three graphic panes?

 

So 12K (+768 bytes for Screen Image) of memory is unavoidably used-up once you decide to use Graphics (Bit-Map) Mode-II?

  • Like 1
Link to comment
Share on other sites

16 hours ago, Airshack said:

Surely I won't have to define 6K of character data and another 6K of color data just to exploit the advantages of Graphics Mode-II (Bit-Map)?

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. 

  • Like 4
Link to comment
Share on other sites

The problem with the sprite duplication in emulation is that it's not 100% deterministic... or at least that was found to be so on the ColecoVision. The BlueMSX emulator tried to emulate it and ended up removing it.

 

In fairness, I don't know /why/ it's non-deterministic, my bitmap test program seems to do the same thing all runs. Maybe the 9928 behaves slightly differently from the 9918 in that respect.

 

As for why there are three pattern tables, I didn't see if that was answered -- it's because bitmap mode is just an extension of the regular character mode, and the addressing is based on 8-bit indexes. With 768 positions, 8 bits isn't enough, but it took very little silicon to just have it advance to the next table at a fixed point. Remember this was in the very early days of graphics processors, and bitmap was not even a design goal for the chip. The designer just figured out a way to add it for very few transistors. ;)

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

You can also alter the Screen Image Table layout from 1,2,3 ... 255. To change the indexing of your bytes from 8x8 to 8x16; 8x32 or 8x64. Just make sure the SIT is repeated the same way all three times.

 

0,8,16,24 ... 248

1,9,17,25 ...  249

:

6,14,22,30 ... 254

7,15,23,31 ... 255

 

Repeated 3 times -- 8x64

Edited by Torrax
  • Like 2
Link to comment
Share on other sites

22 hours ago, Airshack said:

Say it ain’t so Lee! Damn. 
 

Is it true I must triple-redundantly define each character if I vertically scroll the entire play field? Or in other words, if a wall tile character is drawn from top of the screen to bottom, must I define that tile once for each of the three graphic panes?

 

So 12K (+768 bytes for Screen Image) of memory is unavoidably used-up once you decide to use Graphics (Bit-Map) Mode-II?

I refer you to my explanation of bitmap mode at 

 

https://ftp.whtech.com/datasheets%20and%20manuals/Hardware/ti%20hardware%20compendium.txt

 

You can reduce the pattern table to 2 kilobytes, color table to 64 bytes, use 8 screen image tables for scrolling the screen, and have room for sprites, file buffers, etc.

 

Maybe at some point I will recover the program.  It had my fast 99/4A direct CRU keyboard scan, too.

  • Like 2
Link to comment
Share on other sites

17 hours ago, Tursi said:

With 768 positions, 8 bits isn't enough,

So I suppose Bitmap mode wants to offer you 768 unique position patterns in order to call itself a true bitmap mode? Is that what you’re saying? I believe I get that only 256 patterns wouldn’t allow for 768 unique tiles.

 

I just want access to the extra colors as 256 characters seems plenty.

 

Would be nice to have 256 characters * 8bytes/ char = 2K

 

With eight bytes of color data per character = 256*8 = 2K

 

plus 768 single pane screen image table = 768 bytes

 

**** sounds like this is @Asmusr suggests with the hybrid-bitmap deal which I’ll investigate. Limits me to eight Sprite’s which is worth researching.

Link to comment
Share on other sites

18 hours ago, Asmusr said:

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. 

So the hardware knows to somehow use the one color table for all three panes?

 

Sounds like a reasonable compromise which allows for retaining the use of ALL Sprite’s I presume. For my understanding can you confirm the characters repeated in all three panes MUST be defined three times and appear in the same position (number) in all three panes?

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