Welcome, Guest. Please login or register.

Author Topic: Assembler startup code + line draw (HELP)  (Read 4086 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline balrogsoftTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2006
  • Posts: 186
    • Show only replies by balrogsoft
    • http://www.amigaskoolnet
Assembler startup code + line draw (HELP)
« on: August 14, 2006, 04:35:29 PM »
Hi, i'm trying to learn assembler, i'm using DevPac 3.18, and i only get to work a few of examples, but i have a problem, i have a startup source with a draw line code, it works on my A600, but on my A1200 i got corrupted screen graphics, i got it to work on my A1200 if i remove DIWSTRT, DIWSTOP register data and DDFSTRT and DDFSTOP1 from copper list, but then the line isn't drawed.

Other question, a lot of examples don't work because DevPac don't recognise instruction BLK, is a specific assembler instruction? it can be switched with other instruction compatible with DevPac?

And the last question is about Blitter, to check if the blitter finished the operation, i test bit 6 on $DFF000 address, but i found that some codes test bit 14, and DevPac says that you can test bits 0-7. Why some codes use bit 14?

;************************************************
;*      Non-System Draw Line Example      *
;*    Made as help to demo and game creaters   *
;*                  *
;*  ASM-One example coded by Rune Gram-Madsen   *
;*                  *
;*   All rights reserved. Copyright (c) 1990   *
;************************************************

; Move the mouse around to draw a lot of lines.

;*****************
;*   Constants   *
;*****************

OldOpenLibrary   = -408
CloseLibrary   = -414

DMASET=   %1000000111000000
;    -----a-bcdefghij

;   a: Blitter Nasty
;   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

START:
   MOVEM.L   D0-D7/A0-A6,-(A7)   ; Put registers on stack

;***********************************
;*   CLOSE ALL SYSTEM INTERRUPTS   *
;*                                 *
;*      START DEMO INTERRUPTS      *
;***********************************

   MOVE.L   $4.W,A6         ; Exec pointer to A6
   LEA.L   GfxName(PC),A1      ; Set library pointer
   MOVEQ   #0,D0
   JSR   OldOpenLibrary(A6)   ; Open graphics.library
   MOVE.L   D0,A1         ; Use Base-pointer
   MOVE.L   $26(A1),OLDCOP1      ; Store copper1 start addr
   MOVE.L   $32(A1),OLDCOP2      ; Store copper1 start addr
   JSR   CloseLibrary(A6)   ; Close graphics library

   LEA   $DFF000,A6
   MOVE.W   $1C(A6),INTENA      ; Store old INTENA
   MOVE.W   $2(A6),DMACON      ; Store old DMACON
   MOVE.W   $10(A6),ADKCON      ; Store old ADKCON

   MOVE.W   #$7FFF,$9A(A6)      ; Clear interrupt enable

   BSR.L   Wait_Vert_Blank

   MOVE.W   #$7FFF,$96(A6)      ; Clear DMA channels
   MOVE.L   #COPLIST,$80(A6)   ; Copper1 start address
   MOVE.W   #DMASET!$8200,$96(A6)   ; DMA kontrol data
   MOVE.L   $6C.W,OldInter      ; Store old inter pointer
   MOVE.L   #INTER,$6C.W      ; Set interrupt pointer

   MOVE.W   #$7FFF,$9C(A6)      ; Clear request
   MOVE.W   #$C020,$9A(A6)      ; Interrupt enable

;****       Your main routine      ****


;**** Main Loop  Test mouse button ****

LOOP:
   BTST   #6,$BFE001      ; Test left mouse button
   BNE.S   LOOP

;*****************************************
;*                *
;*   RESTORE SYSTEM INTERRUPTS ECT ECT   *
;*                *
;*****************************************

   LEA   $DFF000,A6

   MOVE.W   #$7FFF,$9A(A6)      ; Disable interrupts

   BSR.S   Wait_Vert_Blank

   MOVE.W   #$7FFF,$96(A6)
   MOVE.L   OldCop1(PC),$80(A6)   ; Restore old copper1
   MOVE.L   OldCop2(PC),$84(A6)   ; Restore old copper1
   MOVE.L   OldInter(PC),$6C.W   ; Restore inter pointer
   MOVE.W   DMACON,D0      ; Restore old DMACON
   OR.W   #$8000,D0
   MOVE.W   D0,$96(A6)      
   MOVE.W   ADKCON,D0      ; Restore old ADKCON
   OR.W   #$8000,D0
   MOVE.W   D0,$9E(A6)
   MOVE.W   INTENA,D0      ; Restore inter data
   OR.W   #$C000,D0
   MOVE.W   #$7FFF,$9C(A6)
   MOVE.W   D0,$9A(A6)
   MOVEM.L   (A7)+,D0-D7/A0-A6   ; Get registers from stack
   RTS

;*** WAIT VERTICAL BLANK ***

Wait_Vert_Blank:
   BTST   #0,$5(A6)
   BEQ.S   Wait_Vert_Blank
.loop   BTST   #0,$5(A6)
   BNE.S   .loop
   RTS

;*** DATA AREA ***

GfxName      DC.B   'graphics.library',0
      even
DosBase      DC.L   0
OldInter   DC.L   0
OldCop1      DC.L   0
OldCop2      DC.L   0
INTENA      DC.W   0
DMACON      DC.W   0
ADKCON      DC.W   0

;**********************************
;*              *
;*    INTERRUPT ROUTINE. LEVEL 3  *
;*              *
;**********************************

INTER:
   MOVEM.L   D0-D7/A0-A6,-(A7)   ; Put registers on stack
   LEA.L   $DFF000,A6
   MOVE.L   #SCREEN,$E0(A6)

;---  Place your interrupt routine here  ---

   BSR.S   INITLINE   ; Init line registers

   MOVEQ   #0,D0      ; Start X - Y coords
   MOVEQ   #0,D1

   MOVEQ   #0,D3      ; End X - Y coords
   MOVEQ   #0,D2

   MOVE.W   $A(a6),D3   ; Get mouse position
   MOVE.B   D3,D2
   LSR.W   #8,D3

   BSR.S   DRAWLINE   ; Draw the line

   MOVE.W   #$4020,$9C(A6)      ; Clear interrupt request
   MOVEM.L   (A7)+,D0-D7/A0-A6   ; Get registers from stack
   RTE

;********************
;*  Init line draw  *
;********************

SINGLE = 0      ; 2 = SINGLE BIT WIDTH
BYTEWIDTH = 40

; The below registers only have to be set once each time
; you want to draw one or more lines.

INITLINE:
   LEA.L   $DFF000,A6

.WAIT:   BTST   #$6,$2(A6)
   BNE.S   .WAIT

   MOVEQ   #-1,D1
   MOVE.L   D1,$44(A6)      ; FirstLastMask
   MOVE.W   #$8000,$74(A6)      ; BLT data A
   MOVE.W   #BYTEWIDTH,$60(A6)   ; Tot.Screen Width
   MOVE.W   #$FFFF,$72(A6)
   LEA.L   SCREEN,A5
   RTS

;*****************
;*   DRAW LINE   *
;*****************

; USES D0/D1/D2/D3/D4/D7/A5/A6

DRAWLINE:
   SUB.W   D3,D1
   MULU   #40,D3      ; ScreenWidth * D3

   MOVEQ   #$F,D4
   AND.W   D2,D4      ; Get lowest bits from D2

;--------- SELECT OCTANT ---------

   SUB.W   D2,D0
   BLT.S   DRAW_DONT0146
   TST.W   D1
   BLT.S   DRAW_DONT04

   CMP.W   D0,D1
   BGE.S   DRAW_SELECT0
   MOVEQ   #$11+SINGLE,D7      ; Select Oct 4
   BRA.S   DRAW_OCTSELECTED
DRAW_SELECT0:
   MOVEQ   #1+SINGLE,D7      ; Select Oct 0
   EXG   D0,D1
   BRA.S   DRAW_OCTSELECTED

DRAW_DONT04:
   NEG.W   D1
   CMP.W   D0,D1
   BGE.S   DRAW_SELECT1
   MOVEQ   #$19+SINGLE,D7      ; Select Oct 6
   BRA.S   DRAW_OCTSELECTED
DRAW_SELECT1:
   MOVEQ   #5+SINGLE,D7      ; Select Oct 1
   EXG   D0,D1
   BRA.S   DRAW_OCTSELECTED


DRAW_DONT0146:
   NEG.W   D0
   TST.W   D1
   BLT.S   DRAW_DONT25
   CMP.W   D0,D1
   BGE.S   DRAW_SELECT2
   MOVEQ   #$15+SINGLE,D7      ; Select Oct 5
   BRA.S   DRAW_OCTSELECTED
DRAW_SELECT2:
   MOVEQ   #9+SINGLE,D7      ; Select Oct 2
   EXG   D0,D1
   BRA.S   DRAW_OCTSELECTED
DRAW_DONT25:
   NEG.W   D1
   CMP.W   D0,D1
   BGE.S   DRAW_SELECT3
   MOVEQ   #$1D+SINGLE,D7      ; Select Oct 7
   BRA.S   DRAW_OCTSELECTED
DRAW_SELECT3:
   MOVEQ   #$D+SINGLE,D7      ; Select Oct 3
   EXG   D0,D1

;---------   CALCULATE START   ---------

DRAW_OCTSELECTED:
   ADD.W   D1,D1         ; 2*dy
   ASR.W   #3,D2         ; x=x/8
   EXT.L   D2
   ADD.L   D2,D3         ; d3 = x+y*40 = screen pos
   MOVE.W   D1,D2         ; d2 = 2*dy
   SUB.W   D0,D2         ; d2 = 2*dy-dx
   BGE.S   DRAW_DONTSETSIGN
   ORI.W   #$40,D7         ; dx < 2*dy
DRAW_DONTSETSIGN:

;---------   SET BLITTER   ---------

.WAIT:
   BTST   #$6,$2(A6)      ; Wait on the blitter
   BNE.S   .WAIT

   MOVE.W   D2,$52(A6)      ; 2*dy-dx
   MOVE.W   D1,$62(A6)      ; 2*d2
   SUB.W   D0,D2         ; d2 = 2*dy-dx-dx
   MOVE.W   D2,$64(A6)      ; 2*dy-2*dx

;---------   MAKE LENGTH   ---------

   ASL.W   #6,D0         ; d0 = 64*dx
   ADD.W   #$0042,D0      ; d0 = 64*(dx+1)+2

;---------   MAKE CONTROL 0+1   ---------

   ROR.W   #4,D4
   ORI.W   #$BEA,D4      ; $B4A - DMA + Minterm
   SWAP   D7
   MOVE.W   D4,D7
   SWAP   D7
   ADD.L   A5,D3      ; SCREEN PTR

   MOVE.L   D7,$40(A6)      ; BLTCON0 + BLTCON1
   MOVE.L   D3,$48(A6)      ; Source C
   MOVE.L   D3,$54(A6)      ; Destination D
   MOVE.W   D0,$58(A6)      ; Size
   RTS

;*****************************
;*              *
;*      COPPER1 PROGRAM      *
;*              *
;*****************************

   SECTION   Copper,DATA_C

COPLIST:
   DC.W   $0100,$1200   ; Bit-Plane control reg.
   DC.W   $0102,$0000   ; Hor-Scroll
   DC.W   $0104,$0010   ; Sprite/Gfx priority
   DC.W   $0108,$0000   ; Modolu (odd)
   DC.W   $010A,$0000   ; Modolu (even)
   DC.W   $008E,$2C81   ; Screen Size
   DC.W   $0090,$2CC1   ; Screen Size
   DC.W   $0092,$0038   ; H-start
   DC.W   $0094,$00D0   ; H-stop

   DC.W   $0180,$0000   ; Color #0 = 000
   DC.W   $0182,$0FFF   ; Color #1 = fff
   DC.L   $FFFFFFFE

;*****************************
;*              *
;*      SCREEN DATA AREA     *
;*              *
;*****************************

   SECTION   Screen,BSS_C

SCREEN   DS.B   40*256
Balrog Software · http://www.amigaskool.net
Mac Mini G4 1,5ghz · MorphOS 2.7 · Ati Radeon 9200 64Mb · 1 Gb RAM · 80 GB HD
Efika · MorphOS 2.7 · Ati Radeon 9250 128Mb · 120 Gb WD HD
Amiga 1200T · OS 3.9 · Voodoo3 · Blizzard 603e/240mhz 060/50mhz · 98 Mb RAM · 40 GB HD
Amiga 600 · OS 3.1 · ACA 630/25mhz 32 Mb RAM · 4Gb CF
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Assembler startup code + line draw (HELP)
« Reply #1 on: August 14, 2006, 07:00:23 PM »
Quote
i have a startup source with a draw line code, it works on my A600, but on my A1200 i got corrupted screen graphics,

It's a bad startup code, not aware of the AGA.

See my home page for  a better one.

The code also doesn't allocate the blitter (OwnBlitter + WaitBlit) for your own use, so it might mess up system blitter queue. The copperlist is not terminated with two $fffffffe's (two are required due to some copper bugs in some chipset revisions). OldOpenLibrary is obsolete and should not be used. The code actually stores old INTENA, DMACON and ADKCON without disabling interrupts. This leaves the code open for race conditions (wrong values might be restored at exit). The code is not aware of VBR (Vector Base Register, 68010-68060) that can be used to move the vector register array elsewhere in memory. Just poking/peeking $6C.w is not enough, it must be relative to VBR (for 68000 use base of 0).
Code: [Select]

.WAIT: BTST #6,$2(A6)
       BNE.S .WAIT

is not enough to wait blitter. The BTST #6 must be done once before entering a loop, or the code might get false positive for blitter done (again some chipset revisions are buggy). Correct code:
Code: [Select]

       BTST #6,$2(A6)
.WAIT: BTST #6,$2(A6)
       BNE.S .WAIT


Quote
a lot of examples don't work because DevPac don't recognise instruction BLK, is a specific assembler instruction?

No.
Quote
it can be switched with other instruction compatible with DevPac?

Code: [Select]

    dcb.size count,val

for example:
Code: [Select]

    dcb.l 16,$715517

Quote
And the last question is about Blitter, to check if the blitter finished the operation, i test bit 6 on $DFF000 address

It's actually $DFF002 (dmaconr).
Quote
, but i found that some codes test bit 14, and DevPac says that you can test bits 0-7. Why some codes use bit 14?

Because btst is always byte operation and the bit number is masked by 7, and 14 & 7 = 6. Since the bits are counted from the LSB (rightmost bit) to MSB (leftmost bit), it doesn't really matter if you use 14 or 6, both fall to same bit. If you're testing bits 0 to 7, then you need to use btst #x,addr+1.

Some assemblers are a bit more lax about the constant value, but really you should use x-8 for the x = 8...15. Strictly speaking using btst #14,... is a bug, it should be btst #14-8,... or btst #14&7,...

So in short, the correct syntax that works for ALL assemblers (testing bit from 16bit memory location):
Code: [Select]

   btst #x,addr+1    ; if x is 0..7
   btst #x&7,addr    ; if x is 8..15


And expanded to 32bit memory locations:
Code: [Select]

   btst #x,addr+3    ; if x is 0..7
   btst #x&7,addr+2  ; if x is 8..15
   btst #x&7,addr+1  ; if x is 16..23
   btst #x&7,addr    ; if x is 24..31

 

Offline balrogsoftTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2006
  • Posts: 186
    • Show only replies by balrogsoft
    • http://www.amigaskoolnet
Re: Assembler startup code + line draw (HELP)
« Reply #2 on: August 15, 2006, 12:27:28 PM »
Thanks a lot Piru!! very good explanation, i will take a look to your startup code.
Balrog Software · http://www.amigaskool.net
Mac Mini G4 1,5ghz · MorphOS 2.7 · Ati Radeon 9200 64Mb · 1 Gb RAM · 80 GB HD
Efika · MorphOS 2.7 · Ati Radeon 9250 128Mb · 120 Gb WD HD
Amiga 1200T · OS 3.9 · Voodoo3 · Blizzard 603e/240mhz 060/50mhz · 98 Mb RAM · 40 GB HD
Amiga 600 · OS 3.1 · ACA 630/25mhz 32 Mb RAM · 4Gb CF