cool-bun-demo/system/system.s

434 lines
8.8 KiB
ArmAsm

XDEF _takeOverSystem
XDEF _giveBackSystem
XDEF _initializeCopperlist
XDEF _setUpDisplay
XDEF _setUpEmptySpritesInCopperlist
XDEF _addDisplayToCopperlist
XDEF _updateDisplayInCopperList
XDEF _addColorsToCopperlist
XDEF _endCopperlist
XDEF _myWaitBlit
XDEF _WaitBOF
XREF _custom
FUNC_CNT SET -30
FUNCDEF MACRO
_LVO\1 EQU FUNC_CNT
FUNC_CNT SET FUNC_CNT-6
ENDM
INCDIR "include_i_39:"
INCDIR "extra_lvos_39:"
INCLUDE "exec/exec_lib.i"
INCLUDE "exec/types.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/libraries.i" # get the CALLLIB macro
INCLUDE "graphics/gfxbase.i"
INCLUDE "graphics_lvo.i"
INCLUDE "hardware/custom.i"
INCLUDE "hardware/dmabits.i"
INCLUDE "hardware/intbits.i"
; @param 1 Pointer to null terminated name of library
; @param 2 Minimum version of library, 0 for any
; @outreg D0 pointer to library in memory
OpenLibrary MACRO
MOVE.L 4,A6
MOVEM.L A1,-(SP)
MOVE.L \1,A1
MOVE.L \2,D0
CALLLIB _LVOOpenLibrary
MOVEM.L (SP)+,A1
ENDM
PreserveRegister MACRO
MOVE.L D0,-(SP)
LEA _custom,A0
MOVE.W \1r(A0),D0
OR.W #$8000,D0
MOVE.W D0,Old\1
MOVE.L (SP)+,D0
ENDM
RestoreRegister MACRO
MOVE.W #$7FFF,\1(A0)
MOVE.W Old\1,\1(A0)
ENDM
STRUCTURE ScreenSetup,0
UWORD ScreenSetup_width
UWORD ScreenSetup_height
UWORD ScreenSetup_bitplanes
ULONG ScreenSetup_memoryStart
UWORD ScreenSetup_byteWidth
UWORD ScreenSetup_nextBitplaneAdvance
UWORD ScreenSetup_nextBufferAdvance
ULONG ScreenSetup_copperlistBitplanePointers
LABEL ScreenSetup_SIZEOF
STRUCTURE CurrentScreen,0
UWORD CurrentScreen_currentBuffer
CurrentScreen_planes EQU SOFFSET
SOFFSET SET SOFFSET+(8*4)
LABEL CurrentScreen_SIZEOF
BPLCON0_COLOR EQU $200
M68K_LEVEL3_INTERRUPT_AUTOVECTOR EQU $6C
_takeOverSystem:
MOVEM.L A2/A6,-(SP)
OpenLibrary #GraphicsLibrary,#0
MOVE.L D0,GraphicsBase
MOVE.L $4,A6
CALLLIB _LVOForbid
MOVE.L D0,A6
MOVE.L gb_ActiView(A6),OldView
MOVE.L gb_copinit(A6),OldCopper
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
LEA _custom,A0
PreserveRegister dmacon
PreserveRegister intena
PreserveRegister intreq
PreserveRegister adkcon
MOVE.L #0,A1
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
LEA _custom,A0
; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0036.html
MOVE.W #$7FFF,intena(A0) ; disable all interrupts
; we need VERTB to use WaitTOF
MOVE.W #INTF_SETCLR|INTF_INTEN|INTF_COPER|INTF_VERTB,intena(A0) ; enable master interrupt, copper, and VBR
MOVE.W #$7FFF,dmacon(a0)
MOVE.W #DMAF_SETCLR|DMAF_MASTER|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A0)
MOVEM.L (SP)+,A2/A6
RTS
; @outreg D0 pointer to VBR
GetVBR:
MOVE.L A5,-(SP)
MOVEQ #0,D0
MOVE.L $4,A6
BTST #0,AttnFlags+1(A6)
BEQ.B .zIs68K
LEA Get68010VBR(pc),A5
CALLLIB _LVOSupervisor
.zIs68K:
MOVE.L (SP)+,A5
RTS
Get68010VBR:
DC.L $4E7A0801
RTE
NewLevel3VBI:
MOVEM.L D0-A6,-(SP)
MOVE.L VBIPtr,D0
BEQ.B .noVBI
MOVE.L D0,A0
JSR (A0)
.noVBI:
LEA _custom,A6
LEA intreq(A6),A6
MOVEQ #$20,D0
MOVE.W D0,(A6)
MOVE.W D0,(A6) ; there is a bug in the 4000?
MOVEM.L (SP)+,D0-A6
RTE
_giveBackSystem:
MOVE.L A6,-(SP)
LEA _custom,A0
RestoreRegister dmacon
RestoreRegister intena
RestoreRegister intreq
RestoreRegister adkcon
MOVE.L OldCopper,cop1lc(A0)
MOVE.L GraphicsBase,A6
MOVE.L OldView,A1
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitBlit
CALLLIB _LVODisownBlitter
MOVE.L $4,A6
CALLLIB _LVOPermit
MOVE.L (SP)+,A6
RTS
; @stack *copperlist Pointer to copperlist
_initializeCopperlist:
MOVE.L 4(A7),A0
MOVE.L #$FFFFFFFE,(A0)
RTS
; @stack *copperlist Pointer to copperlist
; @stack ScreenSetup Pointer to screenSetup struct
; @stack CurrentScreen Pointer to currentScreen struct
; @stack copperlistBitplanePointers Pointer to bitplane pointers within the copper list [[high, low], ...]
STRUCTURE updateDisplayInCopperList,4
ULONG updateDisplayInCopperList_screenSetup
ULONG updateDisplayInCopperList_currentScreen
ULONG updateDisplayInCopperList_copperlistBitplanePointers
_updateDisplayInCopperList:
MOVE.L updateDisplayInCopperList_screenSetup(A7),A0
MOVE.L updateDisplayInCopperList_currentScreen(A7),A1
MOVE.L updateDisplayInCopperList_copperlistBitplanePointers(A7),D0
MOVEM.L A2-A3/D2,-(SP)
MOVE.L D0,A2
; a2 has copperlistBitplanePointers
MOVE.W ScreenSetup_bitplanes(A0),D1
SUBQ #1,D1
LEA CurrentScreen_planes(A1),A1
; a1 has planes
.continue:
MOVE.L (A1)+,D2
; d2 has bitplane pointer
MOVE.L (A2)+,A3
; a3 has high copperlist bitplane pointer
SWAP D2
MOVE.W D2,(A3)
MOVE.L (A2)+,A3
; a3 has low copperlist bitplane pointer
SWAP D2
MOVE.W D2,(A3)
DBRA D1,.continue
MOVEM.L (SP)+,A2-A3/D2
RTS
; Populate all 8 sprite pointers with the
; address to an empty sprite.
;
; @stack *copperlist Pointer to copperlist
; @outreg D0 Current pointer to copperlist
_setUpEmptySpritesInCopperlist:
MOVE.L 4(A7),A1
MOVE.L D2,-(SP)
MOVEQ #7,D0
MOVEQ #0,D1
MOVE.W #sprpt,D1
LEA EmptySprite,A0
MOVE.L A0,D2
.spritewrite:
SWAP D2
MOVE.W D1,(A1)+
MOVE.W D2,(A1)+
ADDQ #2,D1
SWAP D2
MOVE.W D1,(A1)+
MOVE.W D2,(A1)+
ADDQ #2,D1
DBRA D0,.spritewrite
MOVE.L (SP)+,D2
MOVE.L A1,D0
RTS
; @stack *copperlist Pointer to copperlist
; @stack ScreenSetup Pointer to screenSetup struct
; @stack CurrentScreen Pointer to currentScreen struct
; @stack copperlistBitplanePointers Pointer to currentScreen struct
STRUCTURE AddDisplayToCopperListParams,4
ULONG AddDisplayToCopperListParams_copperlistPtr
ULONG AddDisplayToCopperListParams_screenSetupPtr
ULONG AddDisplayToCopperListParams_currentScreenPtr
ULONG AddDisplayToCopperListParams_copperlistBitplanePointersPtr
_addDisplayToCopperlist:
MOVE.L A7,A0
; A2,D2,D3
MOVEM.L A2-A4/D2-D4,-(SP)
MOVE.L AddDisplayToCopperListParams_copperlistPtr(A0),A1 ; copperlist
MOVE.L AddDisplayToCopperListParams_screenSetupPtr(A0),A2 ; screenSetup
MOVE.L AddDisplayToCopperListParams_currentScreenPtr(A0),A3 ; currentScreen
MOVE.L AddDisplayToCopperListParams_copperlistBitplanePointersPtr(A0),A4 ; copperlistBitplanePointers
LEA CurrentScreen_planes(A3),A3
; a3 contains address to planes
MOVEQ #0,D0
MOVE.W ScreenSetup_bitplanes(A2),D0
; d0 is num of bitplanes
; set up bplpt
MOVEQ #0,D1
ADD.W #bplpt,D1
; d1 contains bltpt
MOVEQ #0,D4
.continue:
; get plane to split up
MOVE.L (A3)+,D3
; high byte
SWAP D3
MOVE.W D1,(A1)+
; get this position for later updating
MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
; low byte
SWAP D3
ADDQ #2,D1
MOVE.W D1,(A1)+
; get this position for later updating
MOVE.L A1,(A4)+
MOVE.W D3,(A1)+
ADDQ #2,D1
ADDQ #1,D4
CMP D4,D0
BNE .continue
; current copperlist position
MOVE.L A1,D0
MOVEM.L (SP)+,A2-A4/D2-D4
RTS
; @stack *copperlist
; @stack *colors
; @stack count
_addColorsToCopperlist:
MOVE.L 4(A7),A0 ; copperlist
MOVE.L 8(A7),A1 ; colors
MOVE.L 12(A7),D0 ; count
MOVEM.L A2/D2,-(SP)
LEA _custom,A2
MOVE.L #color,D2
ADD.L D2,A2
SUBQ #1,D0
.continue:
MOVE.W (A1)+,(A2)+
DBRA D0,.continue
MOVE.L A2,D0
MOVEM.L (SP)+,A2/D2
RTS
; @stack *copperlist
_endCopperlist:
MOVE.L 4(A7),A0
MOVE.W #$ffff,(A0)+
MOVE.W #$fffe,(A0)+
MOVE.L A0,D0
RTS
; @stack bitplaneCount
_setUpDisplay:
MOVE.L D2,-(SP)
MOVE.L 8(A7),D2
LEA _custom,A1
MOVEQ #0,D0
MOVE.W #BPLCON0_COLOR,D0
MOVEQ #0,D1
MOVE.W D2,D1
AND.W #$7,D1
ROL.W #8,D1
ROL.W #4,D1
ADD.W D1,D0
MOVE.W D0,bplcon0(A1)
MOVE.W #0,bplcon1(A1)
MOVE.W #0,bplcon2(A1)
MOVE.W #0,bpl1mod(A1)
MOVE.W #0,bpl2mod(A1)
MOVE.W #$2c81,diwstrt(A1)
; pal trick
MOVE.W #$f4c1,diwstop(A1)
MOVE.W #$38c1,diwstop(A1)
MOVE.W #$0038,ddfstrt(A1)
MOVE.W #$00d0,ddfstop(A1)
MOVE.L (SP)+,D2
RTS
_myWaitBlit:
LEA _custom,A0
BTST.B #DMAB_BLTDONE-8,dmaconr(A0)
BTST.B #DMAB_BLTDONE-8,dmaconr(A0)
BEQ .done
.loop:
BTST.B #DMAB_BLTDONE-8,dmaconr(A0)
BNE .loop
.done:
RTS
_WaitBOF:
MOVE.W 4(A7),D1
ROL.L #8,D1
MOVE.L $dff004,D0
AND.L #$1ff00,D0
CMP.L D1,D0
BNE.B _WaitBOF
.loop2:
MOVE.L $dff004,D0
AND.L #$1ff00,D0
CMP.L D1,D0
BEQ.B .loop2
RTS
CNOP 0,4
GraphicsBase dc.l 0
; old graphics stuff
OldView dc.l 0
OldCopper dc.l 0
; old registers
Olddmacon dc.w 0
Oldintena dc.w 0
Oldintreq dc.w 0
Oldadkcon dc.w 0
; vertical blank interrupt and the vector base register
OldLevel3VBI dc.l 0
VBRPtr dc.l 0
; you can set this to your own interrupt
VBIPtr dc.l 0
CNOP 0,4
GraphicsLibrary GRAPHICSNAME
SECTION Sprite,Data_C
EmptySprite dc.w 0,0