+Vorticon Posted January 16, 2017 Share Posted January 16, 2017 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! 2 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted January 16, 2017 Share Posted January 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 Ah! That may very well be the issue since I did use the RC options. I'll try RO and see how that goes. Thanks! Quote Link to comment Share on other sites More sharing options...
Tursi Posted January 16, 2017 Share Posted January 16, 2017 Might be a good idea to turn the card off before returning, too, just in case XB wants to use a DSR? Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted January 16, 2017 Share Posted January 16, 2017 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' Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 Might be a good idea to turn the card off before returning, too, just in case XB wants to use a DSR? Good idea I will implement that as well. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2017 Share Posted January 16, 2017 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 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2017 Share Posted January 16, 2017 What assembler are you using? Also, post the code that doesn't work so you can get more eyes on it. ...lee Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 I'm using the standard TI assembler. Here's the source. I'm running out of hair to pull ** 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 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted January 16, 2017 Share Posted January 16, 2017 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? Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 16, 2017 Share Posted January 16, 2017 You are only saving R11 in R4 in PIOINI, but you are always restoring it from R4 before you return, is that right? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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... Quote Link to comment Share on other sites More sharing options...
Stuart Posted January 16, 2017 Share Posted January 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 16, 2017 Share Posted January 16, 2017 Try replacing the REFs with: NUMASG EQU >2008NUMREF EQU >200C Quote Link to comment Share on other sites More sharing options...
Stuart Posted January 16, 2017 Share Posted January 16, 2017 You are only saving R11 in R4 in PIOINI, but you are always restoring it from R4 before you return, is that right? As far as I can see, it's not necessary to save the registers at all, as there is no code that overwrites them. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2017 Share Posted January 16, 2017 ... 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 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2017 Share Posted January 16, 2017 Try replacing the REFs with: NUMASG EQU >2008 NUMREF EQU >200C And— XMLLNK EQU >2018 ...lee Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted January 16, 2017 Share Posted January 16, 2017 (edited) 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 January 16, 2017 by InsaneMultitasker Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted January 16, 2017 Author Share Posted January 16, 2017 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? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2017 Share Posted January 17, 2017 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 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker 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. 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.