Jump to content
bfollett

Bitmap mode.

Recommended Posts

What do you mean when you say you can force RXB to run from RAM and not from VDP? Regular TI XB will detect the 32K memory and automatically run programs out of it. If no expansion memory then they run from VDP. Do you have to do something special to run from RAM? I assume RXB uses VDP pretty much the same way as TI XB, using it to store strings etc. Is that the case? I would like to do some tests tonight but I want to be sure that we are doing the same thing.

Share this post


Link to post
Share on other sites

Yes it still buffers from VDP to RAM to load from Disk but once in RAM I can use RXB to rewire the XB program in RAM as it runs.

 

This is possible in normal XB but very hard to do without the access to the RXB routine CALL MOVES that can move chucks of memory around vs XB normal just a byte or two at a time.

 

CALL MOVES is the GPL command MOV put into RXB. Same results any size of memory of any type to any size of any type.

 

As for Strings when you use numbers (hard code) like CALL LOAD(8192,128) vs CALL LOAD(A,V) more string access is used as it must search for the variable name and location, then make a copy in VDP.

 

I do have some ideas on how to make RXB not use VDP and still function with Strings but from RAM only. This presents all kinds of cool things we could do.

 

(I reserved 32K of SAMS memory for a version of RXB that was SAMS based and used the extra 32K as string and buffers space using Assembly to swap out VDP and RAM, so XB would fly)

Share this post


Link to post
Share on other sites

Rich, I'm pretty sure that you will encounter problems with the bit-mapped graphics colliding with XB stuff. I took a look at the "extended BASIC system area" from >0370 to >03EF in VDP RAM and ran a one line program - 10 RUN "DSK1.LOAD" This changed a couple of bytes in this area. Who knows what will happen when you start overwriting this with your image data. Probably nothing good. Also anything in the stack will probably get whacked. I could be wrong. It's easy enough to check. Make some 6K long files of random numbers and load them to >0000 and >2000 with a program that pretends they are actual image files. If you can load a bunch of files like this without killing RXB then this would probably work for you. If it crashes XB then you have a different answer.

 

Of course, if you can move all the VDP access to RAM so RXB uses none of this memory then you should have no problems. But this shrinks the maximum program size which will give folks something to complain about!

Share this post


Link to post
Share on other sites

Rich, I'm pretty sure that you will encounter problems with the bit-mapped graphics colliding with XB stuff. I took a look at the "extended BASIC system area" from >0370 to >03EF in VDP RAM and ran a one line program - 10 RUN "DSK1.LOAD" This changed a couple of bytes in this area. Who knows what will happen when you start overwriting this with your image data. Probably nothing good. Also anything in the stack will probably get whacked. I could be wrong. It's easy enough to check. Make some 6K long files of random numbers and load them to >0000 and >2000 with a program that pretends they are actual image files. If you can load a bunch of files like this without killing RXB then this would probably work for you. If it crashes XB then you have a different answer.

 

Of course, if you can move all the VDP access to RAM so RXB uses none of this memory then you should have no problems. But this shrinks the maximum program size which will give folks something to complain about!

 

Yea any XB routine that uses a string for Disk Access or if you use way to many variables or use a routine that needs to duplicate string like SEG$ or ASC will crash Bit Mapped Graphics.

 

But it can be done using lines with numbers only and very few variables to stay away from the temporary buffer at >0370 like this is the XB source code for VDP memory at that area:

 

[0208] 0371 LODFLG EQU >0371 Auto-boot needed flag

[0209] 0372 START EQU >0372 Line to start execution at

[0210] 0376 SYMBOL EQU >0376 Saved symbol table pointer

[0211] 0382 SPGMPT EQU >0382 Saved PGMPTR for continue

[0212] 0384 SBUFLV EQU >0384 Saved BUFLEV for contiue

[0213] 0386 SEXTRM EQU >0386 Saved EXTRAM for continue

[0214] * SAVEVP EQU >0388 Saved VSPRT for continue

[0215] * ERRLN EQU >038A On-error line pointer

[0216] 038C BUFSRT EQU >038C Edit recall start addr (VARW)

[0217] 038E BUFEND EQU >038E Edit recall end addr (VARA)

[0218] 0392 TABSAV EQU >0392 Saved main symbol table ponte

[0219] 0396 SLSUBP EQU >0396 Saved LSUBP for continue

[0220] 0398 SFLAG EQU >0398 Saved on-warning/break bits

[0221] 039A SSTEMP EQU >039A To save subprogram program ta

[0222] 039C SSTMP2 EQU >039C Same as above. Used in SUBPRO

[0223] 039E MRGPAB EQU >039E MERGEd temporary for pab ptr

