Jump to content
IGNORED

Assembly routines in XB


Vorticon

Recommended Posts

Hi. I'm working on a set of assembly routines for low-level access to the PIO port from XB for the purposes of rapid prototyping, and I'm running into an issue.

 

Below is a test code I want to run from XB to initialize the PIO port. It assembles without errors and the tagged object code file is named PIOLIB on DSK1.

       DEF    PIOINI

PIO    EQU    >5000

PIOINI MOV    R11,R4   SAVE THE RETURN REGISTERS
       MOV    R13,R5
       MOV    R14,R6
       MOV    R15,R7
       LI     R12,>1300  DSR ADDRESS OF RS232 CARD
       SBO    0          ACTIVATE CARD
       SBO    7          TURN CARD LED ON
       CLR    @PIO       CLEAR PIO DATA LINES
       MOV    R4,R11     RESTORE THE RETURN REGISTERS
       MOV    R5,R13
       MOV    R6,R14
       MOV    R7,R15
       RT                RETURN TO XB
       END

In XB, when I run the code below, I get the error "UNDEFINED CHARACTER IN 30".

10 CALL CLEAR
20 CALL INIT
30 CALL LOAD("DSK1.PIOLIB")
40 CALL LINK("PIOINI")
50 END

For the life of me I can't figure out what that means since there are obviously no errors in the syntax of line 30.

 

Any clarification as to what I'm doing wrong would be immensely appreciated!

  • Like 2
Link to comment
Share on other sites

Hi. I'm working on a set of assembly routines for low-level access to the PIO port from XB for the purposes of rapid prototyping, and I'm running into an issue.

 

In XB, when I run the code below, I get the error "UNDEFINED CHARACTER IN 30".

10 CALL CLEAR
20 CALL INIT
30 CALL LOAD("DSK1.PIOLIB")
40 CALL LINK("PIOINI")
50 END

For the life of me I can't figure out what that means since there are obviously no errors in the syntax of line 30.

I suspect your object code was assembled as compressed; Extended BASIC cannot load compressed object files. Use only the R and O options, not C, during assembly.

Link to comment
Share on other sites

Hi. I'm working on a set of assembly routines for low-level access to the PIO port from XB for the purposes of rapid prototyping, and I'm running into an issue.

 

Just out of curiosity, is this something you might consider releasing when it's done? This sounds like something even BASIC coders could have some fun with and from a hardware perspective, this could be the entry-level point that attracts a lot of attention.

 

I can envision all sorts of future projects, and if people started uploading their schematics and parts lists, we could all partake of the fun with some computer controlled 'homebrew'

Link to comment
Share on other sites

 

Just out of curiosity, is this something you might consider releasing when it's done? This sounds like something even BASIC coders could have some fun with and from a hardware perspective, this could be the entry-level point that attracts a lot of attention.

 

I can envision all sorts of future projects, and if people started uploading their schematics and parts lists, we could all partake of the fun with some computer controlled 'homebrew'

 

Yup, there is a blog entry brewing along with practical examples :)

  • Like 1
Link to comment
Share on other sites

So the code snippet above worked just fine when I used the RO options in the assembler.

However, the same error reared its head again when I added more than one entry points to the program in the DEF statement. Looking at one of my reference it appears that the UNDEFINED CHARACTER error means that there is an invalid tag. Not sure what that means...

The idea is to CALL LOAD the PIOLIB program, and then CALL LINK to different subroutines within it rather than LOAD multiple object codes. I have written routines to input/output data from/to the PIO port as well read and set the status of the HSK and SPR lines, and each one has an entry point in the program like so:

 

DEF PIOINI,DATOUT,DATIN,HSKOUT,HSKIN,SPROUT,SPRIN

 

Is this valid or am I missing something?

Link to comment
Share on other sites

By “the same error reared its head again”, do you mean that the CALL LOAD() statement failed again—or, was it one of the CALL LINK() statements this time?

 

Also, are you turning the card on and off at the beginning and end, respectively, of each subroutine call?

 

Also, because you need to turn the card on at entry and off at exit, perhaps you could write PIOLIB with a single entry point that uses opcodes to decide which subroutine to execute. Of course, that is not as clear in your XB program as using multiple, named entry points, but I digress...

 

...lee

Link to comment
Share on other sites

By “the same error reared its head again”, do you mean that the CALL LOAD() statement failed again—or, was it one of the CALL LINK() statements this time?

 

