Jump to content



0

Lynx audio


5 replies to this topic

#1 jp48 OFFLINE  

jp48

    Space Invader

  • 41 posts
  • Location:Finland

Posted Mon Nov 15, 2010 11:05 AM

Hi all,

Trying to write CC65-program to Lynx, using only Mikey audio, writing directly to sound registers using POKE
(have done same for several consoles, without problems, or at least problems I couldn't solve myself :). Anyway
when trying to do same for Lynx, nothing (except interesting graphics in Handy), using POKE to write 0xFD20 to
0xFD27, apparently something is needed to initialize Mikey/Lynx/audio, I've only used CLI(), should I initialize
tgi too. And/or anything else ?


Thanks for advance !


-jp

#2 matashen OFFLINE  

matashen

    Moonsweeper

  • 397 posts

Posted Mon Nov 15, 2010 1:49 PM

View Postjp48, on Mon Nov 15, 2010 11:05 AM, said:

Hi all,

Trying to write CC65-program to Lynx, using only Mikey audio, writing directly to sound registers using POKE
(have done same for several consoles, without problems, or at least problems I couldn't solve myself :). Anyway
when trying to do same for Lynx, nothing (except interesting graphics in Handy), using POKE to write 0xFD20 to
0xFD27, apparently something is needed to initialize Mikey/Lynx/audio, I've only used CLI(), should I initialize
tgi too. And/or anything else ?


Thanks for advance !


-jp

no, there is no more to initialize
here are a example how to get out some noise...

uchar MStereo at 0xfd50;

#define Channel0 (char *)0xfd20
#define Channel1 (char *)0xfd28
#define Channel2 (char *)0xfd30
#define Channel3 (char *)0xfd38

void SoundInit()
{
MStereo = 0x42;
}

void SoundSetup(channel, volume, shift, lowshift, backup, flags)
uchar *channel;
uchar volume;
uchar shift;
uchar lowshift;
uchar backup;
uchar flags;
{
channel[0] = volume;
channel[1] = shift;
channel[3] = lowshift;
channel[4] = backup;
channel[5] = flags;
}

SoundSetup(Channel3,0x00,0x00,0x05,0xbb,0x19);

I use it with the newcc65 from the BLL Kit and it runs

Regards
Matthias

#3 jp48 OFFLINE  

jp48

    Space Invader

  • 41 posts
  • Location:Finland

Posted Mon Nov 15, 2010 2:40 PM

View Postmatashen, on Mon Nov 15, 2010 1:49 PM, said:


no, there is no more to initialize
here are a example how to get out some noise...

uchar MStereo at 0xfd50;

#define Channel0 (char *)0xfd20
#define Channel1 (char *)0xfd28
#define Channel2 (char *)0xfd30
#define Channel3 (char *)0xfd38

void SoundInit()
{
MStereo = 0x42;
}

void SoundSetup(channel, volume, shift, lowshift, backup, flags)
uchar *channel;
uchar volume;
uchar shift;
uchar lowshift;
uchar backup;
uchar flags;
{
channel[0] = volume;
channel[1] = shift;
channel[3] = lowshift;
channel[4] = backup;
channel[5] = flags;
}

SoundSetup(Channel3,0x00,0x00,0x05,0xbb,0x19);

I use it with the newcc65 from the BLL Kit and it runs

Regards
Matthias

Thanks very much Matthias, yes, I only poked to 0xfd50 as "init" and it works ! Only thing I can't find (or perhaps the mechanism is different) is vblank routine for timing. nes.h contains waitvblank(), anything similar to Lynx.

Has anyone used mednafen as Lynx emulator, I can't get it work (except with NES, nothing else), lynxboot.img is copied and has correct MD5 sum, anyway doesn't recognize Lynx .o files. Any of them, not only mine :).

Thanks !

-jp

#4 matashen OFFLINE  

matashen

    Moonsweeper

  • 397 posts

Posted Tue Nov 16, 2010 4:05 PM

View Postjp48, on Mon Nov 15, 2010 2:40 PM, said:

View Postmatashen, on Mon Nov 15, 2010 1:49 PM, said:


no, there is no more to initialize
here are a example how to get out some noise...

uchar MStereo at 0xfd50;

#define Channel0 (char *)0xfd20
#define Channel1 (char *)0xfd28
#define Channel2 (char *)0xfd30
#define Channel3 (char *)0xfd38

void SoundInit()
{
MStereo = 0x42;
}

void SoundSetup(channel, volume, shift, lowshift, backup, flags)
uchar *channel;
uchar volume;
uchar shift;
uchar lowshift;
uchar backup;
uchar flags;
{
channel[0] = volume;
channel[1] = shift;
channel[3] = lowshift;
channel[4] = backup;
channel[5] = flags;
}

SoundSetup(Channel3,0x00,0x00,0x05,0xbb,0x19);

I use it with the newcc65 from the BLL Kit and it runs

Regards
Matthias

Thanks very much Matthias, yes, I only poked to 0xfd50 as "init" and it works ! Only thing I can't find (or perhaps the mechanism is different) is vblank routine for timing. nes.h contains waitvblank(), anything similar to Lynx.

Has anyone used mednafen as Lynx emulator, I can't get it work (except with NES, nothing else), lynxboot.img is copied and has correct MD5 sum, anyway doesn't recognize Lynx .o files. Any of them, not only mine :).

