#ifndef COMPILE_H
#include "COMPILE.H"
#endif
#ifdef MEDIA442_A20E_A21E
void F0936_LaunchProcess();
void F0937_InitAmigaData();
void F0938_CallCloseWorkbench();
void F0940_CopyCopperInstructions();
void F0508_AMIGA_BuildPaletteChangeCopperList();
void F0942_InitDiskResource();
void F0943_ReleaseDiskResource();
void F0944_();
void F0945_InitAudioData();
void F0946_ReleaseAudioData();
void F0947_InitDiskData();
void F0948_ReleaseDiskData();

AMIGA_DATA* G0734_ps_AmigaData = NULL;
struct ExecMessage* G0723_ps_ExecMessage = NULL;
char* G0724_pc_swoosh = "DungeonMaster:swoosh";
char* G0725_pc_dm = "DungeonMaster:dm";
char G0726_ac_ProcessName[] = "Dungeon Master";
BOOLEAN G0727_B_ = C0_FALSE;
unsigned int16_t G0728_aui_Palette_Black[32] = { 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 };
UBYTE G0730_uc_AudioChannelsAllocation = 0x0F;
unsigned int16_t* G0731_pui_Palette_FadeFrom;
char G0732_ac_Unreferenced[32];
struct GfxBase* GfxBase;
BPTR DOSBase;
struct Message* G0733_ps_Msg; /* BUGX_XX: allocated memory is never freed */
long _savsp;
long _stkbase;
struct IntuitionBase* IntuitionBase;


void main(
)
{
        GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0L);
        if (GfxBase == NULL) {
                Alert(0x80444D20, 0L);
        }
        G0734_ps_AmigaData = AllocMem((long)sizeof(AMIGA_DATA), MEMF_PUBLIC | MEMF_CLEAR);
        G0723_ps_ExecMessage = AllocMem((long)sizeof(struct ExecMessage), MEMF_PUBLIC | MEMF_CLEAR);
        if ((G0734_ps_AmigaData == NULL) || (G0723_ps_ExecMessage == NULL)) {
                Alert(0x80444D21, 0L);
        }
        DOSBase = (BPTR)OpenLibrary("dos.library", 0L);
        if (DOSBase == NULL) {
                Alert(0x80444D22, 0L);
        }
        G0723_ps_ExecMessage->AmigaData = G0734_ps_AmigaData;
        G0723_ps_ExecMessage->DOSBase = DOSBase;
        G0723_ps_ExecMessage->sm_Message.mn_ReplyPort = &((struct Process*)FindTask(0L))->pr_MsgPort;
        F0937_InitAmigaData();
        F0936_LaunchProcess(G0724_pc_swoosh, 1);
        F0936_LaunchProcess(G0725_pc_dm, 1);
        if (G0723_ps_ExecMessage) {
                FreeMem(G0723_ps_ExecMessage, (long)sizeof(struct ExecMessage));
        }
        if (G0734_ps_AmigaData) {
                FreeMem(G0734_ps_AmigaData, (long)sizeof(AMIGA_DATA));
        }
}

void F0936_LaunchProcess(P0993_pc_Name, P0994_B_WaitProcessCompletion)
REGISTER char* P0993_pc_Name;
BOOLEAN P0994_B_WaitProcessCompletion;
{
        REGISTER struct Segment* L1762_ps_SegList;
        REGISTER struct Process* L1763_ps_Process;


        L1762_ps_SegList = LoadSeg(P0993_pc_Name);
        L1763_ps_Process = CreateProc(P0993_pc_Name, 0L, L1762_ps_SegList, 8000L);
        PutMsg(L1763_ps_Process, G0723_ps_ExecMessage);
        if (P0994_B_WaitProcessCompletion) {
                WaitPort(G0723_ps_ExecMessage->sm_Message.mn_ReplyPort);
                GetMsg(G0723_ps_ExecMessage->sm_Message.mn_ReplyPort);
                UnLoadSeg(L1762_ps_SegList);
        }
}

