move.w #$4000,$dff09a ; INTENA - disable all interrupts move.w #$01a0,$dff096 ; DMACON - disable bitplane, copper, sprite lea.l screen(pc),a1 ; move address of screen into a1 lea.l bplcop+2(pc),a2 ; move address of plcop+2 into a2 ; set BPL1PTH / BPL1PTL in bplcop to screen move.l a1,d1 ; move screen pointer into d1 move.w d1,4(a2) ; move a word to set BPL1PTL in bplcop swap d1 ; swap words in the 32 bit register d1 move.w d1,(a2) ; move a word to set BPL1PTH in bplcop lea.l copper(pc),a1 ; move address of copper into a1 move.l a1,$dff080 ; move long copper address into COP1LCH / COP1LCL move.w #$8180,$dff096 ; DMACON - enable bitplane, copper bsr initlinedraw ; branch to subroutine initlinedraw main: ; label moveq #100,d0 ; first line pos x in d0 moveq #100,d1 ; first line pos y in d1 move.w $dff00a,d2 ; move value in JOY0DAT into d2 move.w d2,d3 ; move value in d2 into d3 andi.w #$ff,d2 ; second line pos is mouse x values in d2 lsr.w #8,d3 ; second line pos is mouse y values in d3 bsr.s linedraw ; branch to subroutine linedraw btst #6,$bfe001 ; test left mouse button bne.s main ; if not pressed goto main move.l 4.w,a6 ; make a6 point to ExecBase of exec.library move.l 156(a6),a6 ; IVBLIT points to GfxBase move.l 38(a6),$dff080 ; copinit ptr to copper start up list restore workbench copperlist move.w #$8020,$dff096 ; DMACON enable sprite rts ; return from subroutine ; Subroutine linedraw ; If both points are equal, then no line is drawn. ; Input: ; d0: x1 x-coordinate of first point ; d1: y1 y-coordinate of first point ; d2: x2 x-coordinate of second point ; d3: y2 y-coordinate of second point ; a0: pointer to the bitplane ; a1: pointer to the octant table ; a2: base address of the custom chip register $dff000 swid=40 ; screen width in bytes linedraw: ; subroutine linedraw cmp.w d0,d2 ; compare x1 and x2 bne.s ld_not1pix ; if x1 != x2 goto ld_not1pix cmp.w d1,d3 ; compare y1 and y2 bne.s ld_not1pix ; if y1 != y2 goto ld_not1pix rts ; return from subroutine ld_not1pix: ; label, both points of line is not the same pixel movem.l d4/d7/a3-a4,-(a7) ; push registers on the stack moveq #0,d7 ; clear octant index d7 sub.w d0,d2 ; store dx=x2-x1 in d2 bge.s ld_xok ; if dx>=0 goto ld_xok neg.w d2 ; store -dx in d2 addq.w #2,d7 ; add 2 to octant index d7 (dx < 0) ld_xok: ; label, dx is OK sub.w d1,d3 ; store dy=y2-y1 in d3 bge.s ld_yok ; if dy>=0 goto ld_yok neg.w d3 ; store -dy in d3 addq.w #4,d7 ; add 4 to octant index d7 (dy < 0) ld_yok: ; label, dy is OK cmp.w d3,d2 ; compare dy and dx bgt.s ld_xyok ; if dx > dy goto ld_xyok ; bne.s ld_not45 ; FIX: remove code ; add.w #16,d7 ; FIX: remove code ld_not45: ; Label line is not 45 degrees exg d2,d3 ; exchange dx and dy so that dx is largest addq.w #8,d7 ; add 8 to octant index d7 (dy > dx) ld_xyok: ; label, dx and dy is OK add.w d3,d3 ; 2dy to d3 move.w d3,d4 ; 2dy to d4 cmp.w d3,d2 ; FIX: compare d3=2dy with d2=dx bgt.s ld_sign_ok ; FIX: if dx > 2dy goto ld_sign_ok add.w #16,d7 ; FIX: no sign is needed 2dy - dx >= 0 ld_sign_ok: sub.w d2,d4 ; 2dy-dx to d4 add.w d3,d3 ; 4dy to d3 move.w d3,a3 ; 4dy to a3 add.w d2,d2 ; 2dx in d2 add.w d2,d2 ; 4dx in d2 sub.w d2,d3 ; 4dy - 4dx in d3 mulu #swid,d1 ; convert y1 coordinate to byte offset move.l a0,a4 ; Screen pointer to a4 add.w d1,a4 ; Screen + y1 to a4 move.w d0,d1 ; x1 to d1 lsr.w #3,d1 ; convert x1 coordinate to byte offset (x1/8) add.w d1,a4 ; Screen + y1 + x1 to a4. andi.w #$f,d0 ; d0 sets BLTCON0 / BLTCON1 Keep the first four bits of x1 ror.w #4,d0 ; Within a word rotate right 4 bits. add.w #$bca,d0 ; FIX: Add values to three lowest nibbles swap d0 ; Swap the words in d0 move.w (a1,d7.w),d0 ; move octant value at d7 into d0 lsl.w #4,d2 ; d2 sets BLTSIZE bit 15-6 holds dx add.w #$40,d2 ; FIX: bit 15-6 now holds dx + 1 addq.w #2,d2 ; bit 5-0 holds 2 ld_wldraw: btst #6,$2(a2) ; DMACONR test Blitter DMA enable bne.s ld_wldraw ; if not set then goto ld_wldraw move.l d0,$40(a2) ; BLTCON0 / BLTCON1 move.w d3,$64(a2) ; BLTAMOD move.w a3,$62(a2) ; BLTBMOD move.w d4,$52(a2) ; BLTAPTL move.l a4,$48(a2) ; BLTCPTH / BLTCPTL move.l a4,$54(a2) ; BLTDPTH / BLTDPTL move.w d2,$58(a2) ; BLTSIZE movem.l (a7)+,d4/d7/a3-a4 ; pop the stack into registers rts initlinedraw: ; subroutine initlinedraw lea.l screen(pc),a0 ; move address of screen into a0 lea.l octant(pc),a1 ; move screen of octant into a1 move.l #$dff000,a2 ; move value into a2 waitinit: ; label waitinit btst #6,$2(a2) ; DMACONR test Blitter DMA enable bne.s waitinit ; if not Blitter DMA enable goto waitinit move.l #-1,$44(a2) ; BLTAFWM / BLTALWM move.l #$ffff8000,$72(a2) ; BLTBDAT / BLTADAT move.w #swid,$60(a2) ; BLTCMOD move.w #swid,$66(a2) ; BLTDMOD rts ; return from subroutine octant: dc.w $0051,$0055,$0059,$005d dc.w $0041,$0049,$0045,$004d dc.w $0011,$0015,$0019,$001d dc.w $0001,$0009,$0005,$000d copper: dc.w $2001,$fffe ; wait for vpos >= $20 and hpos >= $0 dc.w $0102,$0000 ; set BPLCON1 (scroll) dc.w $0104,$0000 ; set BPLCON2 (video) dc.w $0108,$0000 ; BPL1MOD (odd bitplanes) dc.w $010a,$0000 ; BPL2MOD (even bitplanes) dc.w $008e,$2c81 ; DIWSTRT upper left corner at y/vpos = $2c, x = $81 dc.w $0090,$f4c1 ; DIWSTOP enable PAL trick dc.w $0090,$38c1 ; DIWSTOP lower right corner at y/vpos = $12c, x = $1c1 dc.w $0092,$0038 ; DDFSTRT data fetch start at vpos = DIWSTRT, hpos = $38 dc.w $0094,$00d0 ; DDFSTOP data fetch stop at vpos = DIWSTOP, hpos = $d0 dc.w $0180,$0000 ; COLOR00 set to black - background color dc.w $0182,$0ff0 ; COLOR01 set to yellow - foreground color dc.w $2c01,$fffe ; wait for vpos >= $2c and hpos >= $0 bplcop: dc.w $00e0,$0000 ; BPL1PTH (high bit 16-31) dc.w $00e2,$0000 ; BPL1PTL (low bit 0-15) dc.w $0100,$1200 ; BPLCON0 enable 1 bitplane, enable color burst dc.w $ffdf,$fffe ; wait for vpos >= $ff and hpos >= $de dc.w $2c01,$fffe ; wait for vpos >= $12c and hpos >= $0 (counter roll over) dc.w $0100,$0200 ; BPLCON0 disable bitplane - older PAL chips dc.w $ffff,$fffe ; wait for vpos >= $ff and hpos >= $fe ; wait indefinitely - until next vertical blanking screen: blk.w 5120,0 ; Allocate mem for a 320x256 screen