+Lee Stewart Posted January 17, 2017 Share Posted January 17, 2017 The XMLLNK DATA values for CFI and CIF do not look right to me. IIRC, CIF (integer to float) is accessed via >0020. I don't have access to reference material to confirm the values at this time. CFI is >12B8 and CIF is >0020 for Extended Basic. See comments in later posts. , indeed, >1200 as Walid has it. However, >2300 for CIF only works with the E/A cartridge, not The XB cartridge, because it is copied to >2006 only by the E/A cartridge. Walid, you will need to copy the E/A routine to your PIOLIB and branch to it, rather than invoking it with XMLLNK. I will dig up the CIF routine from the 9640 L10 library I modified for fbForth 2.0. ...lee Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 k* CFI is, indeed, >1200 as Walid has it. However, >2300 for CIF only works with the E/A cartridge, not the XB cartridge, because it is copied to >2006 only by the E/A cartridge. Walid, you will need to copy the E/A routine to your PIOLIB and branch to it, rather than invoking it with XMLLNK. I will dig up the CIF routine from the 9640 L10 library I modified for fbForth 2.0. ...lee Gosh! This project is definitely a learning experience. That would explain part of the issues I have, but not all. I ended up saving the return registers in RAM and restoring them upon return because I could not be sure that the R4 to R7 registers I was initially using were not being corrupted by some of the utility routines. It did not solve any of my issues but at least it eliminated one potential source of problems. My FAC operations were not correct either because I was treating it like a 16bit register. SWPB @FAC will not work for example (I *think* - right?). I'll post the updated source once I am back home tomorrow. 10 CALL CLEAR 20 CALL INIT 30 CALL LOAD("DSK1.PIOLIB") 40 CALL LINK("PIOINI") / LED turns on 50 FOR I=1 TO 20::PRINT I::NEXT I 60 CALL LINK("PIOOFF") / Nothing happens.. 70 END When I run this test, the LED comes on, the numbers 1 to 20 are printed to the screen indicating that the PIOINI returned successfully to XB, and then the program exits normally, but the LED stays on. The XB environment at this point appears normal with no corruption, however if I reset the computer then it locks up and I have to cycle the PEB power to get things started again. Since PIOOFF is super simple with no utility calls or argument passing, I suspect that there is something problematic at the hardware level that I am overlooking. Are we having fun yet? Truth be told though that half the enjoyment I get from this retrocomputing hobby is working the problems and eventually bending the beast to my will. It's positively masochistic. Go figure Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted January 17, 2017 Share Posted January 17, 2017 For example, when I call PIOINI, the LED comes on as expected. However, if I subsequently call PIOOFF, nothing happens and the LED stays on. PIOOFF does not get simpler than that with no utility calls or argument passing at all, so there must be something fundamentally problematic at the hardware level. /snip/ however if I reset the computer then it locks up and I have to cycle the PEB power to get things started again. Are we having fun yet? Based on your posted code... keep in mind that whenever you return to XB, all bets are off with respect to the GPLWS registers and their values.... especially if you are expecting one or more of them to be static when you re-enter your assembly code. That said, which register is critical to your CRU bit twiddling in PIOOFF? Resolving that answer should also help with the PEB lockup issue you experienced. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 Based on your posted code... keep in mind that whenever you return to XB, all bets are off with respect to the GPLWS registers and their values.... especially if you are expecting one or more of them to be static when you re-enter your assembly code. That said, which register is critical to your CRU bit twiddling in PIOOFF? Resolving that answer should also help with the PEB lockup issue you experienced. If this is a quiz, then I am failing miserably! Unless you mean R12!!! Ah ha!!! I'm starting to glimpse the issue here: I essentially need to reload R12 with the DSR address of the RS232 card with every call. As things stand, I am only doing this with PIOINI and assuming that R12 is preserved, and if it's not then god knows what my machinations are doing to the computer. I have a good feeling about this I'll test it out first thing tomorrow morning. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2017 Share Posted January 17, 2017 I should think that if turning the LED on requires turning bit 7 on, then it might require turning bit 7 off to turn it off before you turn off bit 0 to deactivate the card. Anyway, Tim is right—all calls that twiddle PIO bits need to be talking to the right DSR, which can only happen by insuring that R12 contains the right CRU address (>1300). ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2017 Share Posted January 17, 2017 I was wrong about the XMLLNK addresses for CFI and CIF for Extended Basic! Tim and I worked it out—mostly Tim, as I was a beat behind him in a private discussion. He may clarify more in a bit, but I corrected the addresses above and you won't need my CIF routine: CFI EQU >12B8 CIF EQU >0020 See page 415 of the E/A Manual. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 I should think that if turning the LED on requires turning bit 7 on, then it might require turning bit 7 off to turn it off before you turn off bit 0 to deactivate the card. Anyway, Tim is right—all calls that twiddle PIO bits need to be talking to the right DSR, which can only happen by insuring that R12 contains the right CRU address (>1300). ...lee Yup that's what I did but it did not work, likely because the CRU address is not properly set up after the first call. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 I was wrong about the XMLLNK addresses for CFI and CIF for Extended Basic! Tim and I worked it out—mostly Tim, as I was a beat behind him in a private discussion. He may clarify more in a bit, but I corrected the addresses above and you won't need my CIF routine: CFI EQU >12B8 CIF EQU >0020 See page 415 of the E/A Manual. ...lee Thanks guys. I really need to go over that section of the E/A manual closely. Between this info and the R12 preservation, I think the routines will work as intended. I'll keep you posted. 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted January 17, 2017 Share Posted January 17, 2017 The short explanation is that the Extended BASIC XMLLNK is not the same as that loaded by EA Support utilities. I went back to the Smart Programmer Newsletter, Sept 1984, which pointed to the EA manual appendix Lee refers to above: Why doesn't Extended Basic's XMLLNK work properly? The XMLLNK that is loaded into Low Memory Expansion by Extended Basic's CALL INIT is different than the XMLLNK loaded by the Editor/Assembler or the one in the Mini Memory. In the back of the Editor/Assembler manual on pages 415-418 you will find a list of XB Equates. Use the Equates from FADD through GVWITE for the DATA statement following BLWP @XMLLNK and XB's XMLLNK will work properly, I Don't know why TI changed so many of the routines in XB as compared to E/A, By the way, the Equates listed from FADD to NEXT are ABSOLUTE ROM addresses for ALL consoles! The equates that are a byte in length like GIF EQU >26 are XML Table pointers that use routines built into XB's Cartridge ROM. I vaguely remember looking at the appendix long, long, long ago and ever since, have just used and recycled my own code, forgetting where the original knowledge came from. It has been over 30 years in some cases... that's a sobering thought. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted January 17, 2017 Share Posted January 17, 2017 I know this is coming late, but I really recommend that you don't leave the card enabled on return from the CALL LINK. The XB environment does not expect that a DSR is mapped in, and will happily activate other cards if asked to. Since the mapping happens on a per-card basis (and not globally), it is possible to have two cards activated and have both of them attempt to drive the bus, which is bad. This is the likely reason for your crash on attempted reset -- nothing ever tells the cards to shut off on reset... 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 Once again thanks for all the help guys! I have incorporated all of the corrections and recommendations you gave me, and tested the whole thing on hardware and it works like a charm. There is something special about using XB to control stuff. I'm working of finalizing a blog entry with all the gory details for those interested in interfacing projects using XB and the parallel port. Here's the final source code. ** XB PIO LOW LEVEL CONTROL UTILITIES ** ** JANUARY 2017 ** ** BY WALID MAALOULI ** DEF DATOUT,DATIN,HSKIN,HSKOUT,SPRIN,SPROUT PIO EQU >5000 PIO PORT DATA ADDRESS FAC EQU >834A FLOATING POINT ACCUMULATOR ADDRESS XMLLNK EQU >2018 NUMASG EQU >2008 NUMREF EQU >200C REGSTR BSS 8 STORAGE FOR RETURN REGISTERS ** SEND DATA OUT TO DATA LINES DATOUT MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMREF FETCH ARGUMENT AND PLACE IN FAC BLWP @XMLLNK DATA >12B8 CONVERT ARGUMENT TO INTEGER SBZ 1 SET PIO PORT TO OUTPUT MOVB @FAC+1,@PIO SEND BYTE TO PIO PORT B @RETURN ** RECEIVE DATA FROM DATA LINES DATIN MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI SBO 1 SET PIO PORT TO INPUT MOVB @PIO,R2 GET BYTE FROM PIO PORT INTO R2 CLR @FAC MOVB R2,@FAC+1 MOVE RECEIVED BYTE TO LOW BYTE OF FAC BLWP @XMLLNK DATA >0020 CONVERT BYTE TO FLOATING FLOATING POINT NUMBER CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMASG ASSIGN NUMBER TO SELECTED ARGUMENT B @RETURN ** SEND BIT TO HANDSHAKEOUT LINE HSKOUT MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMREF GET VALUE FROM ARGUMENT INTO FAC BLWP @XMLLNK DATA >12B8 CONVERT VALUE TO INTEGER MOV @FAC,R2 CI R2,1 JNE HSKRST SBO 2 SET HANDSHAKEOUT LINE TO LOGIC 1 B @RETURN HSKRST SBZ 2 SET HANDSHAKEOUT LINE TO LOGIC 0 B @RETURN ** RECEIVE LOGIC STATUS OF HANDSHAKEIN LINE HSKIN MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI TB 2 READ LOGIC STATUS OF HANDSHAKEIN LINE JNE HSKIN0 LI R2,1 JMP SNDVAL HSKIN0 CLR R2 SNDVAL MOV R2,@FAC BLWP @XMLLNK DATA >0020 CONVERT LINE BIT VALUE TO FLOAT NUMBER CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMASG SEND LOGIC STATUS TO ARGUMENT 1 B @RETURN ** SEND BIT TO SPAREOUT LINE SPROUT MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMREF PLACE VALUE OF ARGUMENT 1 INTO FAC BLWP @XMLLNK DATA >12B8 CONVERT ARGUMENT VALUE TO INTEGER MOV @FAC,R2 CI R2,1 JNE SPRRST SBO 3 SET THE SPROUT LINE B @RETURN SPRRST SBZ 3 RESET THE SPROUT LINE B @RETURN ** RECEIVE LOGIC STATUS OF THE SPRIN LINE SPRIN MOV R11,@REGSTR MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 BL @PIOINI TB 3 READ THE LOGIC STATE OF THE SPRIN LINE JNE SPRIN0 LI R2,1 JMP SNDVAL SPRIN0 CLR R2 JMP SNDVAL ** INITIALIZE RS232 CARD PIOINI LI R12,>1300 PLACE RS232 CARD CRU ADDRESS IN R12 SBO 0 ACTIVATE CARD SBO 7 TURN CARD LED ON RT ** RETURN TO XB RETURN SBZ 7 TURN CARD LED OFF SBZ 0 INACTIVATE RS232 CARD MOV @REGSTR,R11 MOV @REGSTR+2,R13 MOV @REGSTR+4,R14 MOV @REGSTR+6,R15 RT END 4 Quote Link to comment Share on other sites More sharing options...
Tursi Posted January 17, 2017 Share Posted January 17, 2017 Very nice looking code! Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 17, 2017 Author Share Posted January 17, 2017 Very nice looking code! I'm going to frame that statement! Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 23, 2017 Author Share Posted January 23, 2017 Lee was kind enough to optimize the PIOLIB code as noted below. Functionality is the same. ** XB PIO LOW LEVEL CONTROL UTILITIES ** ** JANUARY 2017 ** ** BY WALID MAALOULI ** ** MOD 5 LES ** DEF DATOUT,DATIN,HSKIN,HSKOUT,SPRIN,SPROUT PIO EQU >5000 PIO PORT DATA ADDRESS FAC EQU >834A FLOATING POINT ACCUMULATOR ADDRESS XMLLNK EQU >2018 NUMASG EQU >2008 NUMREF EQU >200C CFI EQU >12B8 CIF EQU >0020 REGSTR BSS 8 STORAGE FOR RETURN REGISTERS ** SEND DATA OUT TO DATA LINES DATOUT MOV R11,@REGSTR BL @PIOINI BL @GETARG FETCH XB ARGUMENT 1 TO FAC BLWP @XMLLNK CONVERT ARGUMENT DATA CFI TO INTEGER SBZ 1 SET PIO PORT TO OUTPUT MOVB @FAC+1,@PIO SEND BYTE TO PIO PORT JMP RETURN ** RECEIVE DATA FROM DATA LINES DATIN MOV R11,@REGSTR BL @PIOINI CLR @FAC SBO 1 SET PIO PORT TO INPUT MOVB @PIO,@FAC+1 GET BYTE FROM PIO PORT INTO LSB OF FAC BLWP @XMLLNK CONVERT INTEGER DATA CIF TO FLOAT NUMBER JMP PUTARG CONVERT & SEND BYTE TO XB ARG 1 AND RETURN ** SEND BIT TO HANDSHAKEOUT LINE HSKOUT MOV R11,@REGSTR BL @PIOINI BL @GETARG FETCH XB ARGUMENT 1 TO FAC MOVB @FAC+1,R2 FAC+1 = 0? JEQ HSKRST YES; RESET HANDSHAKEOUT LINE SBO 2 NO; SET HANDSHAKEOUT LINE TO LOGIC 1 JMP RETURN HSKRST SBZ 2 SET HANDSHAKEOUT LINE TO LOGIC 0 JMP RETURN ** RECEIVE LOGIC STATUS OF HANDSHAKEIN LINE HSKIN MOV R11,@REGSTR BL @PIOINI TB 2 READ LOGIC STATUS OF HANDSHAKEIN LINE HSKSPR JEQ HSKIN0 <<< SPRIN JUMPS HERE TO FINISH CLR @FAC FAC = FP 0 (REMAINING 6 BYTES DO NOT MATTER) JMP PUTARG SEND LINE BIT VALUE TO XB ARG 1 & RETURN HSKIN0 LI R2,>4001 EXPONENT AND FIRST RADIX-100 DIGIT, WHICH = 1 MOV R2,@FAC TO FAC CLR @FAC+2 ZERO CLR @FAC+4 REMAINDER CLR @FAC+6 OF FP NUMBER IN FAC JMP PUTARG SEND LINE BIT VALUE TO XB ARG 1 & RETURN ** SEND BIT TO SPAREOUT LINE SPROUT MOV R11,@REGSTR BL @PIOINI BL @GETARG FETCH XB ARGUMENT 1 TO FAC MOVB @FAC+1,R2 FAC+1 = 0? JEQ SPRRST YES; RESET SPROUT LINE SBO 3 SET THE SPROUT LINE JMP RETURN SPRRST SBZ 3 RESET THE SPROUT LINE JMP RETURN ** RECEIVE LOGIC STATUS OF THE SPRIN LINE SPRIN MOV R11,@REGSTR BL @PIOINI TB 3 READ THE LOGIC STATE OF THE SPRIN LINE JMP HSKSPR JUMP INTO HSKIN TO FINISH >>> ** INITIALIZE RS232 CARD PIOINI MOV R13,@REGSTR+2 MOV R14,@REGSTR+4 MOV R15,@REGSTR+6 LI R12,>1300 PLACE RS232 CARD CRU ADDRESS IN R12 SBO 0 ACTIVATE CARD SBO 7 TURN CARD LED ON RT ** CONVERT XB ARGUMENT 1 TO INTEGER IN FAC GETARG CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMREF FETCH ARGUMENT AND PLACE IN FAC RT ** RETURN ARGUMENT TO XB PUTARG CLR R0 LI R1,1 SELECT ARGUMENT 1 FROM XB CALL BLWP @NUMASG SEND CONVERTED INT TO ARGUMENT 1 ** RETURN TO XB RETURN SBZ 7 TURN CARD LED OFF SBZ 0 INACTIVATE RS232 CARD MOV @REGSTR,R11 MOV @REGSTR+2,R13 MOV @REGSTR+4,R14 MOV @REGSTR+6,R15 RT END 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted January 23, 2017 Share Posted January 23, 2017 (edited) I use my routine CALL EXECUTE(RAM ADDRESS) and CALL LOAD and CALL PEEK to move values same way I did this in my game program IN THE DARK Now I have been told this is no faster then CALL LINK but each time a CALL LINK is called it has to check the VDP STACK, Variables and update values, while CALL EXECUTE does not so that would indicate that my CALL EXECUTE would be faster in the long run the more times called as many less checks and updates are needed. Also as most can be done in Assembly area this means I can push values using Assembly directly without the checks. of course that also means no errors are allowed at all or you crash the system. CALL EXECUTE works like assembly program: AORG >8300 DATA >8302 * First address BLWP @>834A * Switch context from GPL WS to Scratch FAC address >834A CLR @>837C * Clear GPL Status byte for return to XB RT * Return to GPL WS END * FAC >834A is Workspace and values loaded there are then used in Registers * Advantage of this is RXB WS is more Registers to use than normal CALL LINK allows. Now that is the core of CALL EXECUTE, but how small are the programs? 100 CALL INIT 110 CALL LOAD(9838,47,0,38,114,4,32,32,44,3,128) 120 CALL LOAD(12032,0,0,48,0,2,255) 130 CALL EXECUTE(9838)! Above does a VMBR from VDP >0000 to RAM >3000 140 CALL LOAD(9838,47,0,38,114,4,32,32,36,3,128) 150 CALL LOAD(12032,0,0,48,0,2,255) 160 CALL EXECUTE(9838) ! Above does a VMBW from RAM >3000 to VDP >0000 170 CALL VCHAR(1,1,32,768) ! Slower version of CALL CLEAR 180 GOTO 160 The above RXB program used: Register R0 is the VDP address >0000 Register R1 is the RAM address >3000 Register R2 is size to read or write >02FF Edited January 23, 2017 by RXB Quote Link to comment Share on other sites More sharing options...
Opry99er Posted February 19, 2017 Share Posted February 19, 2017 (edited) This was an excellent thread to read and follow... Truly cool to see the development process, and a great piece of utility kit came to be. Bookmarking this one. Edited February 19, 2017 by Opry99er Quote Link to comment Share on other sites More sharing options...
RXB Posted February 20, 2017 Share Posted February 20, 2017 Well been working on XB ROM's Source and this is what I have so far. I would any help you can provide me on comments on what does what in this source I am working on. XBROM SOURCE.zip 2 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 22, 2017 Author Share Posted August 22, 2017 So I'm back at it with another project, and I've run into a snag: I need to send an entire array from XB to a small assembly program to be put out to the PIO port. The problem is that while I can give the assembly program access to the array via the NUMREF utility, it seems that I can only access one element for each XB call. For example: 1 REM XB SAMPLE 10 CALL INIT 20 CALL LOAD("DSK1.PIOOUT") 30 DIM A(256) 40 CALL LINK("DATOUT",A()) On the assembly side of things, the program PIOOUT will access the A() array using BLWP @NUMREF, with R0 having the array index and R1 the argument number in the CALL LINK statement, which would be 1 like so. DATOUT CLR R0 LI R1,1 BLWP @NUMREF All is well and good with the first pass. However, if I try to access other elements of the array by changing R0 to the appropriate index and doing another NUMREF without returning to XB first and doing another CALL LINK, I get an error (BAD ARGUMENT). It appears that for any single CALL LINK, I can only use NUMREF once, which is not helpful because this will slow down the data transfer to the PIO port significantly. My goal was to cycle through the entire array within the assembly program using only one call from XB and send the data out before returning to XB. Do you guys have any idea if that is possible in the above context? The EA manual is silent on this... Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 22, 2017 Share Posted August 22, 2017 ... Do you guys have any idea if that is possible in the above context? The EA manual is silent on this... In the last two posts of TI MiniMemory programs, I do this without using NUMREF, NUMASG, etc. You surely can do it the way you are attempting it. If that is the way you must do it, I can probably dig up how I did it before hitting upon the method in the above reference. I should be able to find you a better reference than the E/A manual for using arrays with NUMREF, etc. ...lee Quote Link to comment Share on other sites More sharing options...
apersson850 Posted August 22, 2017 Share Posted August 22, 2017 (edited) First, I wouldn't write this code using the GPLWS, if you have big problems saving values and restoring them again. Define your own workspace and use that. Go back to GPLWS just before returning to BASIC. I know this will run slower on machines that have the standard memory expansion, but it doesn't matter in this case, as the assembly code is small and the BASIC code running around it is slower anyway. Second, for the array passing, I'd do it so that I would have a specific call to the assembly program where it returns an address to a memory area where the control array should be stored. CALL LINK("PIOMEM",ADDR) will come back with the start address of the array (which is a byte array). Then you do FOR I=0 TO N CALL LOAD(ADDR+I,VALUE(I)) NEXT I Now you've populated the byte array with values from the array VALUE. After that, you call an assembly routine which will output this array to the port. If the number of values change, you'll have to inform about the length of the byte array too. Perhaps you also want to include some kind of time stamp for how long you want each value to remain on the port. I've done almost exactly the same thing once, so this is nothing I dreamed up now. You can have an exercise in Swedish through these two links: Number 1 Number 2 There are two articles I wrote in 1987 about something similar. I implemented a traffic crossing, with traffic lights, controlled by BASIC and Forth, but the Forth code isn't in the magazine, but was published through the Forth special interest group within Programbiten. But there are two routines, one which sets the outputs in the port and one that reads the two auxiliary inputs. Look for "Styr and ställ" (Control and set) in the magazines. Edited August 22, 2017 by apersson850 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 22, 2017 Share Posted August 22, 2017 (edited) So I'm back at it with another project, and I've run into a snag: I need to send an entire array from XB to a small assembly program to be put out to the PIO port. The problem is that while I can give the assembly program access to the array via the NUMREF utility, it seems that I can only access one element for each XB call. For example: 1 REM XB SAMPLE 10 CALL INIT 20 CALL LOAD("DSK1.PIOOUT") 30 DIM A(256) 40 CALL LINK("DATOUT",A()) On the assembly side of things, the program PIOOUT will access the A() array using BLWP @NUMREF, with R0 having the array index and R1 the argument number in the CALL LINK statement, which would be 1 like so. DATOUT CLR R0 LI R1,1 BLWP @NUMREF All is well and good with the first pass. However, if I try to access other elements of the array by changing R0 to the appropriate index and doing another NUMREF without returning to XB first and doing another CALL LINK, I get an error (BAD ARGUMENT). It appears that for any single CALL LINK, I can only use NUMREF once, which is not helpful because this will slow down the data transfer to the PIO port significantly. My goal was to cycle through the entire array within the assembly program using only one call from XB and send the data out before returning to XB. Do you guys have any idea if that is possible in the above context? The EA manual is silent on this... The problem with your code is clearing R0. That tells NUMREF you are interested in getting the parameter number in R1 as a number, not an array. Because parameter #1, A(), is an array, R0 must not be 0. The first element of the array is indicated by 1. And—the E/A manual is not really silent on the matter. The NUMREF discussion refers you back to NUMASG, which is handled the same way—just used for assigning a value rather than reading a value. [Edit: This is not correct! If arrays are zero-based (the default), R0 = 0 should reference the first element. Sorry about the misinformation.] ...lee Edited August 22, 2017 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 22, 2017 Author Share Posted August 22, 2017 In the last two posts of TI MiniMemory programs, I do this without using NUMREF, NUMASG, etc. You surely can do it the way you are attempting it. If that is the way you must do it, I can probably dig up how I did it before hitting upon the method in the above reference. I should be able to find you a better reference than the E/A manual for using arrays with NUMREF, etc. ...lee I'm not too clear on how you did this Lee. I will have to study the code a bit more carefully... Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 22, 2017 Author Share Posted August 22, 2017 Second, for the array passing, I'd do it so that I would have a specific call to the assembly program where it returns an address to a memory area where the control array should be stored. CALL LINK("PIOMEM",ADDR) will come back with the start address of the array (which is a byte array). Then you do FOR I=0 TO N CALL LOAD(ADDR+I,VALUE(I)) NEXT I Now you've populated the byte array with values from the array VALUE. After that, you call an assembly routine which will output this array to the port. If the number of values change, you'll have to inform about the length of the byte array too. Perhaps you also want to include some kind of time stamp for how long you want each value to remain on the port. Ah OK I get it. This should work quite well. I'll give it a try tonight. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted August 22, 2017 Author Share Posted August 22, 2017 The problem with your code is clearing R0. That tells NUMREF you are interested in getting the parameter number in R1 as a number, not an array. Because parameter #1, A(), is an array, R0 must not be 0. The first element of the array is indicated by 1. And—the E/A manual is not really silent on the matter. The NUMREF discussion refers you back to NUMASG, which is handled the same way—just used for assigning a value rather than reading a value. ...lee So you're saying that R0 of 1 refers to the first element of the array even if the index starts at 0 and not at 1? If that's the case, then it's a really simple adjustment... Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 22, 2017 Share Posted August 22, 2017 (edited) So you're saying that R0 of 1 refers to the first element of the array even if the index starts at 0 and not at 1? If that's the case, then it's a really simple adjustment... Yes. [Edit: I might be wrong on this. It was always my impression that R0 had to be non-zero for an array, but perhaps not. I will check.] [Edit2: I was wrong! If the arrays are zero-based (the default) R0 = 0 will retrieve the first element.] ...lee Edited August 22, 2017 by Lee Stewart 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.