_main() /* do_detach */
{
        REGISTER struct Process* pp;
        struct Process* _FindTask();
        void* _GetMsg();
        void* _AllocMem();
        REGISTER long* lp;
        REGISTER unsigned short c;
        REGISTER long l;
        REGISTER long* sav;
        REGISTER struct CommandLineInterface* cli;
        long L1764_Unreferenced;
        struct MemList* mm;


        pp = (struct Process*)_FindTask(0L);
        if (pp->pr_CLI) {
                _stkbase = _savsp - *((long*)_savsp+1) + 8;
                *(long*)_stkbase = 0x4d414e58L;
                cli = (struct CommandLineInterface*)((long)pp->pr_CLI << 2);
                G0733_ps_Msg = _AllocMem((long)sizeof(struct Message), MEMF_PUBLIC);
                if (G0733_ps_Msg == NULL) {
                        Alert(AG_NoMemory, 0L);
                        _exit(0);
                }
                l = cli->cli_Module;
                cli->cli_Module = 0;
                _Forbid();
                pp = CreateProc(&G0726_ac_ProcessName, 0L, l, 4000L);
                PutMsg(pp, G0733_ps_Msg);
#asm
                moveq   #0,d0
                move.l        __savsp,sp                ;get back original stack pointer
                rts                                                ;and exit
#endasm
        } else {
                _WaitPort(&pp->pr_MsgPort);
                G0733_ps_Msg = _GetMsg(&pp->pr_MsgPort);
                lp = (long*)((long)pp->pr_SegList << 2);
                lp = (long*)(lp[3] << 2);
                sav = lp;
                for (c = 0; lp; c++) {
                        lp = (long*)(*lp << 2);
                }
                mm = _AllocMem((long)sizeof(struct MemList) + (c - 1) * sizeof(struct MemEntry), MEMF_PUBLIC);
                lp = sav;
                mm->ml_NumEntries = c;
                for (c = 0; lp; c++) {
                        mm->ml_me[c].me_Addr = (APTR)lp - 1;
                        mm->ml_me[c].me_Length = lp[-1];
                        lp = (long*)(*lp << 2);
                }
                AddTail(&pp->pr_Task.tc_MemEntry, mm);
                main();
                _exit(0);
        }
}

_exit(code)
{
        long ret = code;


        #asm
                mc68881
                move.l        4,a6                                ;get ExecBase
                btst.b        #4,$129(a6)                        ;check for 68881 flag in AttnFlags
                beq                1$                                        ;skip if not
                move.l        a5,-(sp)
                lea                2$,a5
                jsr                -30(a6)                                ;do it in supervisor mode
                move.l        (sp)+,a5
                bra                1$
2$
                clr.l        -(sp)
                frestore (sp)+                                ;reset the ffp stuff
                rte                                                        ;and return
1$
        #endasm
        if (DOSBase) {
                _CloseLibrary(DOSBase);
        }
        _Forbid();
        _ReplyMsg(G0733_ps_Msg);
        #asm
                        move.l        -4(a5),d0                ;pick up return exit code
                        move.l        __savsp#,sp                ;get back original stack pointer
                        rts                                                ;and exit
        #endasm
}

