*****************************************************************************
*          RESIDENT MODULE                                                  *
* Compiler: Devpac 3.04                                              ORHAN  *
*****************************************************************************
           MACHINE     MC68020
           INCLUDE     "exec/types.i"
           INCLUDE     "exec/execbase.i"
           INCLUDE     "exec/memory.i"
           INCLUDE     "exec/resident.i"
           INCLUDE     "graphics/gfx.i"
           INCLUDE     "hardware/cia.i"
           INCLUDE     "hardware/custom.i"
           INCLUDE     "hardware/intbits.i"
           INCLUDE     "hardware/dmabits.i"
           INCLUDE     "lvo/exec_lib.i"
*****************************************************************************
*          start                                                            *
*****************************************************************************
           SECTION     "CODE",CODE_C
           MOVE.L      ($4),A6
           MOVE.L      #ENDCODE-GOABS,D0
           MOVE.L      #MEMPTR,A1
           CALLSYS     AllocAbs
           TST.L       D0
           BEQ.S       EXIT

           LEA.L       GOABS,A0
           MOVE.L      #MEMPTR,A1
           MOVE.L      #ENDCODE-GOABS,D1
CPY:       MOVE.B      (A0)+,(A1)+
           SUB.L       #1,D1
           BNE         CPY

           JMP         (MEMPTR.L)
*****************************************************************************
*          exit                                                             *
*****************************************************************************
EXIT:      MOVE.L      #0,D0
           RTS
*****************************************************************************
*          set pseudo vector                                                *
*****************************************************************************
           CNOP        0,4
GOABS:
           CALLSYS     Disable
           BSR.S       SETKICK

           LEA.L       EXECLIB,A0
           MOVE.L      KickMemPtr(A6),KickMemPtr(A0)       
           MOVE.L      KickTagPtr(A6),KickTagPtr(A0)       
           MOVE.L      KickCheckSum(A6),KickCheckSum(A0)       
           MOVE.L      A0,($4)
           BSR         SETVEC
           BRA         RESET1
*****************************************************************************
*          initialize KickTagPtr, KickMemPtr to AllocABS module space       *
*****************************************************************************
SETKICK:
           MOVEM.L     D0-D7/A0-A6,-(SP)
           MOVE.L      ($4),A6
           LEA.L       ROMTAGPTR,A0
           LEA.L       ROMTAG,A1
           MOVE.L      A1,(A0)
           MOVE.L      A1,RT_MATCHTAG(A1)
           LEA.L       MODULE,A2
           ADD.L       #ENDCODE-MODULE,A2
           MOVE.L      A2,RT_ENDSKIP(A1)
           LEA.L       MODNAME,A2
           MOVE.L      A2,RT_NAME(A1)
           LEA.L       MODKICK,A2
           MOVE.L      A2,RT_INIT(A1)

           LEA.L       MODULE,A5
           LEA.L       MEMLIST,A1
           MOVE.L      A5,ML_ME+ME_ADDR(A1)

           LEA.L       ROMTAGPTR,A0          
           MOVE.L      A0,KickTagPtr(A6)
           LEA.L       MEMLIST,A0
           MOVE.L      A0,KickMemPtr(A6)
           CALLSYS     SumKickData
           MOVE.L      D0,KickCheckSum(A6)
           MOVEM.L     (SP)+,D0-D7/A0-A6
           RTS
*****************************************************************************
*          Cold Capture System Reset Vector module                          *
*****************************************************************************
MODULE:
           BSR.S       SETVEC
           TST.L       STARTFLAG
           BNE.S       EXITCOLD

           LEA.L       ($8),A0
           LEA.L       EXCEPTSTART1,A1
           MOVE.W      #46-1,D1
