Code:
;*****************
;* Constants *
;*****************
OldOpenLibrary = -$198 ; -408
CloseLibrary = -$19E ; -414
DMASET= %1000001010000000
; -----axbcdefghij
; a: Blitter Nasty
; x: DMA below on
; b: Bitplane DMA (if this isn't set, sprites disappear!)
; c: Copper DMA
; d: Blitter DMA
; e: Sprite DMA
; f: Disk DMA
; g-j: Audio 3-0 DMA
SECTION CODESECTION,CODE ; This command will run the below code
; on FAST RAM (if enough) or CHIP RAM
START:
MOVE.L $4.W,A6 ; Exec pointer to A6
LEA.L GfxName(PC),A1 ; Set library pointer to A1
MOVEQ #0,D0
JSR OldOpenLibrary(A6) ; Open graphics.library
; write to D0 the offset
MOVE.L D0,A1 ; Use Base-pointer
MOVE.L $26(A1),oldcop ; Store copperlist system address,
; retrieved $26 from glib offset
JSR CloseLibrary(A6) ; Close graphics library
move.w $dff01c,oldint ; save INTENAR
move.w $dff002,olddma ; save DMACONR
move.w #$7fff,$dff09a ; disable INTENA = turn off OS
move.w #$7fff,$dff09c ; disable INTREQ
move.w #$7fff,$dff09c ; twice -> amiga4000 hw bug!
move.w #$7fff,$dff096 ; disable DMACON
move.w #DMASET,$dff096 ; enable necessary bits in DMACON
move.l #COPPERLIST,$dff080 ; COP1LC - Point to #COPPERLIST
move.w d0,$dff088 ; COPJMP1 - Start COP
bsr Draw_Env_Before_FF ; BE AWARE! if RbVPos < $2d
; call Draw_Env_After_FF instead
Main:
move.l $dff004,d0 ; wait
and.l #$0001ff00,d0 ; for
cmp.l #303<<8,d0 ; rasterline 303
bne.s Main
bsr.s Movebar
.pause:
btst #10,$dff016 ; check for right mouse button
beq.s .pause ; pressed? pause!
btst #6,$bfe001 ; check for left mouse button
bne.s Main ; if not, repeat the above line
end:
move.w #$7fff,$dff096 ; clear DMACON
move.w olddma,d0
or.w #$8200,d0 ; set bits of DMACON state
move.w d0,$dff096 ; restore original DMACON
move.l oldcop,$dff080 ; restore original copperlist
move.w #0,$dff088 ; and activate it
move.w oldint,d0
or.w #$c000,d0 ; set bits of INTENAR state
move.w d0,$dff09a ; restore INTENA state = turn on OS
moveq #0,d0 ; nice clean
rts ; exit
GfxName:
dc.b "graphics.library",0,0
GfxBase: ; Dedicated to offset "graphics.library"
dc.l 0
OldCop: ; Dedicated to system COP address
dc.l 0
oldint:
dc.w 0 ; Dedicated to INTENA(R)
olddma:
dc.w 0 ; Dedicated to DMA
RbVPos:
; dc.b $26,$01 ; red bar h pos, v pos (always 0)
; dc.b $fe,$01
dc.b $2e,$01
; $2d - VERT TOP LIMIT PAL
; $ff -
; $2c - VERT BOTTOM LIMIT PAL
Movebar:
tst.b Direction_flag
beq.s Movebar_down
bne.s Movebar_up
SwitchDirection:
bchg #0,Direction_flag
rts
Movebar_down:
addq.b #1,RbVPos
cmpi.b #$28,RbVPos ; is bottom limit reached?
beq.s SwitchDirection ; bottom limit reached
; switch direction
cmpi.b #$ff,RbVPos
beq.w Draw_Env_After_FF
cmpi.b #$2d,RbVPos
bcs.s Draw_Bar_After_FF
bhi.w Draw_Bar_Before_FF
Draw_Bar_Before_FF:
lea redbar, a0
move.b RbVPos, (a0)
move.b RbVPos, d0
addq.b #1, d0
move.b d0, 8(a0)
rts
Draw_Bar_After_FF:
lea redbar, a0
move.b RbVPos, 4(a0)
move.b RbVPos, d0
addq.b #1, d0
move.b d0, 12(a0)
rts
Movebar_up:
subq.b #1,RbVPos
cmpi.b #$2c, RbVPos ; is top limit reached?
beq.s SwitchDirection ; top limit reached
; switch direction
cmpi.b #$ff,RbVPos
beq.s Draw_Env_Before_FF
cmpi.b #$2d,RbVPos
bcs.s Draw_Bar_After_FF
bhi.s Draw_Bar_Before_FF
rts
Direction_flag:
dc.b 0,0 ; direction flag
Draw_Env_Before_FF:
lea redbar, a0
move.l #$ff01ff00, (a0) ; redbar
move.l #$01800f00, 4(a0)
move.l #$0001ff00, 8(a0) ; redbar
move.l #$01800000, 12(a0)
move.l #$ffdffffe, 16(a0)
rts
Draw_Env_After_FF:
lea redbar, a0
move.l #$ffdffffe, (a0)
move.l #$ff01ff00, 4(a0) ; redbar
move.l #$01800f00, 8(a0)
move.l #$0001ff00, 12(a0) ; redbar
move.l #$01800000, 16(a0)
rts
SECTION GRAPHIC,DATA_C ; Section below MUST be executen on CHIP RAM,
; because COPPERLIST requires it
COPPERLIST:
dc.w $100, $200 ; BPLCON0 - THE BITLANE CONTROL
dc.w $180, $000 ; Color 0 - BLACK
dc.w $2c01,$ff00
dc.w $180, $0f0 ; Top screen green bar
dc.w $2d01,$ff00
dc.w $180, $000 ; Color 0 - BLACK
REDBAR:
dc.w 0,0
dc.w 0,0
dc.w 0,0
dc.w 0,0
dc.w 0,0
GREEN_BAR:
dc.w $2c01,$ff00
dc.w $180, $0f0 ; Bottom screen green bar
dc.w $2d01,$ff00
dc.w $180, $000 ; Color 0 - BLACK
END_COPPERLIST:
dc.w $FFFF,$FFFE ; END OF COPPERLIST
Basically I had to reduce call to copperlist (redbar) with drawing fixed values once when passing to $ff vertical position (see Draw_Env_Before_FF and Draw_Env_After_FF) and then call
directive ONLY for redbar position.