void F0937_InitAmigaData(
)
{
        struct Process* L1765_ps_Process;
        REGISTER int16_t L1766_i_Unreferenced;
        REGISTER long L1767_l_AvailableChipMemory;
        REGISTER long L1768_l_AvailableFastMemory;


        L1765_ps_Process = (struct Process*)FindTask(0L);
        L1765_ps_Process->pr_WindowPtr = -1;
        L1768_l_AvailableFastMemory = AvailMem(MEMF_FAST);
        L1767_l_AvailableChipMemory = AvailMem(MEMF_CHIP);
#ifdef MEDIA432_A20E
        if (L1768_l_AvailableFastMemory < 171000) { /* If not enough Fast RAM for main program (wrong test because actual program size is larger!) */
                if (L1767_l_AvailableChipMemory >= 471000) { /* If there is enough Chip RAM for both program and data */
                        G0734_ps_AmigaData->NotEnoughRAM = C0_FALSE;
                } else {
                        G0734_ps_AmigaData->NotEnoughRAM = C1_TRUE;
                }
        } else {
                L1768_l_AvailableFastMemory -= 171000;
                if ((L1767_l_AvailableChipMemory > 300000) || (L1768_l_AvailableFastMemory > 300000)) { /* If there is enough Chip RAM or Fast RAM for data */
                        G0734_ps_AmigaData->NotEnoughRAM = C0_FALSE;
                } else {
                        G0734_ps_AmigaData->NotEnoughRAM = C1_TRUE;
                }
        }
#endif
#ifdef MEDIA447_A21E /* New test: any Amiga with Fast RAM has enough memory for the game, unless there is less than 512 KB of chip RAM as on early models */
        if ((L1768_l_AvailableFastMemory == 0) && (L1767_l_AvailableChipMemory < 512000)) {
                G0734_ps_AmigaData->NotEnoughRAM = C1_TRUE;
        } else {
                G0734_ps_AmigaData->NotEnoughRAM = C0_FALSE;
        }
#endif
        F0938_CallCloseWorkbench();
        F0944_();
        GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0L);
        if (GfxBase == NULL) {
                Alert(0x80444D00, 0L);
        }
        G0734_ps_AmigaData->ScreenBuffer = AllocMem((long)M075_BITMAP_BYTE_COUNT(320, 200), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->ScreenBuffer == NULL) {
                Alert(0x80444D04, 0L);
        }
        G0734_ps_AmigaData->BlitterTemporaryBitplane = AllocMem((long)M091_BITPLANE_SIZE(320, 200), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->BlitterTemporaryBitplane == NULL) {
                Alert(0x80444D07, 0L);
        }
        G0734_ps_AmigaData->CopperList = AllocMem((long)sizeof(struct UCopList), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->CopperList == NULL) {
                Alert(0x80444D05, 0L);
        }
        G0734_ps_AmigaData->HatchBoxBitMap = AllocMem((long)sizeof(struct BitMap), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->HatchBoxBitMap == NULL) {
                Alert(0x80444D06, 0L);
        }
        G0734_ps_AmigaData->ScreenBitMap = AllocMem((long)sizeof(struct BitMap), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->ScreenBitMap == NULL) {
                Alert(0x80444D09, 0L);
        }
        InitBitMap(G0734_ps_AmigaData->ScreenBitMap, 4L, 320L, 200L); /* 320x200 pixels, 4 bits per pixel */
        G0734_ps_AmigaData->ScreenBitMap->Planes[0] = (PLANEPTR)G0734_ps_AmigaData->ScreenBuffer;
        G0734_ps_AmigaData->ScreenBitMap->Planes[1] = G0734_ps_AmigaData->ScreenBitMap->Planes[0] + M091_BITPLANE_SIZE(320, 200);
        G0734_ps_AmigaData->ScreenBitMap->Planes[2] = G0734_ps_AmigaData->ScreenBitMap->Planes[1] + M091_BITPLANE_SIZE(320, 200);
        G0734_ps_AmigaData->ScreenBitMap->Planes[3] = G0734_ps_AmigaData->ScreenBitMap->Planes[2] + M091_BITPLANE_SIZE(320, 200);
        G0734_ps_AmigaData->ViewBeforeGame = GfxBase->ActiView;
        InitView(&G0734_ps_AmigaData->GameView);
        InitVPort(&G0734_ps_AmigaData->ViewPort);
        InitRastPort(&G0734_ps_AmigaData->RastPort);
        G0734_ps_AmigaData->GameView.ViewPort = &G0734_ps_AmigaData->ViewPort;
        G0734_ps_AmigaData->RasInfo.BitMap = G0734_ps_AmigaData->ScreenBitMap;
        G0734_ps_AmigaData->RasInfo.RyOffset = 0;
        G0734_ps_AmigaData->RasInfo.RxOffset = 0;
        G0734_ps_AmigaData->RasInfo.Next = NULL;
        G0734_ps_AmigaData->ViewPort.DWidth = 320;
        G0734_ps_AmigaData->ViewPort.DHeight = 200;
        G0734_ps_AmigaData->ViewPort.RasInfo = &G0734_ps_AmigaData->RasInfo;
        G0734_ps_AmigaData->ViewPort.Modes = SPRITES;
        G0734_ps_AmigaData->ViewPort.ColorMap = NULL;
        G0734_ps_AmigaData->ViewPort.UCopIns = G0734_ps_AmigaData->CopperList;
        G0734_ps_AmigaData->RastPort.BitMap = G0734_ps_AmigaData->ScreenBitMap;
        MakeVPort(&G0734_ps_AmigaData->GameView, &G0734_ps_AmigaData->ViewPort);
        F0940_CopyCopperInstructions(&G0734_ps_AmigaData->ViewPort, 32L);
        F0508_AMIGA_BuildPaletteChangeCopperList(&G0728_aui_Palette_Black, &G0728_aui_Palette_Black);
        LoadView(&G0734_ps_AmigaData->GameView);
        SetDrMd(&G0734_ps_AmigaData->RastPort, JAM1);
        SetAPen(&G0734_ps_AmigaData->RastPort, 0L);
        SetBPen(&G0734_ps_AmigaData->RastPort, 0L);
        G0734_ps_AmigaData->RastPort.TmpRas = AllocMem((long)sizeof(struct TmpRas), MEMF_CHIP);
        if (G0734_ps_AmigaData->RastPort.TmpRas == NULL) {
                Alert(0x80444D0A, 0L);
        }
        InitTmpRas(G0734_ps_AmigaData->RastPort.TmpRas, G0734_ps_AmigaData->BlitterTemporaryBitplane, (long)M091_BITPLANE_SIZE(320, 200));
        F0947_InitDiskData();
        F0942_InitDiskResource();
        F0945_InitAudioData();
}

