497 lines
11 KiB
ArmAsm
497 lines
11 KiB
ArmAsm
XDEF _takeOverSystem
|
|
XDEF _giveBackSystem
|
|
XDEF _initializeCopperlist
|
|
XDEF _setUpDisplay
|
|
XDEF _setUpEmptySpritesInCopperlist
|
|
XDEF _addDisplayToCopperlist
|
|
XDEF _updateDisplayInCopperList
|
|
XDEF _addColorsToCopperlist
|
|
XDEF _endCopperlist
|
|
XDEF _myWaitBlit
|
|
XDEF _WaitBOF
|
|
XDEF _stupidKeyboardHandler
|
|
|
|
XDEF _keyboardPressed
|
|
|
|
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"
|
|
INCLUDE "exec/io.i"
|
|
INCLUDE "devices/inputevent.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 ScreenDefinition,0
|
|
UWORD ScreenDefinition_width
|
|
UWORD ScreenDefinition_height
|
|
UWORD ScreenDefinition_bitplanes
|
|
ULONG ScreenDefinition_memoryStart
|
|
UWORD ScreenDefinition_byteWidth
|
|
UWORD ScreenDefinition_nextBitplaneAdvance
|
|
UWORD ScreenDefinition_nextBufferAdvance
|
|
ULONG ScreenDefinition_copperlistBitplanePointers
|
|
LABEL ScreenDefinition_SIZEOF
|
|
|
|
STRUCTURE ActiveScreenBufferDetails,0
|
|
UWORD ActiveScreenBufferDetails_currentBuffer
|
|
ActiveScreenBufferDetails_planes EQU SOFFSET
|
|
SOFFSET SET SOFFSET+(8*4)
|
|
LABEL ActiveScreenBufferDetails_SIZEOF
|
|
|
|
; @see https://amigadev.elowar.com/read/ADCD_2.1/Devices_Manual_guide/node019A.html
|
|
; @register A0 struct InputEvent *
|
|
; @register A1 extra data about the event
|
|
; @output D0 The value of A0
|
|
_stupidKeyboardHandler:
|
|
; @stack [RA,A0,current node]
|
|
MOVE.L A0,-(SP)
|
|
MOVE.L #0,-(SP)
|
|
|
|
_stupidKeyboardHandler_CheckLoop:
|
|
CMP.B #IECLASS_RAWKEY,ie_Class(A0)
|
|
BNE.S _stupidKeyboardHandler_NextEvent
|
|
|
|
MOVE.W ie_Code(A0),D0
|
|
AND.W #IECODE_UP_PREFIX,D0
|
|
SEQ _keyboardPressed
|
|
|
|
; if next_event:
|
|
; do the stack swap thing below
|
|
; else:
|
|
; change the A0 in the stack above it
|
|
TST.L (SP)
|
|
BNE.S _stupidKeyboardHandler_hasLastEvent
|
|
|
|
MOVE.L (A0),4(SP)
|
|
BRA.S _stupidKeyboardHandler_NextEvent
|
|
|
|
_stupidKeyboardHandler_hasLastEvent:
|
|
; put the next event in the first pointer of the
|
|
; last event
|
|
MOVE.L A1,-(SP)
|
|
MOVE.L 4(SP),A1
|
|
MOVE.L (A0),(A1)
|
|
MOVE.L (SP)+,A1
|
|
|
|
_stupidKeyboardHandler_NextEvent:
|
|
; next event is in first long of struct
|
|
MOVE.L (A0),D0
|
|
; store current node in stack
|
|
MOVE.L A0,(SP)
|
|
|
|
MOVE.L D0,A0
|
|
BNE.S _stupidKeyboardHandler_CheckLoop
|
|
MOVE.L (SP)+,D0
|
|
MOVE.L (SP)+,D0
|
|
RTS
|
|
|
|
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|DMAF_SPRITE,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 ScreenDefinition Pointer to screenSetup struct
|
|
; @stack ActiveScreenBufferDetails 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 ScreenDefinition_bitplanes(A0),D1
|
|
SUBQ #1,D1
|
|
LEA ActiveScreenBufferDetails_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 ScreenDefinition Pointer to screenDefinition struct
|
|
; @stack ActiveScreenBufferDetails Pointer to activeScreenBufferDetails struct
|
|
; @stack copperlistBitplanePointers Pointer to copperlistBitplanePointers struct
|
|
STRUCTURE AddDisplayToCopperListParams,4
|
|
ULONG AddDisplayToCopperListParams_copperlistPtr
|
|
ULONG AddDisplayToCopperListParams_screenDefinitionPtr
|
|
ULONG AddDisplayToCopperListParams_activeScreenBufferDetailsPtr
|
|
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_screenDefinitionPtr(A0),A2 ; screenDefinition
|
|
MOVE.L AddDisplayToCopperListParams_activeScreenBufferDetailsPtr(A0),A3 ; currentScreen
|
|
MOVE.L AddDisplayToCopperListParams_copperlistBitplanePointersPtr(A0),A4 ; copperlistBitplanePointers
|
|
|
|
LEA ActiveScreenBufferDetails_planes(A3),A3
|
|
; a3 contains address to planes
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W ScreenDefinition_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)+
|
|
ADDQ #2,D1
|
|
|
|
; low byte
|
|
SWAP D3
|
|
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
|
|
|
|
BPLCON0_ENABLE_COMPOSITE_COLOR EQU $200
|
|
|
|
; TODO: [ ] Create a stock display structure w/ all the default values in it
|
|
; that can be overridden, with guides/help on how to do so, then
|
|
; have this accept that structure
|
|
; @stack bitplaneCount
|
|
_setUpDisplay:
|
|
MOVE.L D2,-(SP)
|
|
MOVE.L 8(A7),D2 ; bitplaneCount
|
|
|
|
LEA _custom,A1
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W #BPLCON0_ENABLE_COMPOSITE_COLOR,D0
|
|
|
|
; move bitplane count to bits 12-14
|
|
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)
|
|
|
|
; this controls horizontal scroll. I'm not good enough
|
|
; yet to provide opinions on this.
|
|
MOVE.W #0,bplcon1(A1)
|
|
|
|
; sprites always on top for this demo
|
|
MOVE.W #$0020,bplcon2(A1)
|
|
|
|
; no modulos needed
|
|
MOVE.W #0,bpl1mod(A1)
|
|
MOVE.W #0,bpl2mod(A1)
|
|
|
|
; pal default
|
|
MOVE.W #$2c81,diwstrt(A1)
|
|
MOVE.W #$2cc1,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
|
|
|
|
CNOP 0,4
|
|
_keyboardPressed dc.l 0
|
|
|
|
SECTION Sprite,Data_C
|
|
EmptySprite dc.w 0,0
|