Also, are you turning the card on and off at the beginning and end, respectively, of each subroutine call?

 

Also, because you need to turn the card on at entry and off at exit, perhaps you could write PIOLIB with a single entry point that uses opcodes to decide which subroutine to execute. Of course, that is not as clear in your XB program as using multiple, named entry points, but I digress...

 

...lee

 

It's the same error with the CALL LOAD as before. An no, I'm turning the card on only when PIOINI is called and I will add a separate routine called PIOOFF to turn the card off.

I thought about using codes as well for the various routines, but as you stated it's not as clear to the end-user.

Link to comment
Share on other sites

I'm using the standard TI assembler. Here's the source. I'm running out of hair to pull :D

** XB PIO LOW LEVEL CONTROL UTILITIES **
**          JANUARY 2017              **
**       BY WALID MAALOULI            **
 
       DEF  PIOINI,DATOUT,DATIN,HSKIN,HSKOUT
       DEF  SPRIN,SPROUT,PIOOFF
       REF  XMLLNK,NUMREF,NUMASG
PIO    EQU  >5000             PIO PORT DATA ADDRESS
FAC    EQU  >834A             FLOATING POINT ACCUMULATOR ADDRESS
 
** INITIALIZE RS232 CARD PIO PORT **
PIOINI MOV  R11,R4            SAVE RETURN REGISTERS
       MOV  R13,R5
       MOV  R14,R6
       MOV  R15,R7
       LI   R12,>1300         SELECT DSR ADDRESS OF RS3232 CARD
       SBO  0                 ACTIVATE CARD
       SBO  7                 TURN CARD LED ON
       CLR  @PIO              CLEAR DATA LINES
       B    @RETURN
 
** SEND DATA OUT TO DATA LINES
DATOUT CLR  R0
       LI   R1,1              SELECT ARGUMENT 1 FROM XB CALL
       BLWP @NUMREF           FETCH ARGUMENT AND PLACE IN FAC
       BLWP @XMLLNK
       DATA >1200             CONVERT ARGUMENT TO INTEGER
       SWPB @FAC              MOVE ARGUMENT TO HIGH BYTE
       SBZ  1                 SET PIO PORT TO OUTPUT
       MOVB @FAC,@PIO         SEND BYTE TO PIO PORT
       B    @RETURN
 
** RECEIVE DATA FROM DATA LINES
DATIN  SBO  1                 SET PIO PORT TO INPUT
       CLR  @FAC
       MOVB @PIO,@FAC         GET BYTE FROM PIO PORT INTO FAC
       CLR  R0
       LI   R1,1              SELECT ARGUMENT 1 FROM XB CALL
       SWPB @FAC              MOVE RECEIVED BYTE TO LOW BYTE OF FAC
       BLWP @XMLLNK
       DATA >2300             CONVERT BYTE TO FLOATING FLOATING POINT NUMBER
       BLWP @NUMASG           ASSIGN NUMBER TO SELECTED ARGUMENT
       B    @RETURN
 
** SEND BIT TO HANDSHAKEOUT LINE
HSKOUT CLR  R0
       LI   R1,1              SELECT ARGUMENT 1 FROM XB CALL
       BLWP @NUMREF           GET VALUE FROM ARGUMENT INTO FAC
       BLWP @XMLLNK
       DATA >1200             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  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 >2300             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 CLR  R0
       LI   R1,1              SELECT ARGUMENT 1 FROM XB CALL
       BLWP @NUMREF           PLACE VALUE OF ARGUMENT 1 INTO FAC
       BLWP @XMLLNK
       DATA >1200             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  TB   3                 READ THE LOGIC STATE OF THE SPRIN LINE
       JNE  SPRIN0
       LI   R2,1
       JMP  SNDVAL
SPRIN0 CLR  R2
       JMP  SNDVAL
 
** TURN OFF THE RS232 CARD
PIOOFF SBZ  7                 TURN CARD LED OFF
       SBZ  0                 INACTIVATE RS232 CARD
 
RETURN MOV  R4,R11            RESTORE RETURN REGISTERS
       MOV  R5,R13
       MOV  R6,R14
       MOV  R7,R15
       RT
 
       END

Link to comment
Share on other sites

You may have trouble keeping the card on from inside basic. As I believe trying to "CALL" a function that doesn't exist may cause the 4A to cycle through the DSR's on cards looking for it.

 

