Zum Inhalt springen

Problem bei C zu Java Portierung


Devilmarkus

Empfohlene Beiträge

Hallo zusammen,

momentan beschäftige ich mit einer kleinen Portierung von C zu Java.

Dabei bin ich auf ein kleines Problem gestossen:

Eine Routine erreicht in meinem Code leider nicht die Punkte "set channel interrupt" und "stop channel".

Ist das eventuell ein Fehler, der Aufgrund von Berechnungen erfolgt?

Hier die Codebeispiele:

C code (Original)


void    ASIC_DMA_ExecuteCommand(int ChannelIndex)

{

        Z80_WORD        Command;

        int CommandOpcode;

        int     Addr;

        ASIC_DMA_CHANNEL        *pChannel = &ASIC_Data.DMAChannel[ChannelIndex];


        Addr = ASIC_Data.DMA[ChannelIndex].Addr.Addr_W;


        Command = ASIC_DMA_GetOpcode((Z80_WORD)(Addr & 0x0fffe));


        CommandOpcode = (Command & 0x07000)>>12;


        Addr = Addr+2;


        if (CommandOpcode == 0)

        {

                /* LOAD R,D */


                int     Register;

                int     Data;


                int PreviousRegisterSelected;


                /* PSG register */

                Register = (Command>>8) & 0x0f;

                /* data to write */

                Data = (Command & 0x0ff);


                /* store current selected PSG address register */

                PreviousRegisterSelected = PSG_GetSelectedRegister();


                /* select new register */

                PSG_RegisterSelect(Register);


                /* write data */

                PSG_WriteData(Data);


                /* select previous register again - not to upset other code */

                PSG_RegisterSelect(PreviousRegisterSelected);

        }

        else

        {

                if (CommandOpcode & 0x01)

                {

                        /* PAUSE n */


                        /* pause of 0 is equivalent to a NOP */

                        int PauseCount = Command & 0x0fff;


                        if (PauseCount-1!=0)

                        {

							pChannel->PauseCount = PauseCount-1;

                            pChannel->PrescaleCount = ASIC_Data.DMA[ChannelIndex].Prescale;

                            pChannel->PauseActive = TRUE;

                        }


                }


                if (CommandOpcode & 0x02)

                {

                        /* REPEAT n */


                        /* store repeat count */

                        pChannel->RepeatCount = Command & 0x0fff;


                        /* set next instruction as loop start */

                        pChannel->LoopStart = Addr & 0x0ffff;

                }


                if (CommandOpcode & 0x04)

                {

                        /* NOP, LOOP, INT, STOP */


                        if (Command & 0x0001)

                        {

                                /* LOOP */


                                /* if loop count is 0, this acts like a NOP */


                                /* check repeat count */

                                if (pChannel->RepeatCount!=0)

                                {

                                        /* decrement count */

                                        pChannel->RepeatCount--;


                                        /* reload channel addr from stored loop start */

                                        Addr = pChannel->LoopStart;

                                }



                        }


                        if (Command & 0x0010)

                        {

                                /* INT */


                                /* set channel interrupt */

                                ASIC_Data.InternalDCSR|=1<<(6-ChannelIndex);

                        }


                        if (Command & 0x0020)

                        {

                                /* STOP */


                                /* stop channel */

                                ASIC_Data.InternalDCSR&=~(1<<ChannelIndex);

                        }

                }

        }


		ASIC_DMA_WriteChannelAddr(ChannelIndex, Addr);


/*        ASIC_Data.DMA[ChannelIndex].Addr.Addr_W=(unsigned short)Addr; */


        ASIC_UpdateRAMWithInternalDCSR();


}
Hier meine abgewandelte Java-Version:
    void ASIC_DMA_ExecuteCommand(int ChannelIndex) {

//        ASIC_DMA_CHANNEL pChannel[] = this.pChannel;

        int Command;

        int CommandOpcode;

        int Addr;


        Addr = DMA[ChannelIndex].Addr.getAddr_W();

        Command = ASIC_DMA_GetOpcode((Addr & 0x0fffe));


        CommandOpcode = (Command & 0x07000) >> 12;

        Addr = Addr + 2;


        if (CommandOpcode == 0) {

            /*

             * LOAD R,D

             */

            int Register;

            int Data;


            int PreviousRegisterSelected;


            /*

             * PSG register

             */

            Register = (Command >> 8) & 0x0f;

            /*

             * data to write

             */

            Data = (Command & 0x0ff);


            /*

             * store current selected PSG address register

             */

            PreviousRegisterSelected = psg.getSelectedRegister();


            /*

             * select new register

             */

            psg.setSelectedRegister(Register);


            /*

             * write data

             */

            psg.writeData(Data);


            /*

             * select previous register again - not to upset other code

             */

            psg.setSelectedRegister(PreviousRegisterSelected);

        } else {

            if ((CommandOpcode & 0x01) != 0) {

                /*

                 * PAUSE n

                 */


                /*

                 * pause of 0 is equivalent to a NOP

                 */

                int PauseCount = Command & 0x0fff;


                if (PauseCount - 1 != 0) {

                    pChannel[ChannelIndex].PauseCount = PauseCount - 1;

                    pChannel[ChannelIndex].PrescaleCount = 0;//ASIC_Data.DMA[ChannelIndex].Prescale;

                    pChannel[ChannelIndex].PauseActive = true;

                }


            }


            if ((CommandOpcode & 0x02) != 0) {

                /*

                 * REPEAT n

                 */


                /*

                 * store repeat count

                 */

                pChannel[ChannelIndex].RepeatCount = Command & 0x0fff;


                /*

                 * set next instruction as loop start

                 */

                pChannel[ChannelIndex].LoopStart = Addr & 0x0ffff;

            }


            if ((CommandOpcode & 0x04) != 0) {

                /*

                 * NOP, LOOP, INT, STOP

                 */


                if ((Command & 0x0001) != 0) {

                    /*

                     * LOOP

                     */


                    /*

                     * if loop count is 0, this acts like a NOP

                     */


                    /*

                     * check repeat count

                     */

                    if (pChannel[ChannelIndex].RepeatCount != 0) {

                        /*

                         * decrement count

                         */

                        pChannel[ChannelIndex].RepeatCount--;


                        /*

                         * reload channel addr from stored loop start

                         */

                        Addr = pChannel[ChannelIndex].LoopStart;

                    }



                }


                if ((CommandOpcode & 0x0010) != 0) {

                    /*

                     * INT

                     */


                    /*

                     * set channel interrupt

                     */

                    ASIC_Data.InternalDCSR |= 1 << (6 - ChannelIndex);

                }


                if ((CommandOpcode & 0x0020) != 0) {

                    /*

                     * STOP

                     */


                    /*

                     * stop channel

                     */

                    ASIC_Data.InternalDCSR &= ~(1 << ChannelIndex);

                }

            }

        }


        ASIC_DMA_WriteChannelAddr(ChannelIndex, Addr);

        ASIC_UpdateRAMWithInternalDCSR();


    }
