#ifndef COMPILE_H
#include "COMPILE.H"
#endif
#ifdef MEDIA081_S10EA_S10EB_S11E_S12E_S12G_S13FA_S13FB_S20E_S21E_G14ED_G20E_G21E_A20ED_A20E_A20F_A20G_A21E_A22E_A22G_A31E_A31M_A33M_A35E_A35M
#ifndef NOCOPYPROTECTION
#ifdef MEDIA007_S10EA_S10EB_S11E_S12E_S12G_S13FA_S13FB_S20E_S21E
overlay "start"
#endif
#ifdef MEDIA351_G14ED_G20E_G21E
segment "user"
#endif

#ifdef MEDIA137_S10EA_S10EB_S11E_S12E_S12G_S13FA_S13FB_S20E_S21E_A20ED_A20E_A20F_A20G_A21E_A22E_A22G
int16_t F0464_CPSC_GetChecksumSub(
P0870_pfv_Function)
void (*P0870_pfv_Function)() FINAL_SEPARATOR
{
#ifdef MEDIA007_S10EA_S10EB_S11E_S12E_S12G_S13FA_S13FB_S20E_S21E
        asm {
                        moveq   #27,D0
                        movea.l P0870_pfv_Function(A6),A1
                        move.l  #0x4E5E4E75,D2                  /* These are the bytes for instructions unlk A6 / rts which mark the end of the function */
                        moveq   #0,D1
                        cmpi.w  #0x4EF9,(A1)
                        bne.s   T0464001_Loop                   /* If A1 is not the address of a jmp instruction ($4EF9) from the jumptable */
                        movea.l 2(A1),A1                        /* Replace A1 by the target address of the jmp */
                T0464001_Loop:
                        sub.w   (A1)+,D0                        /* Substract words from start of the function */
                        addq.w  #1,D1
                        add.w   D1,D0
                        cmp.l   (A1),D2
                        bne.s   T0464001_Loop
        }
#endif
#ifdef MEDIA413_A20ED_A20E_A20F_A20G_A21E_A22E_A22G
        #asm
                        moveq   #27,D0
                        movea.l 8(A5),A1        ; P0870_pfv_Function
                        move.l  #$4E5D4E75,D2
                        moveq   #0,D1
                        cmpi.w  #$4EF9,(A1)
                        bne.s   T0464001_Loop
                        movea.l 2(A1),A1
                T0464001_Loop:
                        sub.w   (A1)+,D0
                        addq.w  #1,D1
                        add.w   D1,D0
                        cmp.l   (A1),D2
                        bne.s   T0464001_Loop
        #endasm
#endif
}
#endif
#ifdef MEDIA351_G14ED_G20E_G21E
int16_t F0464_CPSC_GetChecksumSub(
P0870_pfv_Function, P6048_pui_BytesToSkip)
unsigned char*    P0870_pfv_Function    SEPARATOR
unsigned int16_t* P6048_pui_BytesToSkip FINAL_SEPARATOR
{
        unsigned int16_t L6217_;
        unsigned int16_t L6218_ui_Checksum;
        unsigned int16_t L6219_;


        L6217_ = *P6048_pui_BytesToSkip++;
        L6219_ = 0;
        L6218_ui_Checksum = 27;
        do {
                if (*P6048_pui_BytesToSkip == L6219_) {
                        P6048_pui_BytesToSkip++;
                        L6219_ += *P6048_pui_BytesToSkip++;
                } else {
                        L6218_ui_Checksum -= P0870_pfv_Function[L6219_++];
                }
        } while (L6219_ < L6217_);
        return L6218_ui_Checksum;
}
#endif

#ifdef MEDIA626_A31E_A31M_A33M_A35E_A35M
void F1155_(
)
{
        return;
        asm {
                dc.b "JFLdH"            /* JFL: Initials of the programmer "Joseph F. Linhoff" (Joe Linhoff) */
                dc.b 0x14
                dc.b 0
                dc.b 3
                dc.b 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC           /* 20 bytes with value 0x0C */
        }
}