Thanks !

-jp

Timing by Vsync

extern uchar VBLflag;
#asm
_VBLflag = $a0
#endasm

#define VSYNC {++VBLflag;while( VBLflag );}


VBL() interrupt
{
char i;
VBLflag = 0; // indicates that a VBL has ocurred


lastcounter++;
}

....
main()
{
...
InitIRQ();
InstallIRQ(2,VBL);
EnableIRQ(2);
CLI;
...
}
Regards
Matthias

#5 sage OFFLINE  

sage

    Moonsweeper

  • 391 posts
  • Location:Germany

Posted Sun Jan 2, 2011 11:06 AM

View Postjp48, on Mon Nov 15, 2010 2:40 PM, said:


Thanks very much Matthias, yes, I only poked to 0xfd50 as "init" and it works ! Only thing I can't find (or perhaps the mechanism is different) is vblank routine for timing. nes.h contains waitvblank(), anything similar to Lynx.

Has anyone used mednafen as Lynx emulator, I can't get it work (except with NES, nothing else), lynxboot.img is copied and has correct MD5 sum, anyway doesn't recognize Lynx .o files. Any of them, not only mine :).

Thanks !

-jp

mednafen does not recognize *.o files, you have to convert them to an rom image and then to a handy lnx format image.
Thats why I only use Makefiles for development nowadays, it doesnt matter if i only create a .o or the complete image. everthign goes in one step.

OR you add the support to mednafen :-)

#6 karri OFFLINE  

karri

    Stargunner

  • 1,049 posts
  • Location:Espoo, Finland

Posted Mon Jan 3, 2011 4:36 AM

View Postsage, on Sun Jan 2, 2011 11:06 AM, said:

mednafen does not recognize *.o files, you have to convert them to an rom image and then to a handy lnx format image.
Thats why I only use Makefiles for development nowadays, it doesnt matter if i only create a .o or the complete image. everthign goes in one step.

OR you add the support to mednafen :-)

That is the main reason why I added the .lnx target generation as the default target to the cc65.org tools.

The new cc65 tools set up the IRQ's automatically. You do not need to set up any vectors anymore.

Instead you have to declare your ASM routine to be an interrupt handler like this;

    .interruptor RealTimeHandler
    .export _lastcounter

_lastcounter .word 0

RealTimeHandler:
    lda INTSET
    and #VBL_INTERRUPT
    beq @1
    inc _lastcounter
    bne @1
    inc _lastcounter+1
@1: clc
    rts

The linker will take care of creating the vectors and setting up everything. This handler will then be called at every interrupt. It will then check if the interrupt was generated by VBL and if it was it increments _lastcounter.

To activate the interrupt you can initialize the tgi-driver (it is automatically setting up the VBL counter, interrupt handlers and vectors).

  tgi_install(&lynxtgi);
  tgi_init();
  CLI();

All interruptors will always be called during every interrupt as long as carry is cleared when the interruptor exits. If you set the carry flag before exit then the interrupt has been handled. In my interruptors (tgi-graphics and ComLynx) I always leave the carry as cleared so that you can add your own hooks for some extra processing. This is why you can have many interruptors that share the same interrupt. Like tgi-processing and incrementing _lastcounter. Both handlers will be called.

Or you can even set up an interruptor of your own for the music. It should be something similar to the VBL interrupts.

From the asminc file it appears that interrupts 0, 2 and 4 are taken.

; Interrupt bits in INTRST and INTSET
TIMER0_INTERRUPT = $01
TIMER1_INTERRUPT = $02
TIMER2_INTERRUPT = $04
TIMER3_INTERRUPT = $08
TIMER4_INTERRUPT = $10
TIMER5_INTERRUPT = $20
TIMER6_INTERRUPT = $40
TIMER7_INTERRUPT = $80

HBL_INTERRUPT = TIMER0_INTERRUPT
VBL_INTERRUPT = TIMER2_INTERRUPT
SERIAL_INTERRUPT = TIMER4_INTERRUPT

  lda     #$80            ; Enable VBL interrupts
  tsb     VTIMCTLA
  lda     #$7e            ; 75 Hz
  ldx     #$20
  sta     HTIMBKUP
  stx     PBKUP

--
Regards,

Karri

Edited by karri, Mon Jan 3, 2011 5:00 AM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users