Jump to content
IGNORED

Assembly routines in XB


Vorticon

Recommended Posts

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

Link to comment
Share on other sites

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 :D

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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

  • Like 4
Link to comment
Share on other sites

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
  • Like 1
Link to comment
Share on other sites

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 by RXB
Link to comment
Share on other sites

  • 4 weeks later...
  • 6 months later...

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

Link to comment
Share on other sites

...

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
Link to comment
Share on other sites

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 by apersson850
Link to comment
Share on other sites

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 by Lee Stewart
Link to comment
Share on other sites

 

 

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

Link to comment
Share on other sites

 

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.

Link to comment
Share on other sites

 

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

Link to comment
Share on other sites

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 by Lee Stewart
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...