Jump to content
wolhess

Problems with the sound output in assembly

Recommended Posts

Hi,

maybe an assembly expert can help me, I'm just taking my first steps in assembly language programming.

 

I don't really understand the sound output. I have tried the example program "A CHIME" from the EA manual on page 321 and it works as it should.

Then I changed the program to produce a BEEP. This also works as it should.

 

However, if I include a keyboard query to repeat the BEEP with "REDO" and to exit the program with "ESCAPE", then my program only works for the first BEEP.

 

I come back to the EA with "ESCAPE". However, with "REDO" no sound is played and the TI gets stuck.
Even if I then reload and start the program in the EA, no sound is played. Only after a reset via the TI title screen the program is working again at the first run.

 

Spoiler

*
* Example program to play a chime
* E/A page 321-323
* Modified for playing a BEEP
*
       REF  VMBW,KSCAN
       DEF  BEEP
 
 
 
*
KEYVAL EQU  >8375
STATUS EQU  >837C
 
BUFFER EQU  >1000
*
SAVERT DATA >0000
*
H01    BYTE >01
REDOV  BYTE >06
ESCPV  BYTE >0F
       EVEN
*
BEEP   MOV  R11,@SAVERT  SAVE RETURN ADDRESS
 
       LI   R0,BUFFER    VDP-RAM BUFFER ADDRESS
       LI   R1,BEEPST    BEEP SOUND TABLE
       LI   R2,8
 
       BLWP @VMBW        LOAD VDP-RAM
*
LOOP   LIMI 0            DISABLE VDP INTERRUPT
       LI   R10,BUFFER   LOAD SOUND TABLE ADDRESS
       MOV  R10,@>83CC   LOAD POINTER TO THE TABLE
       SOCB @H01,@>83FD  SET VDP-RAM FLAG
       MOVB @H01,@>83CE  START SOUND PROCESSING
       LIMI 2            ENABLE VDP INTERRUPT
 
*
LOOP2  MOVB @>83CE,@>83CE READY CHECK?
       JEQ  KEY           YES, LOOK FOR A KEY PRESSED
       JMP  LOOP2         NO, WAIT UNTIL FINISHED
 
KEY    CLR   @STATUS     CLEAR STATUS
       BLWP  @KSCAN      PERFORM A KEY SCAN
       MOV   @STATUS,@STATUS A KEY IS PRESSED?
       JEQ   KEY             NO, CHECK AGAIN
 
       CB    @KEYVAL,@ESCPV  ESCAPE?
       JEQ   ESCAP           YES, ->
 
       CB    @KEYVAL,@REDOV  REDO?
       JEQ   LOOP            YES, ->
       JMP   KEY             NO, CHECK AGAIN
 
ESCAP  CLR   @STATUS
       MOV   @SAVERT,R11
       RT
*
 
BEEPST BYTE >03,>8E,>0F,>91,>1E
       BYTE >01,>9F,>0
       END
 


What do I have to do so that the sound is also played on the second run?

Share this post


Link to post
Share on other sites
1 hour ago, wolhess said:

JEQ  LOOP          YES, LOOK FOR A KEY PRESSED

Maybe this should be...

 

JEQ  KEY          YES, LOOK FOR A KEY PRESSED

 

...not too sure I'm an expert though.:lol:

Share this post


Link to post
Share on other sites

Yes, you are right, that's how I did it, but then the program behaves exactly as I described it.

 

--> I changed it in the first message!

Share this post


Link to post
Share on other sites
1 hour ago, wolhess said:

KEY    CLR   @STATUS     CLEAR STATUS

 Maybe interrupts need to be off during KSCAN...

 

KEY    LIMI 2
       LIMI 0
       CLR  @STATUS     CLEAR STATUS

 

  • Like 1

Share this post


Link to post
Share on other sites

Your suggestion works.

 

Wow. I would never have figured it out on my own.

 

Thanks alot! 

  • Thanks 1

Share this post


Link to post
Share on other sites

You're welky.:-D

Despite that I should have recognized this, from my own pitfalls ...years gone by!

 

Classic99's LOG, warned about the (SCAN?) program writing to VDP RAM with interrupts on.

 

So, looks like TURSI gets some of the credit too!;)

  • Like 1

Share this post


Link to post
Share on other sites

I did not find this information in the EA manual. Neither with SOUND or KSCAN nor with SCAN or LIMI.

 

However, LIMI says that LIMI 0 is the normal state of the computer.

 

 

Share this post


Link to post
Share on other sites

I'd noticed, some time ago... That there are a lot of seemingly different examples of how to setup/use KSCAN. Not all of them worked consistently for me though. I think this method came from the red Molesworth book.

 