void F0938_CallCloseWorkbench(
)
{
        REGISTER int16_t L1769_i_Unreferenced;
        REGISTER int16_t L1770_i_Unreferenced;
        REGISTER char* L1771_pc_Unreferenced;


        IntuitionBase = (struct IntuitionBase*)OpenLibrary("intuition.library", 0L);
        if (IntuitionBase == NULL) {
                Alert(0x80444D01, 0L);
        }
        Delay(100L);
        if (!CloseWorkBench()) {
                Alert(0x80444D03, 0L);
        }
        CloseLibrary(IntuitionBase);
}

void F0939_ReleaseAmigaData(
)
{
        REGISTER int16_t L1772_i_Unreferenced;


        F0946_ReleaseAudioData();
        F0943_ReleaseDiskResource();
        F0948_ReleaseDiskData();
        if (G0734_ps_AmigaData->ViewBeforeGame) {
                LoadView(G0734_ps_AmigaData->ViewBeforeGame);
                M526_WaitVerticalBlank();
                FreeVPortCopLists(&G0734_ps_AmigaData->ViewPort);
                FreeCprList(G0734_ps_AmigaData->GameView.LOFCprList);
        }
        if (G0734_ps_AmigaData->ViewPort.ColorMap) {
                FreeColorMap(G0734_ps_AmigaData->ViewPort.ColorMap);
        }
        if (G0734_ps_AmigaData->ScreenBitMap) {
                FreeMem(G0734_ps_AmigaData->ScreenBitMap, (long)sizeof(struct BitMap));
        }
        if (G0734_ps_AmigaData->ScreenBuffer) {
                FreeMem(G0734_ps_AmigaData->ScreenBuffer, (long)M075_BITMAP_BYTE_COUNT(320, 200));
                if (G0734_ps_AmigaData->RastPort.TmpRas) {
                        FreeMem(G0734_ps_AmigaData->RastPort.TmpRas, (long)sizeof(struct TmpRas));
                }
        }
        if (G0734_ps_AmigaData->HatchBoxBitMap) {
                FreeMem(G0734_ps_AmigaData->HatchBoxBitMap, (long)sizeof(struct BitMap));
        }
        if (G0734_ps_AmigaData->BlitterTemporaryBitplane) {
                FreeMem(G0734_ps_AmigaData->BlitterTemporaryBitplane, (long)M091_BITPLANE_SIZE(320, 200));
        }
        if (GfxBase) {
                CloseLibrary(GfxBase);
        }
        exit(0);
}