AA1:       MOVE.L      A1,(A0)+
           DBF         D1,AA1

           MOVE.L      #$ACABA,D0
           MOVE.L      #$BABA,D1
           MOVE.L      #$BACA,D2
           MOVE.L      #$DEDE,D3
           MOVE.L      #$BEBE,D4
           MOVE.L      #$ADA,D5
           MOVE.L      #$BADE,D6
           MOVE.L      #$CADDE,D7
           MOVE.L      #0,A0
           MOVE.L      #0,A1
           MOVE.L      #0,A2
           MOVE.L      #0,A3
           MOVE.L      #0,A4

           BSR         MONI

EXCEPTSTART1:
           MOVE.W      #$2700,SR
           LEA.L       STARTFLAG,A0
           MOVE.L      #1,(A0)
           MOVE.L      ($F80004.L),A0
           JMP         (A0)       
EXITCOLD:
           LEA.L       STARTFLAG,A0
           CLR.L       (A0)
           JMP         (A5)
*****************************************************************************
*          set system reset vectors address                                 *
*****************************************************************************
SETVEC:
           MOVEM.L     D0-D7/A0-A6,-(SP)
           MOVE.L      ($4),A6
           LEA.L       MODULE,A0
           MOVE.L      A0,ColdCapture(A6)

           MOVE.L      #-1,A0
           SUB.L       A6,A0
           MOVE.L      A0,ChkBase(A6)

           CLR.L       D1
           LEA.L       SoftVer(A6),A0
           MOVE.W      #((ChkSum-SoftVer)/2)-2,D0
ADDCHECK:  ADD.W       (A0)+,D1
           DBF         D0,ADDCHECK
           NOT.W       D1
           MOVE.W      D1,ChkSum(A6)

           MOVEM.L     (SP)+,D0-D7/A0-A6
           RTS
*****************************************************************************
*          software reset                                                   *
*****************************************************************************
RESET1:
           LEA.L       SUPMOD,A0
           MOVE.L      A0,($80)
           TRAP        #0
SUPMOD:    MOVE.W      #$2700,SR
           MOVE.L      ($F80004.L),A0
           SUB.L       #2,A0
           JMP         (A0)
*****************************************************************************
*          resident module                                                  *
*****************************************************************************
MODKICK:
           MOVEM.L     D0-D7/A0-A6,-(SP)
           BSR         SETVEC

           MOVE.L      ($4),A6
           CALLSYS     SuperState
           MOVE.L      D0,D7    
           CALLSYS     Disable

           LEA.L       EXCEPTSTART,A0
           LEA.L       EXVECTOR,A1
           MOVE.L      #256-1,D0
CPY1:      MOVE.L      A0,(A1)+
           DBF         D0,CPY1

           LEA.L       EXVECTOR,A0
           MOVEC       A0,VBR             ;change vector base

           CALLSYS     Enable
           MOVE.L      D7,D0
           CALLSYS     UserState
           MOVE.L      #0,D0

           MOVEM.L     (SP)+,D0-D7/A0-A6
           RTS
*****************************************************************************
*          exception routine                                                *
*****************************************************************************
EXCEPTSTART:
           CMP.B       #$68,7(SP)             ;if level 2
           BNE.S       EXITEXCEPT
           CMP.B       #$45,(CIAA+ciasdr.L)   ;see key '*'
           BNE.S       EXITEXCEPT

           MOVE.L      D0,-(SP)
           MOVE.L      #0,D0
           BSR.S       SHOWCOP
           BSR         MONI                   ;type "V adr"
           MOVE.L      (SP)+,D0
EXITEXCEPT:
           MOVE.L      4(SP),-(SP)
           AND.L       #$0FFF,(SP)
           MOVE.L      ([SP]),(SP)
           RTS
