Jump to content

Photo

Assembly on the 99/4A


745 replies to this topic

#726 Vorticon OFFLINE  

Vorticon

    River Patroller

  • 3,229 posts
  • Location:Eagan, MN, USA

Posted Sun May 13, 2018 7:12 AM

 
A simple resistor and capacitor on the switch tied to the LOAD input would have provided some simple hardware debounce and the software loop would probably not be necessary.
 
The problem with this approach for Vorticon's purposes is that the LOAD is being driven by a microcontroller, so the input is not bouncing.
 


If that is the case then a timeout is not going to solve this, interrupts will continue to come.  Several things come to mind:

 

1. Disable interrupts immediately upon entering the routine, and re-enable them when you are done.  Keep in mind though, that if the interrupts are coming in fast and furious, it could easily overwhelm the 99/4A.  As soon as you are done with the routine and re-enable interrupts, another could be right there waiting.

 

2. Modify the SmallyMouse code to limit the interrupt rate.  The code is available, I had to compile it myself and load it on the microcontroller.

 

3. You could put a triggered one-shot between the interrupt and the 99/4A to limit the interrupt rate.  Once an interrupt triggers the one-shot, any more interrupts are blocked until the one-shot timeout, which you could adjust to something sensible (once every 30ms or so would be a mouse update every two video frames).

 

You are absolutely correct Matt. I just thought the debouncing in software trick was neat.

Unfortunately, there is no way to disable the LOAD interrupt as it is umaskable. As for modifying the SmallyMouse code, it would be easier to just use an arduino with USB support like the Teensy++ and just decode the USB packets coming from the mouse (they have a standard format) and output direct positional data to a few pins without having to worry about quadrature encoding, phase shifts and all that messy stuff. That way a simple connection to the PIO port will work perfectly. This is actually what I want to experiment with next. The SmallyMouse was really designed to connect to vintage computers already equipped with a mouse port (Amiga, Atari ST, Electron etc...) and I have found that it's more pain than it's worth to try adapting it to mouseless systems. As to your third option, it requires additional hardware which would defeat the purpose...



#727 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,536 posts
  • Location:Castaic, California

Posted Sun May 13, 2018 3:29 PM

Yeah, I think I was attracted to the device for coin-op purposes, since it outputs the same signals as an arcade-style track-ball.  But unless you have a system designed to accept that type of input, then it is probably more trouble than it is worth, as you pointed out.



#728 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,179 posts
  • HarmlessLion
  • Location:BUR

Posted Sun May 13, 2018 11:40 PM

The LOAD interrupt on the 9900 /is/ level triggered, but after any interrupt you get one instruction before interrupts are enabled again - so the CLR is safe.

We had a chat about this in another thread a few years ago: http://atariage.com/...t-the-side-port

Classic99 won't let you see the effects of CLRing the workspace vector, as it refuses to trigger a LOAD interrupt if the vector's not filled out, but it will still work since the first trigger happens. ;) I hadn't seen that trick before I coded support. The real console will keep re-triggering the interrupt for as long as the pin is low.

#729 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Tue Aug 14, 2018 7:41 PM

 

I think >8378 is used by the GPL RAND function to return a random byte.  I will check on that.  <--Yes, this is correct.

 

>83C0 is the console ISR’s R0 and the random number seed for the GPL RAND function used by TI Basic and RXB.  It is also the seed for the Pseudo-Random Number Generators of TI Extended Basic, TI Forth, fbForth and TurboForth (I think).  Not sure about Camel99 Forth.

 

...lee

 

 

Looking at these older posts for little Gems. 

 

Just to confirm, under the fine tuteledge found here, Camel99 Forth also uses >83C0 to pick up a PRNG seed.

 

In fact it is named "SEED" in the code. 

 

See file: https://github.com/b...B.TI/RANDOM.FTH  for details

 

B



#730 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 6:00 AM

Question for the ASM coders.

 

In Forth Assembler I built an integrated BLWP vector that puts the code and the vector together.  It seems a little cleaner to me. 

 

I think the code below would do this in conventional Assembler.

I am wondering if anybody else uses a structure like this or have I just stumbled upon something everybody already knows/does.

 

(code is untested so don't laugh too hard if it's all wrong)

 

Sidenote:

The reason it becomes interesting in Forth Assembler is because you can make the structure run BLWP automatically so SUB-programs like this run just by invoking the label name. Kinda cool , at least for it was for me.

WKSP1  BSS  20

PROG1  DATA WKSP1,$+2
       A    R1,R0
       A    R2,R0
       A    R3,R0
       RTWP
      
PROG2  DATA WKSP1,$+2
       S    R1,R0
       S    R2,R0
       S    R3,R0
       RTWP,
         
      BLWP  PROG1 
      BLWP  PROG2 


#731 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,316 posts
  • Location:Germany

Posted Wed Aug 15, 2018 9:19 AM

In Assembler, you have to write BLWP @PROG1. Also, the BLWP lines must be part of some longer program code that is called somehow, and later returns somehow. (Note that you need to remove the comma after RTWP.)



#732 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,825 posts
  • Location:Denmark

Posted Wed Aug 15, 2018 9:47 AM

Would, in Forth, use different workspaces for PROG1 and PROG2? Otherwise you could just use BL.



#733 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,316 posts
  • Location:Germany

Posted Wed Aug 15, 2018 10:04 AM

I usually share workspaces between subprograms, not for data exchance, but for saving space. It's important though that the caller uses another one.



#734 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,701 posts
  • Location:Silver Run, Maryland

Posted Wed Aug 15, 2018 10:05 AM

WKSP1  BSS  >20

   or