void F0940_CopyCopperInstructions(P0995_ps_ViewPort, P0996_l_)
struct ViewPort* P0995_ps_ViewPort;
long P0996_l_;
{
        REGISTER int16_t L1773_i_;
        REGISTER struct CopIns* L1774_ps_;
        REGISTER struct CopIns* L1775_ps_;


        L1774_ps_ = P0995_ps_ViewPort->DspIns->CopIns + 1;
        L1775_ps_ = L1774_ps_ + P0996_l_;
        L1773_i_ = P0995_ps_ViewPort->DspIns->MaxCount - P0996_l_;
        P0995_ps_ViewPort->DspIns->MaxCount = L1773_i_;
        P0995_ps_ViewPort->DspIns->Count = L1773_i_;
        CopyMem(L1775_ps_, L1774_ps_, (long)((L1773_i_ - 1) * sizeof(struct CopIns)));
}

void F0508_AMIGA_BuildPaletteChangeCopperList(
P0940_pui_Palette_MiddleScreen, P0941_pui_Palette_TopAndBottomScreen) /* Build list of instructions for the copper to change the color palette while drawing the screen */
unsigned int16_t* P0940_pui_Palette_MiddleScreen       SEPARATOR
unsigned int16_t* P0941_pui_Palette_TopAndBottomScreen FINAL_SEPARATOR
{
        REGISTER int16_t L1682_i_ColorIndex;


        G0731_pui_Palette_FadeFrom = P0941_pui_Palette_TopAndBottomScreen;
        CINIT(G0734_ps_AmigaData->CopperList, 66L); /* 66 instructions maximum in copper list */
        for (L1682_i_ColorIndex = 0; L1682_i_ColorIndex < 16; L1682_i_ColorIndex++) {
                CMOVE(G0734_ps_AmigaData->CopperList, custom.color[L1682_i_ColorIndex], (long)P0941_pui_Palette_TopAndBottomScreen[L1682_i_ColorIndex]);
        }
        L1682_i_ColorIndex = 16;
        for (; L1682_i_ColorIndex < 32; L1682_i_ColorIndex++) {
                CMOVE(G0734_ps_AmigaData->CopperList, custom.color[L1682_i_ColorIndex], (long)G0728_aui_Palette_Black[L1682_i_ColorIndex - 16]);
        }
        CWAIT(G0734_ps_AmigaData->CopperList, 31L, 0L); /* When 31 lines have been drawn (champion status boxes on top of the screen), change palette */
        for (L1682_i_ColorIndex = 0; L1682_i_ColorIndex < 16; L1682_i_ColorIndex++) {
                CMOVE(G0734_ps_AmigaData->CopperList, custom.color[L1682_i_ColorIndex], (long)P0940_pui_Palette_MiddleScreen[L1682_i_ColorIndex]);
        }
        CWAIT(G0734_ps_AmigaData->CopperList, 170L, 0L); /* When 170 lines have been drawn (dungeon viewport), change palette */
        for (L1682_i_ColorIndex = 0; L1682_i_ColorIndex < 16; L1682_i_ColorIndex++) {
                CMOVE(G0734_ps_AmigaData->CopperList, custom.color[L1682_i_ColorIndex], (long)P0941_pui_Palette_TopAndBottomScreen[L1682_i_ColorIndex]);
        }
        CEND(G0734_ps_AmigaData->CopperList);
        MrgCop(&G0734_ps_AmigaData->GameView);
}

