XDEF _takeOverSystem XDEF _giveBackSystem XDEF _initializeCopperlist XDEF _setUpDisplay XDEF _setUpEmptySpritesInCopperlist XDEF _addDisplayToCopperlist XDEF _updateDisplayInCopperList XDEF _addColorsToCopperlist XDEF _endCopperlist XDEF _myWaitBlit XDEF _WaitBOF XDEF _KeyboardHandler 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 _KeyboardHandler: ; @stack [RA,A0,current node] MOVE.L A0,-(SP) MOVE.L #0,-(SP) _KeyboardHandler_CheckLoop: CMP.B #IECLASS_RAWKEY,ie_Class(A0) BNE.S _KeyboardHandler_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 _KeyboardHandler_hasLastEvent MOVE.L (A0),4(SP) BRA.S _KeyboardHandler_NextEvent _KeyboardHandler_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 _KeyboardHandler_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 _KeyboardHandler_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 D0,A6 MOVE.L gb_ActiView(A6),OldView MOVE.L gb_copinit(A6),OldCopper MOVE.L #0,A1 CALLLIB _LVOLoadView CALLLIB _LVOWaitTOF CALLLIB _LVOWaitTOF CALLLIB _LVOOwnBlitter CALLLIB _LVOWaitBlit LEA _custom,A0 PreserveRegister dmacon PreserveRegister intena PreserveRegister intreq PreserveRegister adkcon ; 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 ; PORTS and EXTER give me access to the keyboard and mouse via OS interrupts MOVE.W #INTF_SETCLR|INTF_INTEN|INTF_COPER|INTF_PORTS|INTF_EXTER|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 (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