WKSP1  BSS  32

 

...lee



#735 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 11:00 AM

In Assembler, you have to write BLWP @PROG1. Also, the BLWP lines must be part of some longer program code that is called somehow, and later returns somehow. (Note that you need to remove the comma after RTWP.)

 

Noted. @ required.  Comma not required.

 

This is just a code fragment to demonstrate the Vector and code being together. So yes a great deal more would be part of whatever program this was part of.



#736 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 11:06 AM

Would, in Forth, use different workspaces for PROG1 and PROG2? Otherwise you could just use BL.

These examples are more about leaving Forth and doing a sub-program in another workspace with Assembly language and then returning to Forth.

 

And in this case both sub-programs share a workspace so they can keep important information in the registers between calling PROG1 or PROG2.



#737 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 11:09 AM

WKSP1  BSS  >20

   or

WKSP1  BSS  32

 

...lee

Too many Forth programs under my belt clearly. :-)



#738 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 11:14 AM

So the only line I am actually curious about is:

PROG1  DATA  WKSP1,$+2

Does anybody use this structure?



#739 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,316 posts
  • Location:Germany

Posted Wed Aug 15, 2018 11:39 AM

Me, yes. Do you mean that the vector is placed directly before the program code, or just the $+2 notation?



#740 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Wed Aug 15, 2018 3:39 PM

Yes that is what meant.

#741 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 495 posts

Posted Thu Aug 16, 2018 8:16 AM

In my opinion, the advantage of the vectored addressing is that you can group the vectors together, for easy overview. It means that if you want to write a new implementation of one subroutine, you can place that anywhere, and then, at your central vector pack location, just change the pointer to the new version, or the old version, for testing that they both work (or that the new one doesn't have the same bug as the old one). You don't need to scout around for the different routines to find their vectors.

Especially if the actual code is in different include files, due to total code size, this is valuable.



#742 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • 2,163 posts

Posted Thu Aug 16, 2018 1:40 PM

So the only line I am actually curious about is:

PROG1  DATA  WKSP1,$+2

Does anybody use this structure?

I learned this exact approach from another programmer during when I first started dabbling in assembly.  It wasn't until years later that I came upon some code that used the vector/label, and it dawned on me that I could place that vector "anywhere".



#743 FarmerPotato OFFLINE  

FarmerPotato

    Star Raider

  • 94 posts
  • Location:Austin, TX

Posted Thu Aug 16, 2018 4:52 PM

A variation on BLWP (from FORTI's interrupt service routine)

LI R1,$+8
MOV *SP,R0
BLWP R0
* PC continues here:

BLWP takes WP from R0, PC from R1, 

This gets a workspace pointer from the FORTH stack and performs an approximation of LWP, a TMS9995 instruction, on the TMS9900.

 

It's used to run the same routine on different workspace contexts.

 

Afterward you can put a return address in R14.

CLR *SP     set status
LI R14,NEXT
RTWP


#744 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Thu Aug 16, 2018 5:34 PM

In my opinion, the advantage of the vectored addressing is that you can group the vectors together, for easy overview. It means that if you want to write a new implementation of one subroutine, you can place that anywhere, and then, at your central vector pack location, just change the pointer to the new version, or the old version, for testing that they both work (or that the new one doesn't have the same bug as the old one). You don't need to scout around for the different routines to find their vectors.

Especially if the actual code is in different include files, due to total code size, this is valuable.

 

 

I learned this exact approach from another programmer during when I first started dabbling in assembly.  It wasn't until years later that I came upon some code that used the vector/label, and it dawned on me that I could place that vector "anywhere".

 

And course making a table of vectors let's you call them by index which is cool too.

So I guess the moral is  that "one size does not fit all".



#745 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Thu Aug 16, 2018 5:44 PM

 

A variation on BLWP (from FORTI's interrupt service routine)

LI R1,$+8
MOV *SP,R0
BLWP R0
* PC continues here:

BLWP takes WP from R0, PC from R1, 

This gets a workspace pointer from the FORTH stack and performs an approximation of LWP, a TMS9995 instruction, on the TMS9900.

 

It's used to run the same routine on different workspace contexts.

 

Afterward you can put a return address in R14.

CLR *SP     set status
LI R14,NEXT
RTWP

 

OH! That is very clever.   So by doing BLWP R0  (as opposed to  BLWP @R0)  you can use the registers as vector addresses.   

 

So since my Forth keeps TOS in R4, all I need to do in Forth assembler is...

CODE CALLPROG  (code_address workspace -- )
              *SP+ R5 MOV,
                  R4 BLWP,
                     NEXT,

How cool!  I gotta try that right now.

 

Thanks!



#746 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 650 posts
  • Location:The Great White North

Posted Thu Aug 16, 2018 6:56 PM

This code worked just as you described. 

 

Thanks again FarmerPotato!  ;)

\ BLWP direct test

INCLUDE DSK1.TOOLS.F
INCLUDE DSK1.ASM9900.F

HEX
CREATE WKSP2  20 ALLOT

CREATE TEST
       R0 DEAD LI,
       R1 BEEF LI,
       R2 DEAD LI,
       R3 BEEF LI,
       RTWP,

CODE BLWP() ( addr wksp -- )
    *SP+ R5 MOV,  \ pop addr into R5 (temp register in CAMEL99) 
     R4 BLWP,     \ BLWP direct to wksp in TOS cache register
     TOS POP,     \ refill TOS register (R4)
     NEXT,        \ return to Forth 
     ENDCODE

EDIT: I should add

 

Called like this: 

TEST WKSP2 BLWP() 

Edited by TheBF, Thu Aug 16, 2018 7:33 PM.





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users