void F0942_InitDiskResource(
)
{
        G0734_ps_AmigaData->DiskResource = OpenResource("disk.resource");
        if (G0734_ps_AmigaData->DiskResource == NULL) {
                Alert(0x80444D0B, 0L);
        }
        G0734_ps_AmigaData->DiscResourceUnit = AllocMem((long)sizeof(struct DiscResourceUnit), MEMF_PUBLIC);
        if (G0734_ps_AmigaData->DiscResourceUnit == NULL) {
                Alert(0x80444D0C, 0L);
        }
        G0734_ps_AmigaData->DiscResourceUnitReplyPort = CreatePort(NULL, 0L);
        if (G0734_ps_AmigaData->DiscResourceUnitReplyPort == NULL) {
                Alert(0x80444D0D, 0L);
        }
        G0734_ps_AmigaData->DiscResourceUnit->dru_Message.mn_ReplyPort = G0734_ps_AmigaData->DiscResourceUnitReplyPort;
}

void F0943_ReleaseDiskResource(
)
{
        if (G0734_ps_AmigaData->DiscResourceUnitReplyPort) {
                DeletePort(G0734_ps_AmigaData->DiscResourceUnitReplyPort);
        }
        if (G0734_ps_AmigaData->DiscResourceUnit) {
                FreeMem(G0734_ps_AmigaData->DiscResourceUnit, (long)sizeof(struct DiscResourceUnit));
        }
}

void F0944_(
)
{
/* Hypothesis: this routine checks if some Exec functions have been replaced by checking if their entry point address is below 512 KB (in RAM instead of ROM) */
/* SetPatch replaced some ROM functions to fix issues. Not used on DM 2.x disk. Does it patch the functions below? Or is this part of copy protection to detect cracking attempt? */
        #asm
                        movea.l (4).w,a0        ; Exec
                        move.l  -$1C6(a0),d1    ; Address of DoIO() function
                        cmp.l   #$80000,d1      ; Compare address with 512 KB limit
                        blt.s   T0944000
                        move.l  -$1D8(a0),d1    ; Address of WaitIO() function
                        cmp.l   #$80000,d1      ; Compare address with 512 KB limit
                        blt.s   T0944000
                        move.l  -$1BA(a0),d1    ; Address of OpenDevice() function
                        cmp.l   #$80000,d1      ; Compare address with 512 KB limit
                        blt.s   T0944000
                        move.l  #0,_G0727_B_
                        bra.s   T0944001
                T0944000:
                        move.l  #1,_G0727_B_
                T0944001:
                public _G0727_B_
        #endasm
}