*****************************************************************************
*          show current copper list address                                 *
* D0= copper number in the chain,   ret: D0= adr or -1 if copper not found  *
*****************************************************************************
SHOWCOP:
           MOVEM.L     D1-D7/A0-A2,-(SP) 
           MOVE.L      D0,D5
           MOVE.L      #CUSTOM,A1
           LEA.L       SAVEINT,A0
           MOVE.W      intenar(A1),(A0)
           OR.W        #BITSET,(A0)
           LEA.L       SAVEDMA,A0
           MOVE.W      dmaconr(A1),(A0)
           OR.W        #BITSET,(A0)

           MOVE.W      dmaconr(A1),D0
           BTST.L      #DMAB_COPPER,D0                  ;check copper status
           BEQ         AA25

           BSR         WAITVB
           MOVE.W      #BITCLR|INTF_INTEN,intena(A1)                ;turn off ints
           MOVE.W      #BITCLR|DMAF_RASTER|DMAF_SPRITE,dmacon(A1)   ;disable display

           LEA.L       ($0),A0
           MOVE.L      #MEMPTR,D2
           MOVE.L      #$FFFFFFFE,D4
           MOVE.L      #copjmp1<<16+$0000,D6
           MOVE.L      #copjmp2<<16+$0000,D7
AA20:      MOVE.L      (A0),A2
           CMP.L       D4,A2
           BEQ.S       AA21
           CMP.L       D6,A2
           BEQ.S       AA21
           CMP.L       D7,A2
           BEQ.S       AA21
AA22:      ADD.L       #2,A0
           CMP.L       D2,A0
           BNE         AA20
           BRA         AA25
AA21:      CMP.L       D4,A2
           BEQ.S       AA37
           CMP.L       4(A0),D4
           BEQ         AA22
AA37:
           MOVE.L      -4(A0),D0
           MOVE.L      #dmacon<<16+BITCLR|DMAF_COPPER,-4(A0)    ;disable copper
           MOVE.L      D4,(A0)                   ;ensure copper wait

           MOVE.L      #2-1,D1                   ;for interlace
AA32:      BSR         WAITFR
           MOVE.W      dmaconr(A1),D3
           BTST.L      #DMAB_COPPER,D3           ;test copper dma
           BEQ.S       AA31
           DBF         D1,AA32

           MOVE.L      D0,-4(A0)
           MOVE.L      A2,(A0)
           BRA         AA22
AA31:
           MOVE.L      D0,-4(A0)
           MOVE.W      #BITSET|DMAF_COPPER,dmacon(A1)  ;enable copper
           BSR.S       WAITFR
           MOVE.L      A2,(A0)
           DBF         D5,AA22
AA26:
           SUB.L       #4,A0
           CMP.L       #0,A0
           BLT.S       AA25
           MOVE.L      (A0),D0
           SWAP.W      D0
           BTST.L      #0,D0
           BNE.S       AA28
           CMP.W       #cop1lc,D0
           BLO.S       AA28
           CMP.W       #copins,D0
           BLO         AA26
AA28:      SWAP.W      D0
           MOVE.W      #BITSET|INTF_VERTB,intena(A1)      ;enable vblank
           MOVE.L      #intena<<16+BITCLR|INTF_VERTB,(A0) ;disable vblank

           MOVE.L      #2-1,D1                  ;for interlace
AA19:      BSR.S       WAITFR
           MOVE.W      intenar(A1),D3
           BTST.L      #INTB_VERTB,D3           ;test vblank int
           BEQ.S       AA29
           DBF         D1,AA19

           MOVE.L      D0,(A0)
           BRA.S       AA30 
AA29:
           MOVE.L      D0,(A0)
           BRA         AA26
AA30:
           ADD.L       #4,A0
           MOVE.L      A0,D0
           BRA.S       AA27
AA25:
           MOVE.L      #-1,D0
AA27:
           BSR.S       WAITVB
           MOVE.W      #BITCLR|DMAF_RASTER|DMAF_SPRITE|DMAF_COPPER,dmacon(A1)
           MOVE.W      SAVEDMA,dmacon(A1)
           MOVE.W      #BITCLR|INTF_VERTB|INTF_INTEN,intena(A1)
           MOVE.W      SAVEINT,intena(A1)
           MOVEM.L     (SP)+,D1-D7/A0-A2
           RTS
