pixelpedant Posted December 14, 2020 Share Posted December 14, 2020 XB256 implements VWRITE and VREAD as CALL LINKs for reading and writing to VDP memory. This is very nice, and more appealing to me than Mini Memory's PEEKV and POKEV since you can work with large volumes of byte data as strings. My question is, does anyone have a minimal implementation of at least this VDP write behaviour as a simple assembly subprogram? Which is to say something like XB256's CALL LINK("VWRITE",ADDRESS,STRING$) This is specifically of interest to me since I've been doing a lot of playing with the Text-to-Speech disk's subroutines lately, and they mostly monopolise the lower 8K. But there's space there still, or I can make some more by running the SETUP routine from high memory via HMLOADER, and/or skipping XLAT, which usually isn't necessary. So something relatively lightweight isn't a problem. But XB256 as a whole isn't an option. Plus, this just seems like a really fundamentally useful thing that somebody presumably implemented at some point (even if just for the sake of their own program). 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/ Share on other sites More sharing options...
apersson850 Posted December 15, 2020 Share Posted December 15, 2020 I have never needed it, but I can see that it wouldn't be that long a routine. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700142 Share on other sites More sharing options...
RXB Posted December 15, 2020 Share Posted December 15, 2020 Hmmm XB has ROMs 0 and 1: 0225 ************************************************************ 0226 * XML table number 7 for Extended Basic - must have 0227 * it's origin at >6010 0228 ************************************************************ 0229 * 0 1 2 3 4 5 6 0230 6010 619C DATA COMPCG,GETSTG,MEMCHG,CNSSEL,PARSEG,CONTG,EXECG 6012 61A2 6014 72CE 6016 6070 6018 6470 601A 64C4 601C 6500 0231 * 7 8 9 A B C D 0232 601E 61BA DATA VPUSHG,VPOP,PGMCH,SYMB,SMBB,ASSGNV,FBSYMB 6020 6C2A 99/4 ASSEMBLER XML359 PAGE 0005 6022 6410 6024 61B4 6026 61A8 6028 61AE 602A 618C 0233 * E F 0234 602C 6EE2 DATA SPEED,CRNSEL 602E 6076 0235 ************************************************************ 0236 * XML table number 8 for Extended Basic - must have 0237 * it's origin at >6030 0238 ************************************************************ 0239 * 0 1 2 3 4 5 6 7 0240 6030 74AA DATA CIF,CONTIN,RTNG,SCROLL,IO,GREAD,GWRITE,DELREP 6032 65CC 6034 6630 6036 7ADA 6038 7B48 603A 7EB4 603C 7ED8 603E 7EF4 0241 * 8 9 A B C D E 0242 6040 7F7E DATA MVDN,MVUP,VGWITE,GVWITE,GREAD1,GWITE1,GDTECT 6042 6F98 6044 7FC0 6046 7FDA 6048 7EA6 604A 7ECA 604C 6050 0243 * F 0244 604E 7C56 DATA PSCAN XML routines MVDN, MVUP are for moving VDP to VDP. XML routines VGWITE, GVWITE, GREAD1, GWITE1, GREAD, GWRITE are VDP or GROM read and writes. Also VPOP and VPUSHG are stack routines in VDP. XBROMS.zip Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700246 Share on other sites More sharing options...
+Lee Stewart Posted December 15, 2020 Share Posted December 15, 2020 On 12/14/2020 at 2:19 PM, pixelpedant said: My question is, does anyone have a minimal implementation of at least this VDP write behaviour as a simple assembly subprogram? Which is to say something like XB256's CALL LINK("VWRITE",ADDRESS,STRING$) . . . So something relatively lightweight isn't a problem. I presume that STRING$ is an XB string, meaning that it resides in VRAM, and that ADDRESS is also in VRAM, so that implementing the above VWRITE routine is actually moving a string from one VRAM location to another. If so, there are a couple of ways to do this. One is much more “lightweight” than the other. The light one would require only 50 – 60 bytes beyond the CALL overhead. The heavy one, which should be a good bit faster (unless the CALL overwhelms its time), would require an additional 256-byte RAM buffer to hold the largest possible XB string. I will probably attempt both routines just for grins, but do you have a preference? ...lee 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700390 Share on other sites More sharing options...
RXB Posted December 15, 2020 Share Posted December 15, 2020 (edited) 39 minutes ago, Lee Stewart said: I presume that STRING$ is an XB string, meaning that it resides in VRAM, and that ADDRESS is also in VRAM, so that implementing the above VWRITE routine is actually moving a string from one VRAM location to another. If so, there are a couple of ways to do this. One is much more “lightweight” than the other. The light one would require only 50 – 60 bytes beyond the CALL overhead. The heavy one, which should be a good bit faster (unless the CALL overwhelms its time), would require an additional 256-byte RAM buffer to hold the largest possible XB string. I will probably attempt both routines just for grins, but do you have a preference? ...lee GREAD * (RAM to RAM) * Read data from ERAM * @GSRC : Source address on ERAM * @DEST : Destination address in CPU * Where the data stored after read from ERAM GWRITE * (RAM to RAM) * Write the data whcih is stored in CPU to ERAM * @GDST : Destination address on ERAM where data is going * to be stored * @CSRC : Source address on CPU where data stored MVDN * (VDP to VDP) or (RAM to RAM) * WITHOUT ERAM : Move the contents in VDP RAM from a lower * address to a higher address avoiding a * possible over-write of data * >835C ARG : byte count * >8300 VAR0 : source address * >8306 VARY2 : destination address * WITH ERAM Same as above except moves ERAM to ERAM MVUP * (RAM to RAM) * WITH ERAM : Move the contents in ERAM FROM a higher * address to a lower address * ARG : byte count * VAR9 : source address * VAR0 : destination address VGWITE * (VDP to RAM) >834C=ADDR1,>8350=ADDR2,>834E=BCNT1 * Move data from VDP to ERAM * @ADDR1 : Source address where the data stored on VDP * @ADDR2 : Destination address on ERAM * @BCNT1 : byte count GVWITE * Move data from ERAM to VDP (RAM to VDP) * @GSRC : Source address where the data stored on ERAM * @DEST : Destination address on VDP * @BCNT3 : byte count I do use use GPL MOVE instead it takes less bytes to do same thing and speed wise is just slightly slower then the XML versions. Depends on amount moved, the larger the amount to move the slower GPL MOVE is in comparison. Edited December 15, 2020 by RXB Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700407 Share on other sites More sharing options...
pixelpedant Posted December 15, 2020 Author Share Posted December 15, 2020 44 minutes ago, Lee Stewart said: I presume that STRING$ is an XB string, meaning that it resides in VRAM, and that ADDRESS is also in VRAM, so that implementing the above VWRITE routine is actually moving a string from one VRAM location to another. If so, there are a couple of ways to do this. One is much more “lightweight” than the other. The light one would require only 50 – 60 bytes beyond the CALL overhead. The heavy one, which should be a good bit faster (unless the CALL overwhelms its time), would require an additional 256-byte RAM buffer to hold the largest possible XB string. I will probably attempt both routines just for grins, but do you have a preference? That'd be awesome, Lee. I figure the buffered one's the one I'd use the most. But it sure doesn't hurt to have options! I suppose on reflection it's not surprising that this doesn't exist somewhere as just a support routine sitting on a disk for some relatively elaborate legacy XB program (like the XB RPGs). My thinking being that the current appeal of speeding things up or simplifying matters by just dumping large chunks of pregenerated sprite/screen/pattern/colour data into relevant VDP locations as bytes is substantially contingent on two things, neither of which is true in an 80s context: namely, disk access is fast and convenient, and storage is arbitrarily large. And more importantly, handling and generating assets as VDP RAM dumps is easy, and is supported by various cross-platform development tools. Such that it's tempting to just "cut out the middle man" as far as some of that data goes, even when using XB for the broader program logic. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700412 Share on other sites More sharing options...
RXB Posted December 15, 2020 Share Posted December 15, 2020 (edited) 52 minutes ago, pixelpedant said: That'd be awesome, Lee. I figure the buffered one's the one I'd use the most. But it sure doesn't hurt to have options! I suppose on reflection it's not surprising that this doesn't exist somewhere as just a support routine sitting on a disk for some relatively elaborate legacy XB program (like the XB RPGs). My thinking being that the current appeal of speeding things up or simplifying matters by just dumping large chunks of pregenerated sprite/screen/pattern/colour data into relevant VDP locations as bytes is substantially contingent on two things, neither of which is true in an 80s context: namely, disk access is fast and convenient, and storage is arbitrarily large. And more importantly, handling and generating assets as VDP RAM dumps is easy, and is supported by various cross-platform development tools. Such that it's tempting to just "cut out the middle man" as far as some of that data goes, even when using XB for the broader program logic. I agree, RXB does this with my commands like CALL PLOAD("DSK1.FILE") and CALL MOVE("RV",2079,8192,0) from RAM to VDP screen. Edited December 15, 2020 by RXB Spelling Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700450 Share on other sites More sharing options...
+FarmerPotato Posted December 16, 2020 Share Posted December 16, 2020 2 hours ago, pixelpedant said: That'd be awesome, Lee. I figure the buffered one's the one I'd use the most. But it sure doesn't hurt to have options! I suppose on reflection it's not surprising that this doesn't exist somewhere as just a support routine sitting on a disk for some relatively elaborate legacy XB program (like the XB RPGs). My thinking being that the current appeal of speeding things up or simplifying matters by just dumping large chunks of pregenerated sprite/screen/pattern/colour data into relevant VDP locations as bytes is substantially contingent on two things, neither of which is true in an 80s context: namely, disk access is fast and convenient, and storage is arbitrarily large. And more importantly, handling and generating assets as VDP RAM dumps is easy, and is supported by various cross-platform development tools. Such that it's tempting to just "cut out the middle man" as far as some of that data goes, even when using XB for the broader program logic. I agree with considering what is 80s spirit (even if you run it on emulation). I think your issues can be reasonably addressed. It comes down to how much data and how often? Load from disk Give yourself a budget of 90K of assets as a minimum. Also compress it! Let the assembly routine unpack it. Require just a few records of data for each update in the game. Cache the most recently used (maybe just 2 screens worth.) 90K is enough for a hundred screenshots (in chars), a couple of charsets (48-64 characters each). The killer is text. At one extreme, an Infocom data file takes the whole disk. TI-Runner periodically loads 1 screen from disk (albeit from all assembly.) Loading a screenful of chars from strings is reasonable: 6 records of DF128, less with RLE compression. I used this technique to initialize screen data into a 4K buffer in low RAM, 8 screens for a level, each 16x32. One assembly routine to blit a section to the screen. Initializing your charset is another: one DF128 record is 16 char definitions. Rule out loading a full bitmap picture. It's beyond XB VDP capacity. Data hiding Put the data into your program to make it faster. Hiding it in the 24K RAM as lines, locatable only by routines aware of it. I'm rusty on this technique. But I think you load your data into 24K, change the first free address, then MERGE the XB program. Then at runtime, your assembly routines can grab from it. Barry Boone's SYSTEX was one example of this technique (it creates a program in the 24K, that hides your 8K, and restores it the next time you run.) Uses For an RPG, assume you update the charset infrequently (like entering new terrain.) Then suppose a screen is static and composed of tiles. Say you want to fill 2/3 of the screen with map. It's 512 bytes or four records of chars. If you have 2x2 tiles, then only 128 bytes are needed to fill the screen. My first XB-assembly hybrid was a routine that took 81 bytes from a XB string and drew a 9x9 map of 2x2 tiles. I was pretty happy with that (when it was debugged...) If you have a list of bigger objects to draw, you can compose it of 3 byte chunks for row, column, object number. I'm talking about loading compressed data in pieces, not always a VDP dump. (Tunnels of Doom has the whole VDP image in its 52K: pattern table, colors, + data.) When you are comfortable with DSRLNK in assembly, move the loading (and saving!) out of XB code for another big speedup. Sprites Another technique I used is to store the sprite attribute table in low RAM. XB program updates a sprite location in a buffer with CALL LOAD(9472+S*4,Y,X) instead of CALL LOCATE(#S,Y,X). Pattern and color too. One CALL LINK("SPTBL") copies the whole thing to VDP. Instantly updated positions and frames. Combine same technique for the motion table. A substitute for turning the sprite motion bit off, looping across CALL MOTION, turning motion back on.. the assembly routine can set all the sprite attributes together. Code I doubt I can find any of my code for these things. So. It requires knowledge of XB argument processing, which is harder than VDP access. Hope this adds to the idea pool! Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700541 Share on other sites More sharing options...
pixelpedant Posted December 16, 2020 Author Share Posted December 16, 2020 Thanks for the ideas! I think it's definitely worth considering how contemporary tools imply big changes for how we think about TI game development, XB or otherwise. Just given that it is relatively trivial to rapidly generate VDP assets, in the present day. And so this makes certain types of game which would have been extremely arduous to create, at one point in time, some of the easiest to create, now. A Myst-clone (slideshow) style adventure, for example. Crazily arduous to develop graphical assets for, using original era tools. Pretty easy, in the days of Magellan and Convert9918. A TIPI mouse driver for XB is another thing that encourages thinking differently about what genres and designs the platform might now encourage, which once it didn't so much, and gestures in the direction of point and click graphical adventure games. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700580 Share on other sites More sharing options...
senior_falcon Posted December 16, 2020 Share Posted December 16, 2020 On 12/14/2020 at 2:19 PM, pixelpedant said: XB256 implements VWRITE and VREAD as CALL LINKs for reading and writing to VDP memory. This is very nice, and more appealing to me than Mini Memory's PEEKV and POKEV since you can work with large volumes of byte data as strings. My question is, does anyone have a minimal implementation of at least this VDP write behaviour as a simple assembly subprogram? Which is to say something like XB256's CALL LINK("VWRITE",ADDRESS,STRING$) This is specifically of interest to me since I've been doing a lot of playing with the Text-to-Speech disk's subroutines lately, and they mostly monopolise the lower 8K. But there's space there still, or I can make some more by running the SETUP routine from high memory via HMLOADER, and/or skipping XLAT, which usually isn't necessary. So something relatively lightweight isn't a problem. But XB256 as a whole isn't an option. Plus, this just seems like a really fundamentally useful thing that somebody presumably implemented at some point (even if just for the sake of their own program). CALL LINK("VWRITE",address,string) is short and simple. (And VREAD as well) If you are thinking of doing this project in XB I can post the code for those. 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700648 Share on other sites More sharing options...
+FarmerPotato Posted December 16, 2020 Share Posted December 16, 2020 This is some code I wrote to do the job. In 1988. It is mixed in with some 9938 command code for LINE and PSET and all the graphics modes including 80 column. I don't think XB likes that. But here is XB CALL LINK("WRITE", vaddr, string$). There is also a FILL in there. I can't test it right now. The key source. If there are undefineds, I have attached the whole file. xbs DEF WRITE FAC EQU >834A XMLLNK EQU >2018 CFI EQU >12B8 NUMASG EQU >2008 NUMREF EQU >200C STRASG EQU >2010 STRREF EQU >2014 VDPRD EQU >8800 VDPSTA EQU >8802 VDPWD EQU >8C00 VDPWA EQU >8C02 * CALL LINK("WRITE", vaddr, string) WRITE LIMI 0 MOV R11,R12 * Get argument 1, a number LI R1,1 BL @GET MOV R0,R3 * Get argument 2, a string BL @GET$ MOV R2,R2 JEQ WRT MOV R3,R0 BLWP @VMBW WRT BL @SETB0 B *R12 * STRREF, R1=STRBUF R2=LEN GET$ CLR R0 LI R2,STRBUF SETO *R2 BLWP @STRREF MOV R2,R1 MOVB *R1+,R2 SRL R2,8 RT GET CLR R0 BLWP @NUMREF BLWP @XMLLNK DATA CFI MOV @FAC,R0 INC R1 RT VMBW DATA VWS,V4 V4 LIMI 0 MOV *R13,R0 BL @WRV MOV @2(R13),R1 MOV @4(R13),R2 JEQ V4X V4A MOVB *R1+,@VDPWD DEC R2 JNE V4A V4X RTWP VWTR DATA VWS,V5 V5 LIMI 0 MOV *R13,R0 ORI R0,>8000 SWPB R0 MOVB R0,@VDPWA SWPB R0 MOVB R0,@VDPWA RTWP SETB0 LI R0,>0E00 BLWP @VWTR RT 2 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700669 Share on other sites More sharing options...
Asmusr Posted December 16, 2020 Share Posted December 16, 2020 3 hours ago, pixelpedant said: A Myst-clone (slideshow) style adventure, for example. Crazily arduous to develop graphical assets for, using original era tools. Pretty easy, in the days of Magellan and Convert9918. I don't agree. Drawing a few characters and sprites for a homebrew game is doable for a single developer. Drawing new graphics on a larger scale is still a huge task. Unless you convert existing graphics, which can still be a big task, but then you run into issues with copyright and credits. 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700687 Share on other sites More sharing options...
RXB Posted December 16, 2020 Share Posted December 16, 2020 (edited) 4112 ************************************************************ 4113 4114 7FC0 AORG >7FC0 4116 4117 * (VDP to RAM) >834C=ADDR1,>8350=ADDR2,>834E=BCNT1 4118 * Move data from VDP to ERAM 4119 * @ADDR1 : Source address where the data stored on VDP 4120 * @ADDR2 : Destination address on ERAM 4121 * @BCNT1 : byte count 4122 4123 7FC0 VGWITE EQU $ 4124 7FC0 D7E0 MOVB @ADDR11,*R15 LSB of VDP address 7FC2 834D 4125 7FC4 C0A0 MOV @ADDR2,R2 Address in ERAM 7FC6 8350 4126 7FC8 D7E0 MOVB @ADDR1,*R15 MSB of VDP address 7FCA 834C 4127 7FCC 1000 NOP 4128 7FCE DCA0 VGZ1 MOVB @XVDPRD,*R2+ Move a byte 7FD0 8800 4129 7FD2 0620 DEC @BCNT1 One less to move 7FD4 834E 4130 7FD6 16FB JNE VGZ1 If not done, loop for more 4131 7FD8 045B RT Return 4132 ************************************************************ 1 hour ago, senior_falcon said: CALL LINK("VWRITE",address,string) is short and simple. (And VREAD as well) If you are thinking of doing this project in XB I can post the code for those. You are talking about using the XB ROMs or using your own routines? Edited December 16, 2020 by RXB comment added Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700694 Share on other sites More sharing options...
pixelpedant Posted December 16, 2020 Author Share Posted December 16, 2020 1 hour ago, Asmusr said: I don't agree. Drawing a few characters and sprites for a homebrew game is doable for a single developer. Drawing new graphics on a larger scale is still a huge task. Unless you convert existing graphics, which can still be a big task, but then you run into issues with copyright and credits. Oh, indeed, art doesn't create itself. But having a pretty much immediate route from Photoshop/Illustrator to 9918A bitmap graphics certainly is a tantalising reality, when it comes to certain fairly specific categories of game, and of game art which can benefit from this approach. And I have a personal bias which feeds my interest in this reality. After the TI-99, I think I'm most nostalgic about the early CD-ROM era. Because it created so much bizarre, idiosyncratic, and wildly varied outsider art on the back of the newfound reality that there was a cheap and widely supported medium (and sufficient supporting technologies) for distributing large volumes of more or less platform-agnostic image and/or video clip content as game media. With HyperCard and Macromedia Director games feeding into the phenomenon. Suddenly, here were are in 2020 (well, not for long), and playing video clips on a TI-99 and conveniently converting generic popular image formats for use on the TI-99 is a viable reality. Most of the time, I come back to the TI-99/4A precisely because a platform whose art styles are more so dictated and motivated by specific hardware parameters has a natural appeal. But an avenue (however limited) into the exact opposite category of game art, which makes the dangerous and somewhat dubious assumption that (with the right algorithms) the 9918A's bitmap mode can be treated as if it were a straightforward colour bitmap mode - I find that rather tantalising. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700724 Share on other sites More sharing options...
senior_falcon Posted December 16, 2020 Share Posted December 16, 2020 This is from XB256. I haven't tested to see that everything is there. I think it is, but there might be unresolved references or missing code. DEF VWRITE DEF VREAD NUMREF EQU >200C XMLLNK EQU >2018 ERR EQU >2034 VMBW EQU >2024 VMBR EQU >202C STRREF EQU >2014 STRASG EQU >2010 GETNUM INC R1 GETNU1 CLR R0 BLWP @NUMREF BLWP @XMLLNK DATA >12B8 CFI C @>834A,*R11+ JLT GTNERR C @>834A,*R11+ JGT GTNERR B *R11 GTNERR LI R0,>1E00 BLWP @ERR VWRITE LWPI WKSP MOV @>8312,R8 SRL R8,8 CLR R1 VWRIT1 BL @GETNUM DATA 0 DATA >3FFF MOV @>834A,R9 address into r9 INC R1 LI R2,BUFFER SETO *R2 BLWP @STRREF get the string MOV R1,R7 MOV R2,R1 MOVB *R1+,R2 SRL R2,8 length to r2 MOV R9,R0 VDP addr. to r0 BLWP @VMBW write it C R7,R8 JHE BK2XB MOV R7,R1 JMP VWRIT1 VREAD LWPI WKSP MOV @>8312,R8 SRL R8,8 # arguments in r8 CLR R1 VREAD1 BL @GETNUM DATA 0 DATA >3FFF MOV @>834A,R9 BL @GETNUM DATA 1 DATA 255 MOV @>834A,R2 MOV R9,R0 MOV R1,R7 LI R1,BUFFER MOVB @>834B,*R1+ BLWP @VMBR CLR R0 MOV R7,R1 INC R1 LI R2,BUFFER BLWP @STRASG C R1,R8 JLT VREAD1 BK2XB LWPI >83E0 B @>006A BUFFER BSS 256 WKSP BSS 32 5 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4700809 Share on other sites More sharing options...
pixelpedant Posted December 17, 2020 Author Share Posted December 17, 2020 Awesome. Thanks so much. And for all your work in empowering XB programmers. That is indeed doing the trick as a lightweight implementation of VREAD and VWRITE in XB, based on the expected (XB256-equivalent) functionality, compiled as follows. VDPRW Such that the following has the expected observed effect: Description of VREAD and VWRITE from the XB256 manual being (for the sake of completeness): CALL LINK(“VREAD”, memory address, # bytes, string[ , . . .]) VREAD reads the specified number of bytes from the VDP ram into a string variable of up to 255 bytes. Up to 5 strings can read with one call to VREAD. CALL LINK (“VWRITE”,memory address, string[ , . . .]) VWRITE writes a string to the VDP ram starting at the specified memory address. Up to 8 strings can be written with one call to VWRITE. 2 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4701594 Share on other sites More sharing options...
+Lee Stewart Posted December 17, 2020 Share Posted December 17, 2020 On 12/15/2020 at 4:47 PM, Lee Stewart said: I presume that STRING$ is an XB string, meaning that it resides in VRAM, and that ADDRESS is also in VRAM, so that implementing the above VWRITE routine is actually moving a string from one VRAM location to another. If so, there are a couple of ways to do this. One is much more “lightweight” than the other. The light one would require only 50 – 60 bytes beyond the CALL overhead. The heavy one, which should be a good bit faster (unless the CALL overwhelms its time), would require an additional 256-byte RAM buffer to hold the largest possible XB string. I will probably attempt both routines just for grins, but do you have a preference? ...lee A couple of other folks beat me to the buffered VWRITE. I will still do the unbuffered routine [unless someone beats me to it ?], which requires carnal knowledge of XB’s CALL LINK(). Here is how TI Forth and fbForth do a VRAM-to-VRAM unbuffered copy: * ** necessary EQUates * UTILWS EQU >???? ; set to an appropriate workspace address VDPRD EQU >8800 ; VRAM read data register VDPWD EQU >8C00 ; VRAM write data register VDPWA EQU >8C02 ; VRAM write address register * ** VRAM-to-VRAM unbuffered move ** R0: count ** R1: VRAM source ** R2: VRAM destination * VMOVE DATA UTILWS,VMOVEN ; VMOVE vector for BLWP VMOVEN ; VMOVE entry point LIMI 0 MOV *R13,R1 ; get count to R1 MOV @2(R13),R2 ; get VRAM source to R2 MOV @4(R13),R3 ; get VRAM destination to R3 ORI R3,>4000 ; prepare for VDP write ** copy count bytes from VRAM source to VRAM destination VMVMOR MOVB @UTILWS+5,@VDPWA ; write LSB of VDP read address MOVB R2,@VDPWA ; write MSB of VDP read address INC R2 ; next VDP read address MOVB @VDPRD,R0 ; read VDP byte MOVB @UTILWS+7,@VDPWA ; write LSB of VDP write address MOVB R3,@VDPWA ; write MSB of VDP write address INC R3 ; next VDP write address MOVB R0,@VDPWD ; write VDP byte DEC R1 ; decrement count JNE VMVMOR ; repeat if not done RTWP ; return to calling program This will need to be BLWPed from the CALLed routine, which should be pretty small. ...lee 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702014 Share on other sites More sharing options...
senior_falcon Posted December 17, 2020 Share Posted December 17, 2020 You have glossed over an important detail. If 10 A$="hello world" then where in the VDP memory is "hello world"? You cannot move it unless you know where it is. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702051 Share on other sites More sharing options...
+Lee Stewart Posted December 17, 2020 Share Posted December 17, 2020 31 minutes ago, senior_falcon said: You have glossed over an important detail. If 10 A$="hello world" then where in the VDP memory is "hello world"? You cannot move it unless you know where it is. I guess I was not very clear. I really have not glossed over that important detail because I have not yet written the routine to be CALLed from XB. That routine (VWRITU, perhaps) will get the location of said string from the passed argument list as it will the VRAM destination address. It just will not copy it to a RAM buffer as STRREF does. The routine I shared is the one that VWRITU will call. ...lee Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702084 Share on other sites More sharing options...
RXB Posted December 18, 2020 Share Posted December 18, 2020 1 hour ago, senior_falcon said: You have glossed over an important detail. If 10 A$="hello world" then where in the VDP memory is "hello world"? You cannot move it unless you know where it is. Just so you know RXB 2020 shows with SIZE where the first free memory is in VDP and RAM along with Lower 8K. If you type in A$="Hello World" and then SIZE it shows the First Free address is in VDP and that would be address of string A$ then Length byte then that string ending in a >0B Use Classic99 debugger to look at VDP from SIZE says >37CD and there is that string. Type in B$="Goodbye Word" and it shows less memory and >37C3 and always shows end of that string as the address. So it always shows the last address used and Free. Might be a useful tool. Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702121 Share on other sites More sharing options...
senior_falcon Posted December 18, 2020 Share Posted December 18, 2020 18 hours ago, Lee Stewart said: I guess I was not very clear. I really have not glossed over that important detail because I have not yet written the routine to be CALLed from XB. That routine (VWRITU, perhaps) will get the location of said string from the passed argument list as it will the VRAM destination address. It just will not copy it to a RAM buffer as STRREF does. The routine I shared is the one that VWRITU will call. ...lee You will probably use STRREF as the starting point for your code. You will be surprised to see how inefficient XB STRREF is. They could have set up the address to read from, then done a standard loop like this: LOOP MOVB @>8800,*R1+ DEC R2 JNE LOOP Instead there is a sub to set the address for every read: SWPB R3 MOVB R3,@>8C02 SWPB R3 MOVB R3,@>8C02 NOP MOVB @>8800,R1 B *R11 And after returning R1 is stored in the buffer. After seeing I feel better about some of the sloppy code I write. 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702643 Share on other sites More sharing options...
+Lee Stewart Posted December 18, 2020 Share Posted December 18, 2020 2 hours ago, senior_falcon said: You will probably use STRREF as the starting point for your code. You will be surprised to see how inefficient XB STRREF is. No, I will be using the pointers XB uses in scratchpad RAM. Like I said, it requires carnal knowledge of CALL LINK()’s innards. I just need to grab the time to write it and test it. Soon.... ...lee 2 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4702747 Share on other sites More sharing options...
senior_falcon Posted December 20, 2020 Share Posted December 20, 2020 I found a way to modify STRREF to eliminate the slow subroutine at >2406. Here are the pertinent lines of code currently: H239C MOV R6,R3 SRL R1,8 MOV R1,R5 change to MOV R1,R2 (number of bytes to move) H23A2 BL @H2406 MOVB R1,*R0+ INC R3 MOV R0,R1 H24AE MOVB @>8800,*R1+ (this is part of VMBR) DEC R5 B @H24B2 -----> DEC R2 JGT H23A2 JNE H24AE RTWP RTWP Then the sub is: H2406 SWPB R3 MOVB R3,@>8C02 SWPB R3 MOVB R3,@>8C02 JMP H2414 MOVB @>8800,R1 B *R11 You can see that once the loop has started there are only 3 instructions to move a byte vs. 12 instructions. That should really speed things up, right? Not so much, as it turns out. It takes 37 seconds to read a 255 byte long string 500 times in XB It takes 25 seconds to read a 255 byte long string 500 times with the modified routine. This is the best case scenario. Most strings will be less than 255 bytes long, and of course you would want to do something with the string after reading it to the buffer. So in the real world you would probably not see any detectable improvement. 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4704088 Share on other sites More sharing options...
Fredrik Öhrström Posted December 21, 2020 Share Posted December 21, 2020 In 1988 I wrote a CALL LOAD/LINK implementations of VMBW, VMBR,POKEV and PEEKV for normal Extended Basic + Memory expansion. You can read the X-basic program on page 9 in this pdf: http://nivelleringslikaren.eu/nittinian/nittinian_1988_nr3.pdf 1 Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4705248 Share on other sites More sharing options...
RXB Posted December 22, 2020 Share Posted December 22, 2020 19 hours ago, Fredrik Öhrström said: In 1988 I wrote a CALL LOAD/LINK implementations of VMBW, VMBR,POKEV and PEEKV for normal Extended Basic + Memory expansion. You can read the X-basic program on page 9 in this pdf: http://nivelleringslikaren.eu/nittinian/nittinian_1988_nr3.pdf Some way to translate this? Quote Link to comment https://forums.atariage.com/topic/314619-is-there-a-minimal-xb-assembly-subroutine-implementation-out-there-somewhere-which-just-implements-string-writes-to-vdp-memory/#findComment-4705813 Share on other sites More sharing options...
Recommended Posts
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.