I suppose... interrupts need to be on when the key is depressed, in order to be detected. But need to be off when KSCAN runs. Dunno for sure though. But, this seems to always work for me.:cool:

Share this post


Link to post
Share on other sites

There’s an excellent beginners assembly language book I just happened to read through that specifically brought up the subject of sound generation and the need for an LIMI 2/LIMI 0 pair in the main loop to make sound work.  It’s aimed at the Mini Memory cartridge with the Line By Line assembler, but it had a lot of good information for a beginner in it.  COMPUTE!’s Beginners Guide to Assembly Language on the TI 99/4A.  You can find that I think on archive.org as a PDF.  It might be worth taking a look through, even if you are planning to use Editor/Assembler.

  • Like 1

Share this post


Link to post
Share on other sites
21 minutes ago, Casey said:

There’s an excellent beginners assembly language book I just happened to read through that specifically brought up the subject of sound generation and the need for an LIMI 2/LIMI 0 pair in the main loop to make sound work.  It’s aimed at the Mini Memory cartridge with the Line By Line assembler, but it had a lot of good information for a beginner in it.  COMPUTE!’s Beginners Guide to Assembly Language on the TI 99/4A.  You can find that I think on archive.org as a PDF.  It might be worth taking a look through, even if you are planning to use Editor/Assembler.


 

Thank you very much ,
in the book the subject of sound is described in great detail. On page 167 it is also stated that the VDP interrupt should be switched on and off quickly.

That was the secret that I didn't know.

 

  • Like 2

Share this post


Link to post
Share on other sites

There is another interesting point about this LIMI 2/0 and the VDP interrupt. You know, they just did not tell us the whole story ... 🙂

 

When I learned assembly language programming, I learnt that I have to do this LIMI 2/0 in a loop for interrupt-driven function, and that it works. But why does it work? My concern was that these LIMI operations ran in a couple of microseconds, and why should the VDP just raise its interrupt line in between? Wouldn't I miss a lot of interrupts?

 

Much later (actually, when I worked in MAME) I understood what happens. The interrupt input of the 9900 is level-triggered; that is, the interrupt service will start as soon as the processor detects INTREQ*=0 (and the level indicated via IC0-IC3 is higher than the LIMI mask). The VDP interrupt output is latched inside the VDP. That is, when an interrupt occurs, its INT line gets active and stays so, until you clear the interrupt in the VDP. This can only be done by reading the status register. If you look inside "TI Intern" you see that at address 094A, the SBO 2 instruction first disarms the interrupt trigger in the 9901 (Heiner Martin's comment was wrong at that point), and at 0A84, the status is read, which clears the interrupt again.

 

Thus, when LIMI 2 is executed, the latched VDP interrupt will make the CPU jump to the interrupt service immediately.

 

BTW, the 9995 has its own latches which can be queried via CRU addresses 1EE4/6/8.

  • Like 2

Share this post


Link to post
Share on other sites
18 hours ago, HOME AUTOMATION said:

I suppose... interrupts need to be on when the key is depressed, in order to be detected. But need to be off when KSCAN runs. Dunno for sure though. But, this seems to always work for me.:cool:

No, the TI keyboard is literally just a grid of switches. They don't trigger interrupts, so interrupts don't need to be enabled. There's no storage and no caching of status. The KSCAN function literally reads the keyboard by enabling each column, and seeing if any rows on that column are pressed - this is why KSCAN takes a fair bit of time to run. :) It also means you only know the state of the keyboard at the exact time that you scan it.

 

I don't see in a quick scan why interrupts should interfere with KSCAN, but all console software in the TI runs on the assumption that interrupts are normally disabled. When you violate assumptions in other people's code, you tend to get bugs. ;)

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites

I tested this on Classic99 somewhat...

 

...looks like you're right(again);-).

 

Upon better recollection, I probably have the LIMI 2/0 in my keyscan loops, as a simple way to allow the QUIT key-pair to function.:) Perhaps also to provide simple compatibility with TI's wonderfully well-thought-out sample code.;) ...Not to mention my own.:lol:

Share this post


Link to post
Share on other sites
22 hours ago, Tursi said:

I don't see in a quick scan why interrupts should interfere with KSCAN, but all console software in the TI runs on the assumption that interrupts are normally disabled. When you violate assumptions in other people's code, you tend to get bugs. ;)

Doesn't the ISR under normal circumstances try and read the QUIT key ? That in itself might interfere.
 

  • Like 1

Share this post


Link to post
Share on other sites
15 hours ago, sometimes99er said:

Doesn't the ISR under normal circumstances try and read the QUIT key ? That in itself might interfere.
 

Ah... yeah, that's probably it. Changing the CRU setup in the middle of a scan wouldn't be helpful. ;)

 

Share this post


Link to post
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.

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