[0224] *----------------------------------------------------------

[0225] * Added 6/8/81 for NOPSCAN feature

[0226] 03B7 PSCFG EQU >03B7

[0227] *----------------------------------------------------------

[0228] * Flag 0: 99/4 console, 5/29/81

[0229] * 1: 99/4A console

[0230] 03BB CONFLG EQU >03BB

[0231] *----------------------------------------------------------

[0232] * Temporary

[0233] 0374 NOTONE EQU >0374 NO-TONE for SIZE in ACCEPT us

[0234] * in FLMGRS (4 bytes used)

[0235] 0388 SAVEVP EQU >0388

[0236] 038A ERRLN EQU >038A

[0237] 03AC ACCVRW EQU >03AC Temoporary used in ERRZZ, als

[0238] * used in FLMGRS

[0239] 03B0 VALIDP EQU >03B0 Use as two values passing fro

[0240] 03B2 VALIDL EQU >03B2 VALIDATE code to READL1

[0241] 03BC OLDTOP EQU >03BC Temporary used in ERRZZ, also

[0242] 0820 CRNBUF EQU >0820 CRuNch BUFfer address

[0243] 08BE CRNEND EQU >08BE CRuNch buffer END

[0244] 08C0 RECBUF EQU >08C0 Edit RECall BUFfer

[0245] 0958 VRAMVS EQU >0958 Default base of value stack

[0246] 0390 CNSTMP EQU >0390 Use as temporary stored place

 

As you can see quite a few routines use that area. But like I said it can be done. I did write RXB using XB source code so I know it is possible.

The easy way to move >2000 of memory is put it in lower 8K then just move it into >0000 in VDP with the CALL MOVES("RV",8192,8192,0)

