apersson850 Posted February 10 Author Share Posted February 10 (edited) The p-code card is still enabled when your assembly routines are called. You have two cards on simultaneously. That's never a good idea, but you would have survived if it was only during your assembly program's execution. But you return to Pascal in between, and then you need the PME again. You can for sure use the RS232 card directly from assembly under the p-code card, as long as you disable the p-code card while you do it, and re-enable it before returning to Pascal. CRUPCODE .EQU 1F00H CRURS232 .EQU 1300H .PROC RS232FIX MOV R12,R7 LI R12,CRUPCODE SBZ 0 LI R12,CRURS232 SBO 0 SBO 7 ; Play with the RS 232 SBZ 7 SBZ 0 LI R12,CRUPCODE SBO 0 MOV R7,R12 B *R11 Note the need to save R12 and restore before returning. When the PME is running, R8-R15 have values essential to the system. You can freely use R0-R7 in PASCALWS (8380H). If you need more you need to change to a different workspace. Main workspace for PME(>8380) -------------- R0-R7 Temporary use R8 is the p-code instruction pointer. R9 is used as a frame pointer for activation records allocated on the stack. R10 is the stack pointer. R11 is the return link. R12 contains the address of the PME instruction fetch routine. R13 contains the Read Data address of the currently executing code segment. Could be PGRMRD, VDPRD or 0 (for CPU RAM). R14 Global data frame pointer for current segment. R15 is a flag used to remember where the p-code currently interpreted is located. =0: CPU RAM <0: VDP RAM >0: GROM After the interpretation of each p-code, the PME will do a B *R12, so if that's not pointing to 8300H, you're toast. Edited February 10 by apersson850 2 2 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408018 Share on other sites More sharing options...
+Vorticon Posted February 10 Share Posted February 10 Thank you! Not something I needed to worry about previously. Add it to the quirks and features of the pcode system Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408083 Share on other sites More sharing options...
apersson850 Posted February 10 Author Share Posted February 10 The CRU part is not anything you need to be concerned about as long as you don't enable any other card with memory at 4000H-5FFFH. The register part you need to be concerned about as long as you use PASCALWS. 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408122 Share on other sites More sharing options...
+Vorticon Posted February 11 Share Posted February 11 Ok so I reworked the tests and still same lock up. ; routines for rs232 card access .proc initrs232,1 ; setup the rs232 cru address .def cruadr,pmeret mov *r10+,r1 ; get the desired rs232 card number ci r1,1 jne rs2322 li r1,1300h jmp savecru rs2322 li r1,1500h savecru mov r1,@cruadr ; save base cru address b *r11 cruadr .word pmeret .word .proc testbit ; test cru bit access .ref cruadr,pmeret mov r12,@pmeret li r12,1f00h sbz 0 mov @cruadr,r12 sbo 0 sbo 7 sbz 7 sbz 0 li r12,1f00h sbo 0 mov @pmeret,r12 b *r11 .end program rs232test; procedure initrs232(cardnum : integer); external; procedure testbit; external; begin page(output); initrs232(1); testbit; end. (* rs232test *) 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408308 Share on other sites More sharing options...
apersson850 Posted February 11 Author Share Posted February 11 I couldn't see any reason for why that wouldn't work, so I tried it in Classic 99. Works as it should. No lockup. I did have one first, but that was just a typo in my assembly, not following your template completely. Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408420 Share on other sites More sharing options...
+Vorticon Posted February 11 Share Posted February 11 Oops. Looks like I had forgotten to assemble the updated version and was linking in the old version. Sorry. Having to turn off the RS232 before returning to the pcode system definitely complicates the high-level control of the card through the use of small assembly routines like I've done for XB for example. I do have a side question: Can you BL from one .proc to another (of course saving R11 prior to the call)? I tried doing that and I got weird assembler errors where it would not recognize the .end directive (?). Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408454 Share on other sites More sharing options...
apersson850 Posted February 11 Author Share Posted February 11 (edited) As I responded in the assembly thread, depending on what you intend to do with the RS232 card, you may not have to turn it on. If you don't, then you don't have to turn the p-code card off either. Here's a not very useful example of what you should be able to do. .PROC DUMMY1 .DEF SUB1 MOV R11,R7 LI R1,12 BL @SUB1 ; Call local subroutine CLR R1 B *R7 ; Return to Pascal SUB1 MOV R1,R2 B *R11 .PROC DUMMY2 .REF SUB1 MOV R11,R7 LI R1,24 BL @SUB1 ; Call external subroutine CLR R1 B *R7 ; Return to Pascal .END Edited February 11 by apersson850 2 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408545 Share on other sites More sharing options...
+Vorticon Posted February 11 Share Posted February 11 1 hour ago, apersson850 said: As I responded in the assembly thread, depending on what you intend to do with the RS232 card, you may not have to turn it on. If you don't, then you don't have to turn the p-code card off either. Here's a not very useful example of what you should be able to do. .PROC DUMMY1 .DEF SUB1 MOV R11,R7 LI R1,12 BL @SUB1 ; Call local subroutine CLR R1 B *R7 ; Return to Pascal SUB1 MOV R1,R2 B *R11 .PROC DUMMY2 .REF SUB1 MOV R11,R7 LI R1,24 BL @SUB1 ; Call external subroutine CLR R1 B *R7 ; Return to Pascal .END Ah I see what I did wrong: I did not .DEF/.REF the .PROC I was calling with a BL. Thanks for the clarification. Apologies for all the questions. There are enough differences between regular assembly and assembly under the pcode system to throw me off old habits. I am however starting to gain a much better understanding of the pcode environment thanks to you. While the pcode assembler and linker manuals have good info, they are not nearly enough for anything more than the most basic assembly routines. 2 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408613 Share on other sites More sharing options...
apersson850 Posted February 11 Author Share Posted February 11 I have spent a lot of time figuring out the things the manuals don't tell you. My attempts to implement turtlegraphics and pre-emptive multitasking has gained me an insight into the particular p-system in the 99/4A that's probably unique among people outside of the group that developed it. It feels good to be able to share with somebody who's interested. 2 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408682 Share on other sites More sharing options...
Tursi Posted February 11 Share Posted February 11 7 hours ago, apersson850 said: I couldn't see any reason for why that wouldn't work, so I tried it in Classic 99. Works as it should. No lockup. Do be aware that Classic99 does not emulate DSR conflict. I think the debug log should throw a warning if it happens, though... Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408699 Share on other sites More sharing options...
apersson850 Posted February 11 Author Share Posted February 11 Well, that I caught by just reading the code. I would have tried the real thing if we hadn't figured it out. Out of curiosity, what does Classic 99 do if two cards are enabled at the same time? Picks a favorite one? Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408713 Share on other sites More sharing options...
Tursi Posted February 12 Share Posted February 12 3 hours ago, apersson850 said: Well, that I caught by just reading the code. I would have tried the real thing if we hadn't figured it out. Out of curiosity, what does Classic 99 do if two cards are enabled at the same time? Picks a favorite one? Most recent one, IIRC. Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5408833 Share on other sites More sharing options...
apersson850 Posted February 14 Author Share Posted February 14 On 12/9/2018 at 11:29 PM, apersson850 said: No, there's no compiler for the UCSD p-system that produces assembly code. The SYSTEM.COMPILER in the system produces p-code. That's the whole point with the p-system, as it makes it easier to port to different computers and it makes the code more compact. The tradeoff is execution speed. There was a native code generator for the p-system, but I've never seen any for the TI. The native code converter takes simple p-codes and convert them to assembly code, inline with the p-codes. I read some parts from the USUS newsletters that are available form whtech. I found a passage where a possible native code generator for the 6502 processor was discussed. But it was found that the memory requirement expansion factor, when converting p-code to 6502 instructions, was about 1 to 6. That was found unrealistic at the time, so they never did any native code generator for the 6502. One issue with creating one for the 9900 is that first you have to do quite a bit of support routines just to handle the code files, before you can get at actually generate any equivalent native code from the p-code. And then you have to deal with the code files again to save your work properly, as parts of the code file are likely to grow, thus displacing other parts of the file. To see if it will run probably on the TI 99/4A by simulating the whole process is probably the best start. You could simulate the native code generation by using some p_machine statements in a program. 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5410482 Share on other sites More sharing options...
+Vorticon Posted February 14 Share Posted February 14 I was browsing through the SAGE p-system Program Development manual from 1983, and although it does not specify a particular version of the p-system, it does describe a Turtlegraphics unit and a debugger. There is also SYSTEM.MENU file which can be used with applications. Of interest there is also a description of a native code generator. None of these features were included with the TI version, although we do have now a Turtlegraphics unit thanks to @apersson850. I wonder why the debugger never made it into the package... 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5410486 Share on other sites More sharing options...
apersson850 Posted February 14 Author Share Posted February 14 Perhaps it took too much memory to run that together with the applications. Guessing, I don't know. 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5410527 Share on other sites More sharing options...
apersson850 Posted February 15 Author Share Posted February 15 I read an article in one issue of the USUS newsletter at whtech. The article was about the 99/4A p-system and was written by a user. He did not claim to be an expert, not at all, but it's still interesting to see how little they knew in 1985 within USUS, compared to four of us in the Swedish group Programbiten. Since we were three p-system users just a short walk away from each other and one more 10 km away, we may have been the most dense concentration anywhere in 1983. 3 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5411284 Share on other sites More sharing options...
+Vorticon Posted February 15 Share Posted February 15 36 minutes ago, apersson850 said: I read an article in one issue of the USUS newsletter at whtech. The article was about the 99/4A p-system and was written by a user. He did not claim to be an expert, not at all, but it's still interesting to see how little they knew in 1985 within USUS, compared to four of us in the Swedish group Programbiten. Since we were three p-system users just a short walk away from each other and one more 10 km away, we may have been the most dense concentration anywhere in 1983. Well, 41 years later and the situation does not seem to have changed much! 😁 Back then, as now, the hardware requirements to run UCSD Pascal were steep considering that most folks had bought their TI's heavily discounted towards the end of its production, while expansion hardware like the PEB, floppy drives, 32K RAM, Disk controller and RS232, not to mention a printer, remained very expensive to acquire. Your particular situation definitely was uncommon to say the least... Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5411308 Share on other sites More sharing options...
+TheBF Posted February 15 Share Posted February 15 3 hours ago, Vorticon said: Well, 41 years later and the situation does not seem to have changed much! 😁 Back then, as now, the hardware requirements to run UCSD Pascal were steep considering that most folks had bought their TI's heavily discounted towards the end of its production, while expansion hardware like the PEB, floppy drives, 32K RAM, Disk controller and RS232, not to mention a printer, remained very expensive to acquire. Your particular situation definitely was uncommon to say the least... Speaking of RS232, were you able to make any progress on that? Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5411470 Share on other sites More sharing options...
+Vorticon Posted February 16 Share Posted February 16 3 hours ago, TheBF said: Speaking of RS232, were you able to make any progress on that? I did get the CRU bits access working which is primarily what I needed. I have a project in mind once I have some free time next week. 2 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5411554 Share on other sites More sharing options...
+Vorticon Posted February 23 Share Posted February 23 With assembly functions without a passed parameter, R10 is already set up to receive the function result, correct? The manual mentions doing a DECT R10 first... Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5416717 Share on other sites More sharing options...
apersson850 Posted February 24 Author Share Posted February 24 (edited) Yes, they do, but I think that's because they've used a manual written for a different CPU and just edited that to fit the TMS 9900, creating several firm and soft errors along the way. By firm error I mean things that don't work, by soft things that do work but are done better in other ways using the memory-to-memory architecture of the TMS 9900. Here's the example from the Linker manual, page 24. I have removed the original comments from the assembly program and instead inserted my own, pointing out what's not too clever and what's not working at all. Glance in the Linker manual page 24 in parallel to get the full picture. My feeling is that the outline of this program comes from a description for a CPU which implements stack handling in the CPU, but doesn't have the same memory-to-memory capabilities as the TMS 9900. program example; (* Pascal host program *) const size = 80; var i,j,k: integer; lis1: array[0..9] of char; (* prt and lst2 get allocated here in memory when the program is running, but are declared in the assembly program using .PRIVATE *) procedure do_nothing; external; function null_func(xxyxx,z: integer): integer; external; begin (* main Pascal program *) do_nothing; j := null_func(k,size); end. (* example *) SP .EQU 10 ; Not in original example but adds readability .PROC DONOTHING ; No parameters at all .CONST SIZE ; Easy way to refernce value in host .PUBLIC I,LST1 ; Same for global variables .DEF TEMP1 ; Since .PROC, .FUNC and .END are assembly code segment delimiters, you can only access TEMP1 from between .PROC DONOTHING : and .FUNC NULLFUNC, unless you DEFine it for external access. DEF is implicit in .PROC, so BL @DONOTHING would be legal ; from NULLFUNC. B *R11 TEMP1 .WORD ; Still belongs to DONOTHING .FUNC NULLFUNC,2 ; Two parameters, but since it's an integer function, the runtime system will also allocate space for the return value on the ; stack, prior to pushing the parameters. .PRIVATE PRT,LST:9 ; ERROR in the example - should be .PRIVATE PRT,LST2:9 .REF TEMP1 ; So we can reach TEMP1 from this side of the .FUNC NULLFUNC,2 directive MOV *SP+,TEMP1 ; ERROR - Should be MOV *SP+,@TEMP1 MOV *SP+,PRT ; ERROR - Should be MOV *SP+,@PRT MOV *SP+,JUNK ; ERROR - Should be MOV *SP+,@JUNK ; But the whole thing is unnecessary. Since the idea is to pop a value that's not used anyway, we can just as well do a INCT SP. ; Which in turn is unnecessary too, since we don't intend to do anything with the stack prior to returning the result, so the ; best thing here is to simply don't do anyting at all, just leave SP pointing to where to return the result. MOV LST,LST ; ERROR - Should be MOV @LST,@LST Meaningless, but illustrates the concept of NULLFUNC DECT SP ; Required only if we were stupid enough to increment the stack pointer in vain above MOV LST+4,*SP ; ERROR - Should be MOV @LST+4,*SP B *R11 JUNK .WORD ; Just a waste of space if we "pop" by INCT SP, or even better, don't "pop" at all. .END There are six lines that are in ERROR. One of those and one more could better be omitted all together. Below is the same thing again, with all syntax errors and excessive stuff removed. program example; (* Pascal host program *) const size = 80; var i,j,k: integer; lis1: array[0..9] of char; (* prt and lst2 get allocated here in memory when the program is running, but are declared in the assembly program using .PRIVATE *) procedure do_nothing; external; function null_func(xxyxx,z: integer): integer; external; begin (* main Pascal program *) do_nothing; j := null_func(k,size); end. (* example *) SP .EQU 10 ; Not in original example but adds readability .PROC DONOTHING ; No parameters at all .CONST SIZE ; Easy way to refernce value in host .PUBLIC I,LST1 ; Same for global variables .DEF TEMP1 ; Since .PROC, .FUNC and .END are assembly code segment delimiters, you can only access TEMP1 from between .PROC DONOTHING : and .FUNC NULLFUNC, unless you DEFine it for external access. DEF is implicit in .PROC, so BL @DONOTHING would be legal ; from NULLFUNC. B *R11 TEMP1 .WORD ; Still belongs to DONOTHING .FUNC NULLFUNC,2 ; Two parameters, but since it's an integer function, the runtime system will also allocate space for the return value on the ; stack, prior to pushing the parameters. .PRIVATE PRT,LST2:9 .REF TEMP1 ; So we can reach TEMP1 from this side of the .FUNC NULLFUNC,2 directive MOV *SP+,@TEMP1 ; Pop second parameter MOV *SP+,@PRT ; Pop first parameter. Leave stack pointer pointing at word to return. MOV @LST,@LST MOV @LST+4,*SP ; Just store the result word where the SP is pointing B *R11 .END The second example is more lean. But if we assume we have a CPU that can't access the value at top of stack directly, but have to POP register, modify the register and then PUSH register, then it makes sense completely. You wouldn't be able to PUSH result to the correct place without first POP junk with that limitation in stack access. Now the TMS 9900 doesn't have any predefined stack system, but the indirect register access allows us to make one. With a very simple 8-bit architecture you may have to do something like this to add the two 16-bit numbers on top of the stack. Assuming an 8-bit architecture with A being the accumulator, BC, DE and HL being 16-bit register pairs. POP and PUSH to/from register pairs is 16 bit. No direct access to top of stack. You have to PUSH to store a value there and POP to read it. POP BC POP DE POP HL MOV B,A ADD D MOV A,B MOV C,A ADD E JNC NOCAR INC B NOCAR MOV A,C PUSH BC With the TMS 9900, the same thing is accomplished by A *SP+,*SP There are frequently more advanced features in 8-bit CPU architectures too, but the principle should be clear. With this design you have to POP before you can PUSH. Edited February 24 by apersson850 4 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5417105 Share on other sites More sharing options...
+Vorticon Posted February 26 Share Posted February 26 I finally bit the bullet and had the PDF professionally printed on 32 pound paper in large format and spirally bound. Much easier on the eyes and more practical. Not cheap but well worth it. Awesome read btw. 5 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5418588 Share on other sites More sharing options...
+Vorticon Posted February 29 Share Posted February 29 Here's a library of assembly routines providing access to the RS232 card at the low level from the pcode environment, both serial and parallel. Spoiler ; Routines for low-level rs232 access pioadr .equ 5000h .proc setrs232,1 ; set up the rs232 card cru base ; 1 = CRU 1300H, 2 = CRU 1500H .def cruadr,pmeret,procret,pcodeon,pcodoff,uartdis .def rs232on,rs232of mov r12,@pmeret ;save the pme pointer mov *r10+,r1 ;get desired RS232 card number ci r1,1 jne rs2322 li r12,1300h li r3,40h ;uart base address displacement jmp savecru rs2322 li r12,1500h li r3,80h ;uart base address displacement savecru mov r12,@cruadr ;save base CRU address mov r3,@uartdis ;save uart base address displacement mov @pmeret,r12 ;restore the pme pointer b *r11 cruadr .word pmeret .word procret .word uartdis .word pcodeon li r12,1f00h ;activate the pcode card sbo 0 mov @pmeret,r12 ;retrieve the pme pointer b *r11 pcodoff mov r12,@pmeret ;save the pme pointer li r12,1f00h ;deactivate the pcode card sbz 0 b *r11 rs232on mov @cruadr,r12 ;load rs232 cru base sbo 0 ;turn card on sbo 7 ;turn card led on b *r11 rs232of mov @cruadr,r12 ;load rs232 cru base sbz 7 ;turn card led off sbz 0 ;turn card off b *r11 .proc bitset,2 ;set/reset specified cru bit .ref cruadr,pmeret mov r12,@pmeret ;save the pme pointer mov @cruadr,r12 ;retrieve the base cru address mov *r10+,r1 ;get the cru bit state request (0 or 1) mov *r10+,r2 ;get the cru bit number sla r2,1 ;multiply by 2 a r2,r12 ;offset the cru base ci r1,1 jne setzero sbo 0 jmp setdone setzero sbz 0 setdone mov @pmeret,r12 ;restore the pme pointer b *r11 .proc sendbyte,1 ;send a byte to the serial port .ref pcodeon,pcodoff,rs232on,rs232of,uartdis,procret mov r11,@procret bl @pcodoff bl @rs232on mov *r10+,r6 ;get byte to send swpb r6 a @uartdis,r12 ;set uart base address sbo 16 ;activate rts line. ready to send notread tb 27 ;test dsr pin. is receiver ready? jne notread notempt tb 22 ;is emission buffer empty? jne notempt ldcr r6,8 ;send byte sbz 16 ;inactivate rts line. not ready to send bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .proc hskout,1 ;set handshakeout line (0 or 1) .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on mov *r10+,r6 ;get requested state of hskout line ci r6,1 jne hskolow sbo 2 ;set hskout line to high jmp hskoret hskolow sbz 2 ;set hskout line to low hskoret bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .proc sprout,1 ;set spareout line (0 or 1) .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on mov *r10+,r6 ;get requested state of sprout line ci r6,1 jne sprolow sbo 3 ;set sprout line to high jmp sproret sprolow sbz 3 ;set sprout line to low sproret bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .proc datout,1 ;send a byte to the pio port .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on mov *r10+,r6 ;get the byte to send swpb r6 sbz 1 ;set port to output movb r6,@pioadr ;send byte bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .func getbyte ;receive a byte from the serial port .ref pcodeon,pcodoff,rs232on,rs232of,uartdis,procret,cruadr mov r11,@procret bl @pcodoff bl @rs232on sbz 5 ;activate cts line. ready to receive a @uartdis,r12 ;uart base cru address chkdsr tb 27 ;test dsr pin. signal is inverted! jne chkdsr ;if line high then not ready chkbuf tb 21 ;test receive buffer jne chkbuf stcr r6,8 ;get byte into r6 sbz 18 ;reset buffer cru bit 21 swpb r6 sbo -27 ;inactivate cts line. cru 5 disp from 1340h mov r6,*r10 ;place byte on return stack bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .func datin ;get byte from pio port .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on sbo 1 ;set port to input clr r6 movb @pioadr,r6 ;get byte from port swpb r6 mov r6,*r10 ;save byte to return stack bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .func hskin ;get status of handshakein line .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on tb 2 ;get logic state of hskin line jne hskilow li r6,1 jmp hskiret hskilow clr r6 hskiret mov r6,*r10 ;save hskin state to return stack bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .func sprin ;get status of sparein line .ref pcodeon,pcodoff,rs232on,rs232of,procret mov r11,@procret bl @pcodoff bl @rs232on tb 3 ;get logic state of sparein line jne sprilow li r6,1 jmp spriret sprilow clr r6 spriret mov r6,*r10 ;save sprin state to return stack bl @rs232of bl @pcodeon mov @procret,r11 b *r11 .end Here's a little program demonstrating the parallel port interfacing functionality: program piotest; var n, i : integer; procedure setrs232(base : integer); external; procedure datout(n : integer); external; procedure hskout(n : integer); external; procedure sprout(n : integer); external; procedure delay; var d : integer; begin for d := 1 to 100 do end; begin setrs232(1); for i := 1 to 20 do begin n := 1; repeat begin hskout(1); delay; hskout(0); datout(n); delay; sprout(1); delay; sprout(0); n := n * 2; end; until n > 256; end end. and here it is in action PIO interface demo.mp4 With this library, you should be able to interface the TI to a variety of real world projects using pcode. I should state that I've done something similar for XB, but with the latter assembly routines access is much slower whereas within the pcode environment I had to actually introduce delays. Next is XMODEM 4 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5420192 Share on other sites More sharing options...
+TheBF Posted February 29 Share Posted February 29 Congratulations. This looks really good. I found an Xmodem program in Forth, of all things, but it might take some effort to port it. It was written for PC based GForth, a far cry from a TI-99. I suspect you will have something going pretty quickly with your new solid RS232 library and that Pcode system. 3 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5420251 Share on other sites More sharing options...
+TheBF Posted February 29 Share Posted February 29 I was reading your Asm code to send a byte and I see something that won't bite you until you try sending to another slow computer that uses RTS/CTS handshaking. The DSR/DTR is typically used to indicate that a "data set" and a "data terminal" are connected. Now you can find devices that use it to throttle data but my understanding is that is not what it is for. The RTS/CTS lines are "supposed" to be for throttling data and preventing overruns. This is what Teraterm does for example. Now when a TI-99 sends bytes to a modern PC it's probably never going to overrun it. But if you were sending to another retro-computer it might matter if that program has proper RTS/CTS handshaking and debugging those problems is a pain. So when you send a byte, you test DSR to make sure everybody is connected. You got that. Then the SENDER sets the RTS line and WAITS for the receiver to reply with the CTS. It's a question and answer type protocol. Sender: I am ready to send. Receiver: OK, you are clear to send So here what I think you need based what I have learned in my little dungeon. .proc sendbyte,1 ;send a byte to the serial port .ref pcodeon,pcodoff,rs232on,rs232of,uartdis,procret mov r11,@procret bl @pcodoff bl @rs232on mov *r10+,r6 ;get byte to send swpb r6 a @uartdis,r12 ;set uart base address notread tb 27 ;test dsr pin. Are we connected? jne notread sbo 16 ;activate rts line. ready to send waitcts tb 28 jne waitcts notempt tb 22 ;is emission buffer empty? jne notempt ldcr r6,8 ;send byte sbz 16 ;inactivate rts line. not ready to send bl @rs232of bl @pcodeon mov @procret,r11 b *r11 And one minor change to minimize the chance of losing a character on receive is to give the permission to send immediately before you start looking for it. .func getbyte ;receive a byte from the serial port .ref pcodeon,pcodoff,rs232on,rs232of,uartdis,procret,cruadr mov r11,@procret bl @pcodoff bl @rs232on a @uartdis,r12 ;uart base cru address chkdsr tb 27 ;test dsr pin. signal is inverted! jne chkdsr ;if line high then not ready ; pull -CTS line right before the code tests the receive buffer sbz -27 ;activate cts line. ready to receive chkbuf tb 21 ;test receive buffer jne chkbuf stcr r6,8 ;get byte into r6 sbz 18 ;reset buffer cru bit 21 swpb r6 sbo -27 ;inactivate cts line. cru 5 disp from 1340h mov r6,*r10 ;place byte on return stack bl @rs232of bl @pcodeon mov @procret,r11 b *r11 And of course you can add flag variables that that let you enable or disable either or both handshake tests, but for receive the 99 really needs to throttle the sending machine. (until you get @InsaneMultitasker 's interrupt driven receive running) 3 1 Quote Link to comment https://forums.atariage.com/topic/193355-pascal-on-the-994a/page/28/#findComment-5420276 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.