public class ASIC_ADDR {


    public addrb Addr_B = new addrb();


    public void writeAddr_W(int word) {

        Addr_B.l = (word & 0xff);

        Addr_B.h = ((word >> 8) & 0x0ff);

    }

    class addrb {

        public int l;

        public int h;

    }


    public int getAddr_W() {

        return (Addr_B.l & 0xff) | ((Addr_B.h << 8) & 0xff00);

    }

}

Addr_B.l und Addr_B.h werden korrekt gesetzt (nicht hier im Code enthalten, da hierfür unwichtig)

Gibt es zwischen C und Java mathematische Differenzen, welche ich hier nicht richtig berücksichtigt habe?

Die "psg.setSelectedRegister" und - .writeData funktionieren auch korrekt!

Es sieht aus, als ob der ChannelOpcode nicht richtig berechnet wird...

Ich hoffe, mir kann hier jemand helfen :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Paar Fehler sind zwar noch irgendwo versteckt (hat nichts mit diesem Thema zu tun), aber dank Klotzkopp funktioniert nun schon einiges mehr.

Zum Testen: (Amstrad CPC+ Emulation)

JavaCPC games site

Im Menü die Standardversion und dann die Amstrad Plus Variante auswählen.

Leertaste und Cursortasten fürs Menü.

Joystick (im Spiel) liegt auf den Ziffernblocktasten bei Num-Lock ein.

prehist1.png

prehist2.png

Die Raster (Interruptgeschaltet) verwalten hier die Farbbalken und Bildschirmanordnung.

Ohne diesen Bugfix sah es Katastrophal aus!!!

Also Danke nochmal an Klotzkopp!!!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror

Die Frage ist recht allgemein und so auch meine Antwort. Je nach Anwendungsfall:

- einfach int verwenden und bei den Berechnungen auf die unteren 16 Bits beschränken

- short verwenden und entsprechende Vorsicht und Korrekturmaßnahmen bei den Berechnungen anwenden.

Ich hatte seinerzeit mal einen x86-Interpreter in Java verfasst und die erste Variante dafür verwendet - die ist weniger schmerzhaft.

Falls du einen konkreten Anwendungsfall hast, kann man dir vielleicht gezielter helfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das Hauptproblem liegt leider darin, dass ich von der Original Hardware keinen Schimmer habe.

Also weiss ich nicht, wann, wo in welchem Fall, welche Komponente einen Interrupt erzeugen soll / löschen soll.

Ausserdem besteht der Emulator, welchen ich bearbeite, aus 'Mischcode'.

Der Emulatorkern ist von 2002-2004 und seitdem kaum noch vom Originalautor überarbeitet worden.

Im Prinzip bügel ich nur die Fehler aus, und verbessere die Emulation so gut ich kann, hier & da.

Die "CPC Plus" Emulation ist dabei völliges Neuland für mich, und da adaptiere ich den Code, soweit ich ihn verstehe, von einem völlig anderen Emulator, welcher halt in C geschrieben wurde.

Selbstverständlich habe ich Erlaubnis von allen Seiten, den Code zu verwenden und zu ändern.

Der Rest basiert auf Trial- & Error...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror

Schreib einfach bei welchem konkreten C-Fragment du Probleme bei der Übersetzung zu Java hast. Bei dem Grundverständnis von dem, was du da tust kann dir wahrscheinlich nur jemand helfen, der in das Projekt involviert ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...