+Vorticon Posted June 28, 2021 Share Posted June 28, 2021 3 minutes ago, senior_falcon said: VSBW, VSBR, VMBW, VMBR, VWTR are all there and can be used as usual. NUMASG, NUMREF, STRASG, STREF cannot work. They were written to pass values to and from an XB program. They would have no idea where the strings and numbers are kept in a compiled program. Since everything is integer, CFI and CIF have no purpose and are simply bypassed. Got it. Thanks for the info. 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted June 28, 2021 Share Posted June 28, 2021 TI-Net BBS took advantage of this. The LOAD program is made with SYSTEX (Barry Boone) and it fills up the low memory with object code. Then it chains to BBS. It can chain to “Doors” programs (that is, games). When the game exits, it hangs up and runs BBS again. Assembly routines are only loaded one time. 2 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted June 28, 2021 Share Posted June 28, 2021 29 minutes ago, Vorticon said: Got it. Thanks for the info. I should add that this is totally transparent to the user. When you test the program in XB you can use any of the assembly support utilities as desired. When it's time to compile there is a utility called FIXAL that modifies the assembly support routines so they will work with the compiler. If you use XB 2.8 G.E.M. you will find that loading the assembly routines for testing happens 20X faster 2 Quote Link to comment Share on other sites More sharing options...
Jeff White Posted June 28, 2021 Share Posted June 28, 2021 It has been years since I looked at it, but I seem to recall that you can force XB to use high memory (A000-FFFF) for assembly and low memory (2000-3FFF) plus VRAM for XBASIC code. It takes some effort and probably breaks a few things. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted June 28, 2021 Share Posted June 28, 2021 4 minutes ago, Jeff White said: It has been years since I looked at it, but I seem to recall that you can force XB to use high memory (A000-FFFF) for assembly and low memory (2000-3FFF) plus VRAM for XBASIC code. It takes some effort and probably breaks a few things. You can AORG an ALC program into high memory, but it will have to coexist with the XB program. I am not aware you could force XB into low memory but I might be wrong there. Besides, since the idea to mix XB and assembly is to avoid the tediousness of pure assembly for complex tasks while delegating features not available in XB or too slow to assembly, restricting XB to the lower 8K would likely be too restrictive for most projects... Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted June 29, 2021 Share Posted June 29, 2021 2 hours ago, Vorticon said: You can AORG an ALC program into high memory, but it will have to coexist with the XB program. I am not aware you could force XB into low memory but I might be wrong there. Besides, since the idea to mix XB and assembly is to avoid the tediousness of pure assembly for complex tasks while delegating features not available in XB or too slow to assembly, restricting XB to the lower 8K would likely be too restrictive for most projects... Actually, with some cleverness there is a great deal of flexibility in where XB can put programs. For example: CALL INIT::CALL LOAD(-31868,0,0,0,0) Type SIZE and you'll see that the memory expansion is turned off and XB will run completely from VDP ram. But CALL LOAD didn't get the message, so you can still poke values wherever you want. Or you can CALL LOAD an object file anywhere in the memory expansion. You'll need to AORG the code to high memory, but you can use all 32K for assembly, plus about 12K for the XB program in VDP. Since you can put the XB program into 12K of VDP ram, it wouldn't make much sense to put it in the 8K low memory. If 24K is not large enough for your XB program, you can split the program between high and low memory and use all 32K for an XB program. In the Game Developer's Package there is a file called XB32K.OBJ which lets you do just that. HMLOADER lets you embed assembly routines in an XB program and run them from high memory. This makes a neat, self contained package that contains everything in one program. 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted June 29, 2021 Share Posted June 29, 2021 15 minutes ago, senior_falcon said: Actually, with some cleverness there is a great deal of flexibility in where XB can put programs. For example: CALL INIT::CALL LOAD(-31868,0,0,0,0) Type SIZE and you'll see that the memory expansion is turned off and XB will run completely from VDP ram. But CALL LOAD didn't get the message, so you can still poke values wherever you want. Or you can CALL LOAD an object file anywhere in the memory expansion. You'll need to AORG the code to high memory, but you can use all 32K for assembly, plus about 12K for the XB program in VDP. Since you can put the XB program into 12K of VDP ram, it wouldn't make much sense to put it in the 8K low memory. If 24K is not large enough for your XB program, you can split the program between high and low memory and use all 32K for an XB program. In the Game Developer's Package there is a file called XB32K.OBJ which lets you do just that. HMLOADER lets you embed assembly routines in an XB program and run them from high memory. This makes a neat, self contained package that contains everything in one program. This is the realm of black magic! I am only but a poor accolyte... Quote Link to comment Share on other sites More sharing options...
Jeff White Posted June 29, 2021 Share Posted June 29, 2021 19 hours ago, senior_falcon said: Actually, with some cleverness there is a great deal of flexibility in where XB can put programs. For example: CALL INIT::CALL LOAD(-31868,0,0,0,0) Type SIZE and you'll see that the memory expansion is turned off and XB will run completely from VDP ram. But CALL LOAD didn't get the message, so you can still poke values wherever you want. Or you can CALL LOAD an object file anywhere in the memory expansion. You'll need to AORG the code to high memory, but you can use all 32K for assembly, plus about 12K for the XB program in VDP. Since you can put the XB program into 12K of VDP ram, it wouldn't make much sense to put it in the 8K low memory. If 24K is not large enough for your XB program, you can split the program between high and low memory and use all 32K for an XB program. In the Game Developer's Package there is a file called XB32K.OBJ which lets you do just that. HMLOADER lets you embed assembly routines in an XB program and run them from high memory. This makes a neat, self contained package that contains everything in one program. I think that CALL LOAD is just clearing the values for first free address (FFA) and last free address (LFA) of 24K to make it “disappear”. I am pretty sure that I was able to point the FFA and LFA using values in the range 2000-3FFF and manipulated some other values to CALL LOAD object code into 24K without using AORG. I had limited success. It made sense to do it at the time. I could be misremembering. Quote Link to comment Share on other sites More sharing options...
RXB Posted June 29, 2021 Share Posted June 29, 2021 23 hours ago, Vorticon said: You can AORG an ALC program into high memory, but it will have to coexist with the XB program. I am not aware you could force XB into low memory but I might be wrong there. Besides, since the idea to mix XB and assembly is to avoid the tediousness of pure assembly for complex tasks while delegating features not available in XB or too slow to assembly, restricting XB to the lower 8K would likely be too restrictive for most projects... Check out RXB 2020 it has CALL PRAM(start low memory address, end high memory address) ! for XB programs in upper 24K where XB programs reside CALL VDPSTACK(VDP stack memory location) ! for XB to change location of VDP Stack in VDP so changes VDP RAM use and control CALL PLOAD(memory address boundary ,"DSK#.filename") ! will load at any 32K location 4K file into memory (i.e. example >B000 ) CALL SAMS(memory address boundary , page number) ! changes SAMS page number at boundary address (i.e. example >A000) 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted July 6, 2021 Share Posted July 6, 2021 Hi. Does anyone know if the CFI function (XMLLNK) trashes R5? It seems to be the case but I want to make sure. There is no mention of that in the EA manual... Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted July 6, 2021 Share Posted July 6, 2021 1 hour ago, Vorticon said: Hi. Does anyone know if the CFI function (XMLLNK) trashes R5? It seems to be the case but I want to make sure. There is no mention of that in the EA manual... Not unless you are using FAC as your workspace. When you BLWP @XMLLNK DATA >1200 the workspace is changed to >2094. The return is then changed to the instruction following the DATA directive and the workspace is again changed to the GPLWS (>83E0) before BLing to the CFI routine. After CFI returns, the workspace is reverted to >2094 and the RTWP, of course, reverts to your workspace, continuing execution with the instruction following the DATA directive. No register in your workspace is touched unless it overlaps FAC, >2094, or GPLWS. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted July 6, 2021 Share Posted July 6, 2021 1 hour ago, Lee Stewart said: Not unless you are using FAC as your workspace. When you BLWP @XMLLNK DATA >1200 the workspace is changed to >2094. The return is then changed to the instruction following the DATA directive and the workspace is again changed to the GPLWS (>83E0) before BLing to the CFI routine. After CFI returns, the workspace is reverted to >2094 and the RTWP, of course, reverts to your workspace, continuing execution with the instruction following the DATA directive. No register in your workspace is touched unless it overlaps FAC, >2094, or GPLWS. ...lee Well, I have this nasty habit of not creating my own workspace and just using the default registers, so I don't think that's it... I really should stop doing that regardless ? In the mean time, I just replaced R5 with a different register until I figure this out. I would never have guessef was it not for the Classic99 debugger... Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 13, 2021 Share Posted August 13, 2021 I'm working on a mixed XB and assembly project. Below is an excerpt of an ALC routine called from XB. It worked fine without using a dedicated user space. But when I added the LWPI instruction it crashed. I have never bothered to create my own register user space in the past (I know, heresy...) but that's been causing issues here with the XB assembly support utilities which seem to modify certain registers when used. Any hints? DEF RSTMAP,UPDMAP,WINDOW,MODMAP DEF ADDUNT VMBW EQU >2024 NUMREF EQU >200C XMLLNK EQU >2018 CFI EQU >12B8 FAC EQU >834A WSPREG EQU >8300 RETADR BSS 8 RSTMAP MOV R11,@RETADR MOV R13,@RETADR+2 MOV R14,@RETADR+4 MOV R15,@RETADR+6 LWPI WSPREG CLR @MAPPTR MOV @RETADR,R11 MOV @RETADR+2,R13 MOV @RETADR+4,R14 MOV @RETADR+6,R15 RT etc... 1 Quote Link to comment Share on other sites More sharing options...
+9640News Posted August 13, 2021 Share Posted August 13, 2021 24 minutes ago, Vorticon said: I'm working on a mixed XB and assembly project. Below is an excerpt of an ALC routine called from XB. It worked fine without using a dedicated user space. But when I added the LWPI instruction it crashed. I have never bothered to create my own register user space in the past (I know, heresy...) but that's been causing issues here with the XB assembly support utilities which seem to modify certain registers when used. Any hints? DEF RSTMAP,UPDMAP,WINDOW,MODMAP DEF ADDUNT VMBW EQU >2024 NUMREF EQU >200C XMLLNK EQU >2018 CFI EQU >12B8 FAC EQU >834A WSPREG EQU >8300 RETADR BSS 8 RSTMAP MOV R11,@RETADR MOV R13,@RETADR+2 MOV R14,@RETADR+4 MOV R15,@RETADR+6 LWPI WSPREG CLR @MAPPTR MOV @RETADR,R11 MOV @RETADR+2,R13 MOV @RETADR+4,R14 MOV @RETADR+6,R15 RT etc... How about changing WSPREG EQU >8300 to WSPREG BSS 32 That way, you create the workspace within your code. I think that works with XB assembly, but not 100% certain. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 13, 2021 Share Posted August 13, 2021 The problem with this is that it slows things down quite a bit. It's recommended to keep the user space in the scratchpad RAM for maximum performance. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted August 13, 2021 Share Posted August 13, 2021 I believe XB drops you into a shared WP. You can use your own workspace but you need to restore it before returning from your code. There is STWP, I don't remember if that has general addressing or must go to a "register". If necessary move it to a well known address so you can get at it later. Then before return the only way I could figure out was to MOV the desired return WS address into the parameter address of the LWPI code.. mov @wpstash, @8(WPRT) WPRT LWPI >0000 ; dummy value for assembler rt something like that... Or, use a BLWP to get to your code that wants its own WP, and return from it with RTWP 2 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted August 13, 2021 Share Posted August 13, 2021 Your example is nearly implementing BLWP and RTWP except it is missing the part that restores WP. I'd just use the actual instructions... 3 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 13, 2021 Share Posted August 13, 2021 32 minutes ago, Vorticon said: The problem with this is that it slows things down quite a bit. It's recommended to keep the user space in the scratchpad RAM for maximum performance. There are not a lot of safe places in the scratchpad ram when doing CALL LINK. When LINK is performed, it starts with the GPLWS at >83E0. You can use some of this workspace. R0 to maybe R10. Other places might be OK for a workspace if you store the contents and restore them. But using STRREF, NUMASG, etc might interfere with that. Remember, you are interfacing with Extended BASIC which is not exactly a speed demon. Even the most poorly written assembly code will give stellar performance compared to XB. 3 Quote Link to comment Share on other sites More sharing options...
RXB Posted August 13, 2021 Share Posted August 13, 2021 On 6/28/2021 at 4:04 PM, Jeff White said: It has been years since I looked at it, but I seem to recall that you can force XB to use high memory (A000-FFFF) for assembly and low memory (2000-3FFF) plus VRAM for XBASIC code. It takes some effort and probably breaks a few things. RXB 2020 has this built in using CALL PRAM(address-low,address-high) for location of XB program space. And CALL VDPSTACK(address) for location of VDP STACK ADDRESS. Also CALL PLOAD(address-boundry,"DSK#.FILENAME") for loading memory image 4K sized files into any area of memory in 32K. This works like CALL SAMS(address-boundry,RAM-page) for address of RAM and what page to use. And no RXB did not break anything in the process. 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 13, 2021 Share Posted August 13, 2021 I think I'm just going to forgo setting up my own user space in the context of XB and ALC. Seems like more trouble than it's worth. It works fine without it as long as I am careful about my register use choices. Thanks for the pointers guys. 3 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted August 14, 2021 Share Posted August 14, 2021 Well.. if you want an example... https://github.com/jedimatt42/tipi-xb-mouse/blob/b087823c16195d0192a4cd481927a34fe54865ed/tmororg.a99#L92 2 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 14, 2021 Share Posted August 14, 2021 I'm not sure I understand what's going on here... MOV @WORKSV,@$+8 ; this writes WP into next instruction, first param, as though it was literal LWPI >AAAA Aren't you overwriting the recovered WP address with >AAAA? Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted August 14, 2021 Share Posted August 14, 2021 The assembler produces the LWPI >AAAA instruction, which is 2 words in the binary. But at runtime, the MOV before it rewrites that instruction for the desired value of the immediate operand. That move instruction is using @$ which in xas99 is the address of the current instruction. So +8 gets the address of the parameter to LWPI. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 14, 2021 Share Posted August 14, 2021 1 hour ago, Vorticon said: I'm not sure I understand what's going on here... MOV @WORKSV,@$+8 ; this writes WP into next instruction, first param, as though it was literal LWPI >AAAA Aren't you overwriting the recovered WP address with >AAAA? No. It is quite the other way around. This is self-modifying code that replaces the placeholder, >AAAA, with the contents of WORKSV at execution time. ...lee 5 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted August 14, 2021 Share Posted August 14, 2021 I checked my BBS assembly code (just to be sure I was remembering correctly) and I am using GPLWS >83E0 registers for many of the routines, including those that pass parameters via CALL LINK. If I need to BL to another routine, I save R11 then restore prior to exiting to XB. I also save R12 if I modify it, though it probably isn't necessary. One of my go-to references is the Millers Graphics "The Smart Programmer", August 1986, which contains a comprehensive overview of XB scratchpad usage. [MG also published VDP RAM and CPU ram and scratchpad ram usage for XB/EA/MiniMem, in other issues]. The snip below details the >83E0 workspace bytes; the keyscan and interrupt routines use some of the registers, meaning you may want to disable interrupts (LIMI 0) and/or account for any potential changes to registers. Note: the typical DSRLNK routine starts (and in some cases the peripheral DSR expects) execution of the DSR ROM routines with the workspace pointer set to >83E0, so it is usually best to set up your own workspace in some manner when calling IO routines. 3 Quote Link to comment 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.