void F0945_InitAudioData(
)
{
        REGISTER long L1777_l_Error;
        REGISTER int16_t L1778_i_Unreferenced;


        G0734_ps_AmigaData->Sound1LeftChannel = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        G0734_ps_AmigaData->Sound1RightChannel = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        G0734_ps_AmigaData->Sound1Control = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        G0734_ps_AmigaData->Sound2LeftChannel = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        G0734_ps_AmigaData->Sound2RightChannel = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        G0734_ps_AmigaData->Sound2Control = AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR);
        if ((G0734_ps_AmigaData->Sound1LeftChannel == NULL) || (G0734_ps_AmigaData->Sound1RightChannel == NULL) || (G0734_ps_AmigaData->Sound1Control == NULL)) {
                Alert(0x80444D0E, 0L);
        }
        if ((G0734_ps_AmigaData->Sound2LeftChannel == NULL) || (G0734_ps_AmigaData->Sound2RightChannel == NULL) || (G0734_ps_AmigaData->Sound2Control == NULL)) {
                Alert(0x80444D0E, 0L);
        }
        L1777_l_Error = OpenDevice("audio.device", 0L, G0734_ps_AmigaData->Sound1Control, 0L);
        if (L1777_l_Error != 0) {
                Alert(0x80444D0F, 0L);
        }
        G0734_ps_AmigaData->AudioDevice = G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Device;
        G0734_ps_AmigaData->IOAudio1ReplyPort = CreatePort(NULL, 0L);
        G0734_ps_AmigaData->IOAudio2ReplyPort = CreatePort(NULL, 0L);
        G0734_ps_AmigaData->IOAudio3ReplyPort = CreatePort(NULL, 0L);
        if ((G0734_ps_AmigaData->IOAudio1ReplyPort == NULL) || (G0734_ps_AmigaData->IOAudio2ReplyPort == NULL) || (G0734_ps_AmigaData->IOAudio3ReplyPort == NULL)) {
                Alert(0x80444D10, 0L);
        }
        G0734_ps_AmigaData->IOAudio4ReplyPort = CreatePort(NULL, 0L);
        G0734_ps_AmigaData->IOAudio5ReplyPort = CreatePort(NULL, 0L);
        G0734_ps_AmigaData->IOAudio6ReplyPort = CreatePort(NULL, 0L);
        if ((G0734_ps_AmigaData->IOAudio4ReplyPort == NULL) || (G0734_ps_AmigaData->IOAudio5ReplyPort == NULL) || (G0734_ps_AmigaData->IOAudio6ReplyPort == NULL)) {
                Alert(0x80444D10, 0L);
        }
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Message.mn_ReplyPort = G0734_ps_AmigaData->IOAudio3ReplyPort;
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Message.mn_Node.ln_Pri = ADALLOC_MAXPREC;
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Command = ADCMD_ALLOCATE;
        G0734_ps_AmigaData->Sound1Control->ioa_Data = &G0730_uc_AudioChannelsAllocation; /* Value 0x0F = allocate all 4 channels (one bit per channel) */
        G0734_ps_AmigaData->Sound1Control->ioa_Length = sizeof(G0730_uc_AudioChannelsAllocation);
        L1777_l_Error = DoIO(G0734_ps_AmigaData->Sound1Control);
        if (L1777_l_Error != 0) {
                Alert(0x80444D11, 0L);
        }
        G0734_ps_AmigaData->AllocatedUnits = (long)G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Unit & 255;
        *G0734_ps_AmigaData->Sound1LeftChannel = *G0734_ps_AmigaData->Sound1Control;
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Command = ADCMD_FINISH;
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Flags = IOF_QUICK;
        G0734_ps_AmigaData->Sound1Control->ioa_Request.io_Unit = 4 | 8; /* Channel 2 & 3 */
        G0734_ps_AmigaData->Sound1LeftChannel->ioa_Request.io_Command = CMD_WRITE;
        G0734_ps_AmigaData->Sound1LeftChannel->ioa_Request.io_Flags = IOF_QUICK | ADIOF_PERVOL;
        G0734_ps_AmigaData->Sound1LeftChannel->ioa_Volume = 64;
        G0734_ps_AmigaData->Sound1LeftChannel->ioa_Cycles = 1;
        G0734_ps_AmigaData->Sound1LeftChannel->ioa_Request.io_Unit = 8; /* Channel 3 produce sound on left side */
        *G0734_ps_AmigaData->Sound1RightChannel = *G0734_ps_AmigaData->Sound1LeftChannel;
        G0734_ps_AmigaData->Sound1RightChannel->ioa_Request.io_Message.mn_ReplyPort = G0734_ps_AmigaData->IOAudio2ReplyPort;
        G0734_ps_AmigaData->Sound1RightChannel->ioa_Request.io_Unit = 4; /* Channel 2 produce sound on right side */
        *G0734_ps_AmigaData->Sound2Control = *G0734_ps_AmigaData->Sound1Control;
        G0734_ps_AmigaData->Sound2Control->ioa_Request.io_Unit = 1 | 2; /* Channel 0 & 1 */
        *G0734_ps_AmigaData->Sound2LeftChannel = *G0734_ps_AmigaData->Sound1LeftChannel;
        G0734_ps_AmigaData->Sound2LeftChannel->ioa_Request.io_Message.mn_ReplyPort = G0734_ps_AmigaData->IOAudio4ReplyPort;
        G0734_ps_AmigaData->Sound2LeftChannel->ioa_Request.io_Unit = 1; /* Channel 0 produce sound on left side */
        *G0734_ps_AmigaData->Sound2RightChannel = *G0734_ps_AmigaData->Sound1RightChannel;
        G0734_ps_AmigaData->Sound2RightChannel->ioa_Request.io_Message.mn_ReplyPort = G0734_ps_AmigaData->IOAudio5ReplyPort;
        G0734_ps_AmigaData->Sound2RightChannel->ioa_Request.io_Unit = 2; /* Channel 1 produce sound on right side */
        G0734_ps_AmigaData->PendingSound1Index = -1;
        G0734_ps_AmigaData->PendingSound2Index = -1;
}