int16_t F1156_CPSC_GetChecksum(
void (*P2851_pfv_StartFunction)() SEPARATOR
void (*P2852_pfv_EndFunction)()   FINAL_SEPARATOR
{
        asm {
                        movea.l P2851_pfv_StartFunction(a6),a0
                        movea.l P2852_pfv_EndFunction(a6),a1
                        moveq   #0,d0
                        moveq   #0,d1
                        bra.s   @Tloc_1AC88
                @Tloc_1AC82:
                        add.b   (a0)+,d0
                        ror.w   #4,d0
                        addx.w  d1,d0
                @Tloc_1AC88:
                        cmpa.l  a1,a0
                        bcs.s   @Tloc_1AC82
        }
}
#endif

#ifdef MEDIA007_S10EA_S10EB_S11E_S12E_S12G_S13FA_S13FB_S20E_S21E
asm {
        S0465_CPSD_ReadSector247:
        S465Loop:
                tst.w   G0625_i_FloppyDriveDMATimeout_CPSDF(A4)
                bne.s   S465Loop
                moveq   #MASK0x0004_CPS_SECOND_SECTOR,D0
                or.w    D0,G0314_i_SectorsReadRequested_CPSDF(A4)
                move.l  A2,D3                                                   /* Backup A2 in D3 */
                clr.l   -(A7)
                move.w  #0x0020,-(A7)
                trap    #1                                                      /* Call GEMDOS function Super() */
                move.l  D0,2(A7)                                                /* Store result in the stack, in place of the long. The stack is not cleaned up as another identical call will be made later */
                tst.w   C0x043E_ADDRESS_SYSTEM_VARIABLE_flock                   /* Check if system variable flock is equal to 0. This variable must be non zero while using the DMA to prevent the OS from using DMA during vertical blank. This is required during all disk activity */
                bne.s   T0465001
                move.w  #1,C0x043E_ADDRESS_SYSTEM_VARIABLE_flock                /* Set flock system variable to 1 (non zero value) */
                move.w  #259,G0625_i_FloppyDriveDMATimeout_CPSDF(A4)            /* This is the maximum number of Vertical Blanks to wait before the read operation will time out */
                move.w  #C1_TRUE,G0624_B_FloppyDriveTurnedOn_CPSDF(A4)          /* This flag is checked in vertical blank to turn off the floppy drive when reading is complete */
                movea.w #0x8800,A1                                              /* This is the address of the Programmable Sound Generator (PSG, YM2149 sound chip) Read data/Register select */
                moveq   #0xF8,D2                                                /* This is used as bit mask 11111000 */
                move    SR,D0                                                   /* Backup Status Register in D0 */
                ori     #0x0700,SR                                              /* Set interrupt priority mask = 7. All interrupts <= 7 will now be ignored. This includes Horizontal Blank interrupts (level 2), Vertical Blank interrupts (level 4) and MFP interrupts (level 6) */
                move.b  #0x0E,(A1)                                              /* Write $0E to the PSG register select. This selects I/O port A */
                and.b   (A1),D2                                                 /* Read data from chip and apply binary mask in D2 to only keep bits 3 to 7 and clear bits 0 to 2 */
                ori.b   #0x05,D2                                                /* Enable bits 0 and 2 in D2 in order to turn on drive 0 and its light (but not the motor), and select side 0 */
                move.b  D2,2(A1)                                                /* Write D2 to the write address of the PSG */
                movea.w #0x8606,A1                                              /* Address of the DMA mode/status register */
                move.w  #0x0084,(A1)                                            /* Write mode $84 to the DMA mode/status register. Subsequent read/write from/to -2(A1) = $FFFF8604 will be directed to the FDC SECTOR register */
                moveq   #C247_SECTOR_247,D1                                     /* Sector count to read */
                bsr.s   T0465002_SendD1ToFDCRegister
                move.b  0x000D(A7),0xFFFF860D                                   /* Address of the DMA base and counter (Low byte)  (Buffer address where the sector will be read) */
                move.b  0x000C(A7),0xFFFF860B                                   /* Address of the DMA base and counter (Mid byte)  (Buffer address where the sector will be read) */
                move.b  0x000B(A7),0xFFFF8609                                   /* Address of the DMA base and counter (High byte) (Buffer address where the sector will be read) */
                move.w  #0x0090,(A1)                                            /* Write mode $90 to the DMA mode/status register. Set read mode (from DMA to memory) from the FDC. Subsequent write to -2(A1) = 0xFFFF8604 will be directed to the DMA internal sector count register */
                move.w  #0x0190,(A1)                                            /* Write mode $190 to the DMA mode/status register. Set write mode (from memory to DMA) from the FDC. Subsequent write to -2(A1) = 0xFFFF8604 will be directed to the DMA internal sector count register */
                move.w  #0x0090,(A1)                                            /* Write mode $90 to the DMA mode/status register. Set read mode (from DMA to memory) from the FDC. Subsequent write to -2(A1) = 0xFFFF8604 will be directed to the DMA internal sector count register. This sequence of operations (toggling the DMA mode) clears the DMA FIFO buffers and prepares for a read operation */
                move.w  #1,-2(A1)                                               /* Write sector count = 1 to the DMA to read one sector. This triggers the DMA transfer operation */
                move.w  #0x0080,D1                                              /* This value is written both to the DMA mode/status register on the next line and to the FDC CONTROL register below. In this last case, this represents command 0x80 sent to the FDC CONTROL register which triggers the 'Read Sector' command */
                move.w  D1,(A1)                                                 /* Write mode $80 to the DMA mode/status register. Subsequent read/write from/to -2(A1) = 0xFFFF8604 will be directed to the FDC STATUS/CONTROL register */
                bsr.s   T0465002_SendD1ToFDCRegister
                move    D0,SR                                                   /* Restore SR from D0. SR is the Status Register of the processor */
        T0465001:
                trap    #1                                                      /* Call GEMDOS function Super() again to go back to user mode */
                addq.l  #6,A7                                                   /* Cleanup stack */
                movea.l D3,A2                                                   /* Restore A2 from D3 */
                rts
        T0465002_SendD1ToFDCRegister:
                bsr.s   T0465003_Delay
                move.w  D1,-2(A1)                                               /* Write D1 to the currently selected FDC register */
        T0465003_Delay:
                moveq   #46,D2                                                  /* This loop is used to cause a delay during disk accesses */
        T0465004_Loop:
                subq.w  #1,D2
                bne.s   T0465004_Loop
                rts
}
#endif
#endif
#endif