*****************************************************************************
*          wait one frame                                                   *
*****************************************************************************
WAITFR:
           MOVEM.L     D0/D1/A0,-(SP)
           BCHG.B      #CIAB_LED,(CIAA+ciapra.L)   ;blink power led
           MOVE.L      #CUSTOM,A0
           MOVE.L      vposr(A0),D0
           LSR.L       #8,D0
           AND.W       #$07FF,D0
AA24:
           MOVE.L      vposr(A0),D1
           LSR.L       #8,D1
           AND.W       #$07FF,D1
           CMP.W       D0,D1
           BEQ         AA24

AA23:      MOVE.L      vposr(A0),D1
           LSR.L       #8,D1
           AND.W       #$07FF,D1
           CMP.W       D0,D1
           BNE         AA23
AA33:
           MOVE.L      vposr(A0),D1
           LSR.L       #8,D1
           AND.W       #$07FF,D1
           CMP.W       D0,D1
           BEQ         AA33
           MOVEM.L     (SP)+,D0/D1/A0
           RTS
*****************************************************************************
*          wait vertical blank                                              *
*****************************************************************************
WAITVB:
           MOVEM.L     D0/A0,-(SP)
           MOVE.L      #CUSTOM,A0
AA34:      MOVE.L      vposr(A0),D0
           LSR.L       #8,D0
           AND.W       #$07FF,D0
           BNE         AA34
           MOVEM.L     (SP)+,D0/A0
           RTS
*****************************************************************************
*          read palette                                                     *
*****************************************************************************
READPALET:
           MOVEM.L     D0/A0-A2,-(SP)
           MOVE.L      #CUSTOM,A0
           MOVE.W      #$0324,bplcon2(A0)    ;color=read

           LEA.L       color(A0),A2
           LEA.L       PALETTE,A1
           MOVE.L      #NUMCOLOR-1,D0
AA38:      MOVE.W      (A2)+,(A1)+           ;save colors
           DBF         D0,AA38
             
           MOVE.W      #$0224,bplcon2(A0)    ;color=write 
           MOVEM.L     (SP)+,D0/A0-A2
           RTS
*****************************************************************************
*          module data                                                      *
*****************************************************************************
ROMTAG:                                    ;STRUCTURE RT,0
           DC.W        RTC_MATCHWORD       ;UWORD RT_MATCHWORD
           DC.L        *-*                 ;APTR  RT_MATCHTAG
           DC.L        *-*                 ;APTR  RT_ENDSKIP
           DC.B        RTF_COLDSTART       ;UBYTE RT_FLAGS
           DC.B        1                   ;UBYTE RT_VERSION
           DC.B        0                   ;UBYTE RT_TYPE
           DC.B        127                 ;BYTE  RT_PRI
           DC.L        *-*                 ;APTR  RT_NAME
           DC.L        0                   ;APTR  RT_IDSTRING
           DC.L        *-*                 ;APTR  RT_INIT
                                           ;LABEL RT_SIZE

MEMLIST:
           DCB.B       LN_SIZE             ;STRUCTURE ML,LN_SIZE
           DC.W        1                   ;UWORD ML_NUMENTRIES
           DC.L        *-*                 ;LABEL ML_ME      (ME_ADDR)
           DC.L        ENDCODE-MODULE      ;                 (ME_LENGTH)
                                           ;LABEL ML_SIZE

CUSTOM     EQU         $DFF000
CIAA       EQU         $BFE001
CIAB       EQU         $BFD000
MEMPTR     EQU         $1E0000
NUMCOLOR   EQU         32
ROMTAGPTR  DC.L        *-*,0
STARTFLAG  DC.L        0
SAVEDMA    DC.W        0
SAVEINT    DC.W        0
PALETTE    DCB.W       NUMCOLOR
           CNOP        0,4
EXVECTOR   DCB.L       256
           DCB.B       1024
EXECLIB    DCB.B       SYSBASESIZE
MODNAME    DC.B        'module',0
           CNOP        0,4
MONI       INCBIN      "DH2:beermon/moni"
ENDCODE:   END