void F0946_ReleaseAudioData(
)
{
        if (G0734_ps_AmigaData->AudioDevice) {
                CloseDevice(G0734_ps_AmigaData->Sound1Control);
        }
        if (G0734_ps_AmigaData->Sound1LeftChannel) {
                FreeMem(G0734_ps_AmigaData->Sound1LeftChannel, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->Sound1RightChannel) {
                FreeMem(G0734_ps_AmigaData->Sound1RightChannel, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->Sound1Control) {
                FreeMem(G0734_ps_AmigaData->Sound1Control, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->Sound2LeftChannel) {
                FreeMem(G0734_ps_AmigaData->Sound2LeftChannel, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->Sound2RightChannel) {
                FreeMem(G0734_ps_AmigaData->Sound2RightChannel, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->Sound2Control) {
                FreeMem(G0734_ps_AmigaData->Sound2Control, (long)sizeof(struct IOAudio));
        }
        if (G0734_ps_AmigaData->IOAudio1ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio1ReplyPort);
        }
        if (G0734_ps_AmigaData->IOAudio2ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio2ReplyPort);
        }
        if (G0734_ps_AmigaData->IOAudio3ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio3ReplyPort);
        }
        if (G0734_ps_AmigaData->IOAudio4ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio4ReplyPort);
        }
        if (G0734_ps_AmigaData->IOAudio5ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio5ReplyPort);
        }
        if (G0734_ps_AmigaData->IOAudio6ReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOAudio6ReplyPort);
        }
}

void F0947_InitDiskData(
)
{
        G0734_ps_AmigaData->TrackBuffer = AllocMem(TD_SECTOR * NUMSECS, MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->TrackBuffer == NULL) {
                Alert(0x80444DC0, 0L);
                F0939_ReleaseAmigaData();
        }
        G0734_ps_AmigaData->IOExtTD = AllocMem((long)sizeof(struct IOExtTD), MEMF_CHIP | MEMF_CLEAR);
        if (G0734_ps_AmigaData->IOExtTD == NULL) {
                Alert(0x80444DC1, 0L);
                F0939_ReleaseAmigaData();
        }
        G0734_ps_AmigaData->IOExtTDReplyPort = CreatePort(NULL, 0L);
        if (G0734_ps_AmigaData->IOExtTDReplyPort == NULL) {
                Alert(0x80444DC2, 0L);
                F0939_ReleaseAmigaData();
        }
        G0734_ps_AmigaData->IOExtTD->iotd_Req.io_Message.mn_ReplyPort = G0734_ps_AmigaData->IOExtTDReplyPort;
}

void F0948_ReleaseDiskData() /* Identical to F0518_FLOPPY_Deinitialize_CPSX */
{
        if (G0734_ps_AmigaData->IOExtTD) {
                FreeMem(G0734_ps_AmigaData->IOExtTD, (long)sizeof(struct IOExtTD));
        }
        if (G0734_ps_AmigaData->IOExtTDReplyPort) {
                DeletePort(G0734_ps_AmigaData->IOExtTDReplyPort);
        }
        if (G0734_ps_AmigaData->TrackBuffer) {
                FreeMem(G0734_ps_AmigaData->TrackBuffer, TD_SECTOR * NUMSECS);
        }
}
#endif