But before I do that I have to set the VDP registers up correctly so what are the seven VDP registers set to as I can use CALL POKER(reg#,values,....) to load all the VDP registers in one command.

Once it gets to GPL it should not be a problem as the values for POKER are in the upper VDP at around >3000 (Variables) or above and all the screen stuff is lower below >2000 so a >1000 difference.

Even have a bigger buffer to stay out of danger with a CALL FILES(1)

Edited by RXB

Share this post


Link to post
Share on other sites

As an aside, there is an original copy of "The Missing Link" on eBay. Some guy apparently gained access to the inventory of a retail store which had been shuttered since the 1980s, inside being a bunch of TI stuff. With disk images floating around the Internet, I am not certain how valuable original software is to many people anymore.

Share this post


Link to post
Share on other sites

Rich, if you can load pictures under RXB then it sounds like you have this under control. I don't think you even need TML for what you want to do. TI Artist pictures are just dumps of the 6K that is in each of the the two memory blocks memory. The suffix _C is the color data and the suffix _P is the picture data. One has to be in VDP RAM at >0000 and the other at >2000. Either location is OK depending how the VDP registers are set up. Also you need a 768 byte block containing >00 to >FF 3 times and set the VDP register to point to that. The E/A manual will help you sort out what the registers should be. Good luck.

Share this post


Link to post
Share on other sites

So bit 7 in VDP Register 0? Enable input from external? Does that one mean input to video for external device?

Share this post


Link to post
Share on other sites

I think that input from external is the reason for the transparent color in the pallette. As I remember, you could input a composit video image and superimpose graphics from the 9918 on top of that image. The idea was to put titles and other graphics on the screen. Back in the days of VCR's I wanted to put some titling on tapes but never got around to it.

 

FYI, here is how the VPD registers are set up in Missing Link plus my comments from the docs.

R0,R1 = >02E0 Set Bitmapped Mode / Normal setting for R1

R2,R3 = >0E7F Screen image @ >3800 / Color Table @ >0000

R4,R5 = >0778 Pattern descriptor @>2000 / Sprite Attribute list @>3C00

R6,R7 = >0717 Sprite descriptor @>3800 / Background color black on cyan

That's how I did it, but those might not be the best for what you propose to do.

Edited by senior_falcon

Share this post


Link to post
Share on other sites

I was thinking since I do not need any Assembly to do this I could just copy the entire 8K of memory into 2 sections.

 

1. Saved normal XB graphics mode, but that only takes 2079 bytes of RAM so the rest could be assembly language. Or string space.

2. Saved Bit Mapped Mode using a full 5K for graphics. If my numbers are right.

 

It works like my game IN THE DARK does. I change the Bit Mapped screen from normal XB mode that is in lower 8K RAM and then just swap screens when I want to show the Bit Mapped one or Normal XB.

 

This would allow me the best of both worlds and it might be possible to do it in just a single lower 8K as 5K for Bit mapped mode and just over 2K for normal mode.

 

Or use the upper 24K that is not being used by the XB program. One XB program that runs two screens but only change the Bit Mapped one while in RAM.

Edited by RXB

Share this post


Link to post
Share on other sites
I think that input from external is the reason for the transparent color in the pallette. As I remember, you could input a composit video image and superimpose graphics from the 9918 on top of that image. The idea was to put titles and other graphics on the screen. Back in the days of VCR's I wanted to put some titling on tapes but never got around to it.

 

This is in fact what the transparent color is for. I've messed with it in the TI console - you have to cut several traces because the console is hard wired not to support external video. Additional external circuitry is needed to provide separate sync to the VDP. I wasn't quite successful with my attempt, because I didn't understand the sync circuitry at the time, but I was able to switch between stable TI video, and stable external video (with desynchronized TI video overtop of it) in software.

 

It wasn't perfect even ignoring the sync issues, there was bleed between the two signals. Video bled through the TI signal slightly, even when it was turned off, causing ghosting when the external video was disabled and bleed-through of the TI pixels when enabled. That could probably be solved by making the external video a little weaker.

 

There was an article in Radio Electronics a long time ago about building a video titler using the 9918A, and that article noted that the default clock rate for the VDP actually ended up being slightly off from "standard" NTSC video, making stable sync difficult. The author used a slightly different crystal to get around it, IIRC. That might also be an issue in the 4A console, if it's true.

 

Share this post


Link to post
Share on other sites

The 9938 and 9958 solved that problem of VSYNC and someone posted many years ago on the PUNN BBS that they had successfully done this on a 9958 on the TIM card.

 

Do not remember who said they pulled it off. It might have been on the DELPHI network instead that posted this.

Share this post


Link to post
Share on other sites

It wasn't perfect even ignoring the sync issues, there was bleed between the two signals. Video bled through the TI signal slightly, even when it was turned off, causing ghosting when the external video was disabled and bleed-through of the TI pixels when enabled. That could probably be solved by making the external video a little weaker.

 

"Back in the day" when I used to volunteer for KLTV the local public access station in Longview, WA we used a TI-99/4A to feed the text to the Chyron because there was no affordable "GENLOCK" for the TI, however when the Amiga 2000came out with their Genlock and Video Toaster software it opened up a whole new ballgame for us and a lot of people other people who wanted to make their own video productions.

  • Like 1

Share this post


Link to post
Share on other sites

On a side note I got RXB to go into Bit Mapped Mode and save the data from VDP to lower 8K here is the program that uses the TML memory areas.

The issue is without Assembly RXB can not run any configuration that does not crash VDP.

 

I have tried several configurations to run Bit Mapped Mode but the sheer size of VDP used just limits the things that can be done.

 

I attempted to run Lower 8K as the place to modify the Bit Mapped Mode Screen/Pattern/Color/Sprites/

But that left so little VDP memory over that even small XB programs would crash.

 

I can get it to run Bit Mapped Mode and modify for making Pics but the process is Sloooow and keeps at the edge of crashing XB all the time.

 

So TML or XPD or XBPLOT are the best solutions for Bit Mapped Mode to be used from XB. TML is the most advanced of them also.

Edited by RXB
  • Like 1

Share this post


Link to post
Share on other sites

I thought I would try the Forth program from post #35 to draw Alfred E. Neuman again in fbForth 2.0 to see what improvements in speed occurred after I recoded all (or most) of the graphics primitives in ALC and hoisted them into cartridge space. Wow! :-o The time went from 45 seconds down to 3.3 seconds and from about 90 seconds down to 5.7 seconds for the horizontally doubled image—a roughly 15-fold improvement in speed!

 

Of course, with the fbForth 2.0 cartridge, you no longer need to load the blocks for Text mode, Graphics2 (Bitmap) mode and the graphics primitives library because those words are now in cartridge space.

 

...lee

  • Like 4

Share this post


Link to post
Share on other sites

Nice! I might want to revisit my 3D wireframe graphics tests. Last time I tried it with regular TI FORTH it was awfully slow and I gave up on it. Perhaps now 1 frame per second is feasible and a flight simulator in the spirit of Sublogic's FS1 might become a possibility: Limited "world", primitive scenery, but hey still a flight simulator.

  • Like 1

Share this post


Link to post
Share on other sites

I must say that compiling over 2000 numbers from a blocks file into the dictionary is still slow because of the way the Forth interpreter works. I didn't time the actual compilation; but, I'd bet it's actually a little longer than with fbForth 1.0 and TI Forth because fbForth 2.0's dictionary is bigger. The reason that matters is that the interpreter first looks for the new token in the dictionary. It is only after failing to find it that it attempts to convert it to a number in the current radix. That means that each and every number compiled causes the complete dictionary to be searched. It also has to search for , (comma) every time, as well. I need to implement DATA (TurboForth) in fbForth—at least, I think DATA bypasses the complete dictionary search, as well as not needing to look for , every time. Of course, the fastest way to load after the first time is to BSAVE everything—but, I digress...

 

...lee

Share this post


Link to post
Share on other sites

Hi Lee,

 

That's right. DATA only uses WORD and NUMBER internally, no dictionary lookups.

 

See http://turboforth.net/lang_ref/view_word.asp?id=4

 

The source is in 0-17-Speech.a99

 

It's in the speech section because I designed it in the main as an easy means to store speech data, though it's equally usable for character data.

 

M

  • Like 1

Share this post


Link to post
Share on other sites

Hi Lee,

 

That's right. DATA only uses WORD and NUMBER internally, no dictionary lookups.

 

See http://turboforth.net/lang_ref/view_word.asp?id=4

 

The source is in 0-17-Speech.a99

 

It's in the speech section because I designed it in the main as an easy means to store speech data, though it's equally usable for character data.

 

M

 

Fantastic! I will definitely port DATA to fbForth 2.0, first as a utility word in FBLOCKS and, then possibly, in a future upgrade of the cartridge—that is, if I can fit it in.

 

...lee

Share this post


Link to post
Share on other sites

What is the most efficient way of plotting a single pixel on the bitmap screen? In all my previous programming, I have simply used the routine listed in the E/A manual, but I was wondering if there was some better hack out there...

Share this post


Link to post
Share on other sites

What is the most efficient way of plotting a single pixel on the bitmap screen? In all my previous programming, I have simply used the routine listed in the E/A manual, but I was wondering if there was some better hack out there...

 

Are you talking about this from p. 336:

       MOV  Rl,R4        R1 is the Y value.
       SLA  R4,5
       SOC  Rl,R4
       ANDI R4,>FF07
       MOV  R0,R5        R0 is the X value.
       ANDI R5,7
       A    R0,R4        R4 is the byte offset.
       S    R5,R4        R5 is the bit offset.

If so, here is TI Forth/fbForth 2.0 code, which is one more instruction (don't know about timing difference), but maybe easier to follow:

__DTBM MOV  R0,R2       ; y to R2
       MOV  R1,R3       ; x to R3
       ANDI R0,>0007    ; R0 = 3 right bits of y = char dotrow
       ANDI R1,>0007    ; R1 = 3 right bits of x = char dotcolumn
       ANDI R2,>00F8    ; R2 = 5 left bits of y = start dot row of char pattern
       ANDI R3,>00F8    ; R3 = 5 left bits of x = start dot column of char pattern
       SLA  R2,>0005    ; R2 * 32 = PDT offset of char pattern row's 1st row
       A    R2,R0       ; R0 = PDT offset of char pattern's row byte
       A    R3,R0       ; R0 = PDT offset of char pattern byte of dot

Both of the above get the correct byte and bit; but, how do you proceed from there to plot the dot?

 

...lee

Share this post


Link to post
Share on other sites

Yup that's the one. I use a predefined small table with 8 values each representing a specific bit position as below:

BITPOS BYTE >80,>40,>20,>10,>08,>04,>02,>01

Once the byte and bit offsets are known, it's just a matter of adding the byte offset to the PDT address to fetch the appropriate byte, then OR'ing it with BITPOS+Bit offset:

PDT    EQU  >1800
TEMP   BSS  2
       .
       .
       .
       MOV  PDT(R4),R0
       MOV  TEMP,R1           
       BLWP @VSBR             * TEMP now has the needed PDT byte
       SOCB @BITPOS(R5),@TEMP * OR the appropriate pattern with the PDT byte
       MOVB @TEMP,R1
       BLWP @VSBW             * Write the modified byte back to the PDT

The above sets a specific bit. In order to reset it, I replace SOCB with SZCB.

Edited by Vorticon

Share this post


Link to post
Share on other sites

The most efficient method is not to use X and Y coordinates (but rather an address and offset), but if you have to, it's pretty hard to beat that routine for general purpose address calculation. :)

Share this post


Link to post
Share on other sites

I'm not sure your code is working. This looks more right to me:

 

PDT EQU >18002000 * Or >0000 depending on how the VDP is set up

. . .

MOV R4,R0

AI R0,PDT

BLWP @VSBR

SOCB @BITPOS(R5),R1

BLWP @VSBW * Write the modified byte back to the PDT

Share this post


Link to post
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.

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