Or is that table pre-loaded by BASIC?

 

No that does not seem to be an issue. The card does stay on.

Link to comment
Share on other sites

You are only saving R11 in R4 in PIOINI, but you are always restoring it from R4 before you return, is that right?

 

Ah yes that would be problematic once any routine other than PIOINI is called. Missed that :) Come to think of it though, I'm not even sure I really need to save the return registers at all since they are not being overwritten by any of the routines...

Unfortunately, that's not really the issue here as we are not getting past the CALL LOAD call at this point and I can't figure out why... The error is supposed to indicate an invalid tag field which I assume is in the DEF list, but I can't see anything wrong here. It worked with the simple test code at the top of the thread. Could it be that only one entry point per object file is allowed?

 

Another thought is that the problem could be with the REF statement. Per the E/A manual, the XMLLNK utility resides in ROM but the NUMASG and NUMREF are part of a utility file on one of the E/A disks, at least for TI BASIC. The TI Extended Basic Assembly Language Code Programmer's Guide is silent on this other than stating that they reside in the expansion RAM...

Link to comment
Share on other sites

Vorticon, on 16 Jan 2017 - 4:00 PM, said:

So the code snippet above worked just fine when I used the RO options in the assembler.

However, the same error reared its head again when I added more than one entry points to the program in the DEF statement. Looking at one of my reference it appears that the UNDEFINED CHARACTER error means that there is an invalid tag. Not sure what that means...

The idea is to CALL LOAD the PIOLIB program, and then CALL LINK to different subroutines within it rather than LOAD multiple object codes. I have written routines to input/output data from/to the PIO port as well read and set the status of the HSK and SPR lines, and each one has an entry point in the program like so:

 

DEF PIOINI,DATOUT,DATIN,HSKOUT,HSKIN,SPROUT,SPRIN

 

Is this valid or am I missing something?

 

The TI Extended BASIC loader doesn't support the REF external references. See E/A manual section 24.4.4. What you need to do is set up EQUates for the external references - the addresses you need are in section 24.4.8.

Link to comment
Share on other sites

...

Another thought is that the problem could be with the REF statement. Per the E/A manual, the XMLLNK utility resides in ROM but the NUMASG and NUMREF are part of a utility file on one of the E/A disks, at least for TI BASIC. The TI Extended Basic Assembly Language Code Programmer's Guide is silent on this other than stating that they reside in the expansion RAM...

 

Actually, that document says the standard ALC support package is transferred from GROM to RAM. The requirement of EQUating the subroutine entry points is implied in the macros at the end of the manual. Also, the E/A Manual states this explicitly.

 

...lee

Link to comment
Share on other sites

When you LINK into assembly from XB, your workspace will be set to GPLWS (0x83e0). While certainly not necessary, a good practice is to reserve and use your own workspace (WS BSS >20, for example). If speed is of great importance, and you decide to use GPLWS, at minimum you should save R11, R13-R15 and restore them before returning. Watch out for routines that also use GPLWS, such as most DSRLNK routines and the keyboard scan routine, as they often trample on multiple registers.

 

To return to XB, restore your workspace to GPLWS, if you had changed it. You might find it necessary to clear the status byte @ 0x837c. Restore any saved registers then return.

Edited by InsaneMultitasker
Link to comment
Share on other sites

Thanks guys. Equating the external references worked.

Now I have all sorts of other issues as all my routines except PIOINI are not working properly and the output ones are trashing the computer... I suspect that it's an issue with the workspace registers. I'll have to take a closer look at the code and follow Tim's advice.

One question: when I use the XMLLNK >1200 routine to convert a float to an integer in the FAC, and if the number is < 256, it should reside at @FAC+1 since the operation is a word one, correct?

Link to comment
Share on other sites

Thanks guys. Equating the external references worked.

Now I have all sorts of other issues as all my routines except PIOINI are not working properly and the output ones are trashing the computer... I suspect that it's an issue with the workspace registers. I'll have to take a closer look at the code and follow Tim's advice.

One question: when I use the XMLLNK >1200 routine to convert a float to an integer in the FAC, and if the number is < 256, it should reside at @FAC+1 since the operation is a word one, correct?

 

Correct—as long as the value is also not negative. [EDIT: CFI is different for XB. It is >12B8—see later posts.]

 

...lee

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