;----------------------------------------------------------- ; ; Api92/Api89 Source Code ; ; (c) NeXO Software, Benoit SCHERRER ; e-mail : p.c.scherrer@wanadoo.fr ; ; ; File> graphics.xas ; Utility> Graphics subroutines ; ;----------------------------------------------------------- ;----------------------------------------------------- ; InterfaceEngine ;a0.l> addr of api92_IEPipe structure ;----------------------------------------------------- apilib@0031: _InterfaceEngine: movem.l d0-d7/a0-a6,-(a7) \loop move.b (a0)+,d0 beq.s \exit ;IE_END = 0 cmp.b #IE_NOP,d0 beq.s \loop cmp.b #IE_WIN2,d0 beq \win2 cmp.b #IE_ANIMEDWIN,d0 beq \awin cmp.b #IE_ANIMEDWIN2,d0 beq \awin2 cmp.b #IE_CLRSCR,d0 beq \clrscr cmp.b #IE_SETFONT,d0 beq.s \setfont cmp.b #IE_STRING,d0 beq.s \string cmp.b #IE_CHAR,d0 beq.s \char cmp.b #IE_SOLIDRECT,d0 beq.s \solidrect cmp.b #IE_WIN,d0 beq.s \win cmp.b #IE_GFX8,d0 beq.s \gfx8 cmp.b #IE_GFX16,d0 beq.s \gfx16 cmp.b #IE_INVERTAREA,d0 beq.s \invert cmp.b #IE_SAVEFONT,d0 beq \savefont cmp.b #IE_RESTOREFONT,d0 beq \restorefont cmp.b #IE_STRINGADDR,d0 beq \stringaddr cmp.b #IE_WAITKEY,d0 beq \waitkey \next bra.s \loop \exit movem.l (a7)+,d0-d7/a0-a6 rts \setfont clr.w d0 move.b (a0)+,d0 bsr _SetFont bra.s \next \string bsr _draw_sString addq.l #2,a0 \eol tst.b (a0)+ bne.s \eol bra.s \next \char clr.w d0 clr.w d1 clr.w d2 move.b (a0)+,d0 move.b (a0)+,d1 move.b (a0)+,d2 bsr _draw_CharSpecial bra.s \next \solidrect bsr _draw_sSolidRect bra.s \next \win bsr _draw_sWindow addq.l #4,a0 \eol2 tst.b (a0)+ bne.s \eol2 bra.s \next \gfx8 bra.s \next \gfx16 bra.s \next \invert clr.w d0 clr.w d1 clr.w d2 clr.w d3 move.b (a0)+,d0 move.b (a0)+,d1 move.b (a0)+,d2 move.b (a0)+,d3 bsr InvertArea bra.s \next \savefont bsr GetFont move.w d0,\old_font bra.s \next \old_font dc.w 0 \restorefont move.w \old_font(PC),d0 bsr SetFont bra \next \stringaddr clr.w d0 clr.w d1 move.b (a0)+,d0 ;X move.b (a0)+,d1 ;Y move.l (a0)+,a1 bsr _draw_StringSpecial bra \next \win2 bsr _draw_sWindow2 addq.l #4,a0 \eol3 tst.b (a0)+ bne.s \eol3 bra \next \awin bsr _draw_sAnimedWindow addq.l #5,a0 \eol4 tst.b (a0)+ bne.s \eol4 bra \next \awin2 bsr _draw_sAnimedWindow2 addq.l #5,a0 \eol5 tst.b (a0)+ bne.s \eol5 bra \next \clrscr bsr _ClearScreen bra \next \waitkey bsr _WaitKey bra \next ;----------------------------------------------------- ; draw_Window & draw_Window2 ; ; > Draw a window on the screen. The difference ; between the two functions is the graphical ; style of the window. ; ;Input> a0.l : Address of an api92Rect structure ; a1.l : Address of the window title (0-terminated) ;Out> No register modified ; ;------------------------------------------------------ ; Format of the api92Rect structure : ; x.B : X1 ; x.B : Y1 ; x.B : X2 ; x.B : Y2 ;----------------------------------------------------- _draw_Window: apilib@0001: movem.l d0-d7/a0-a2,-(a7) bra.s _DrawWin ;----------------------------------------------------- ; draw_sWindow & draw_sWindow2 ; ; > Draw a window on the screen, using an api92Win ; structure. The difference between the two ; functions is the graphical style of the window. ; ;Input> a0.l : Address of an api92Win structure ;Out> No register modified ; ;----------------------------------------------------- ; Format of the api92Win structure : ; x.B : X1 ; x.B : Y1 ; x.B : X2 ; x.B : Y2 ; (..) : Window title (0-terminated) ;----------------------------------------------------- _draw_sWindow: apilib@0000: movem.l d0-d7/a0-a2,-(a7) lea 4(a0),a1 ;Title ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Internal Function used by ; DrawWindow and DrawWindow2 ; input> a0 : api92Rect struture ; a1 : Title ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; _DrawWin: move.l a0,a2 ;save a0 for after bsr _draw_sSolidRect clr.l d0 clr.l d1 move.b (a2),d0 move.b 1(a2),d1 moveq.w #4,d2 lea w_ul(PC),a0 bsr _draw_GFX8xn move.b 2(a2),d0 subq.w #7,d0 addq.l #5,a0 ;next gfx bsr _draw_GFX8xn move.b 3(a2),d1 subq.w #4,d1 addq.l #5,a0 ;next gfx bsr _draw_GFX8xn move.b (a2),d0 ;X addq.l #5,a0 ;next gfx bsr _draw_GFX8xn bsr GetFont move.w d0,-(a7) ;save current font moveq.w #0,d0 bsr SetFont clr.w d1 ;d0 already cleared clr.w d2 move.b (a2)+,d0 move.b (a2)+,d1 move.b (a2),d2 addq.w #5,d0 ;x += 5 addq.w #1,d1 ;y++ bsr DrawStringSpecial ;a1 should be set subq.w #4,d0 sub.w d0,d2 moveq.w #6,d3 bsr InvertArea move.w (a7)+,d0 ;restore original font bsr SetFont movem.l (a7)+,d0-d7/a0-a2 rts apilib@0053: _draw_Window2: movem.l a0-a2,-(a7) _DrawWin2: bsr _draw_Window move.b (a0)+,d0 lsl.l #8,d0 move.b (a0)+,d0 lsl.l #8,d0 move.b (a0)+,d0 lsl.l #8,d0 move.b (a0)+,d0 move.l d0,-(a7) move.l a7,a1 addq.b #2,(a1)+ ;X add.b #10,(a1)+ ;Y subq.b #2,(a1)+ subq.b #2,(a1)+ move.l a7,a0 bsr _draw_sSolidRect addq.l #4,a7 movem.l (a7)+,a0-a2 rts w_ul: dc.b %00111111 dc.b %00000000 dc.b %10000000 dc.b %10000000 dc.b %10000000 w_ur: dc.b %11111100 dc.b %00000000 dc.b %00000001 dc.b %00000001 dc.b %00000001 w_dr: dc.b %00000001 dc.b %00000001 dc.b %00000010 dc.b %00000100 dc.b %11111000 w_dl: dc.b %10000000 dc.b %10000000 dc.b %01000000 dc.b %00100000 dc.b %00011111 ds.w 0 apilib@0054: _draw_sWindow2: movem.l a0-a2,-(a7) lea 4(a0),a1 bra.s _DrawWin2 ;--------------------------------------------------- ; ;--------------------------------------------------- apilib@005C: _draw_sAnimedWindow: bsr _draw_AnimedWindow addq.l #1,a0 bsr _draw_sWindow subq.l #1,a0 rts apilib@005D: _draw_sAnimedWindow2: bsr _draw_AnimedWindow addq.l #1,a0 bsr _draw_sWindow2 subq.l #1,a0 rts _draw_AnimedWindow: movem.l d0-d7/a0-a2,-(a7) move.w #$500,d0 trap #1 move.l d0,-(a7) ;save previous sr clr.w d0 clr.w d1 clr.w d2 clr.w d3 clr.w d7 move.b (a0)+,d7 ;speed beq \exit ;if null, no anim subq.w #1,d7 move.l a0,a2 ;save a0 move.b (a0)+,d0 ;x1 move.b (a0)+,d1 ;y1 move.b (a0)+,d2 ;x2 move.b (a0)+,d3 ;y2 move.w d0,d4 add.w d2,d4 lsr.w #1,d4 ;xc=(x1+x2)/2 move.w d1,d5 add.w d3,d5 lsr.w #1,d5 ;yc=(y1+y2)/2 subq.l #4,a7 move.l a7,a0 move.w d4,d0 sub.w #10,d0 move.w d4,d2 add.w #10,d2 move.w d5,d1 sub.w #5,d2 move.w d5,d3 add.w #5,d3 \loop move.l a0,a1 move.b d0,(a1)+ move.b d1,(a1)+ move.b d2,(a1)+ move.b d3,(a1)+ jsr _draw_sSolidRect subq.l #4,a0 move.l d7,-(a7) \wait moveq.w #127,d6 \wait2 dbra.s d6,\wait2 dbra.s d7,\wait move.l (a7)+,d7 moveq.w #4,d4 movem.l a0/a2,-(a7) subq.w #2,d0 cmp.b (a2),d0 ;if d0>(a2), skip bge.s \skip1 move.b (a2),d0 subq.w #1,d4 \skip1 addq.l #1,a2 subq.w #2,d1 cmp.b (a2),d1 ;if d0>(a2), skip bge.s \skip2 move.b (a2),d1 subq.w #1,d4 \skip2 addq.l #1,a2 addq.w #2,d2 cmp.b (a2),d2 ;if d0>(a2), skip bls.s \skip3 move.b (a2),d2 subq.w #1,d4 \skip3 addq.l #1,a2 addq.w #2,d3 cmp.b (a2),d3 ;if d0>(a2), skip bls.s \skip4 move.b (a2),d3 subq.w #1,d4 \skip4 ; cmp.b (a0)+,(a2)+ ; beq.s \skip1 ; subq.w #2,d0 ; addq.l #1,d4 ;\skip1 cmp.b (a0)+,(a2)+ ; beq.s \skip2 ; subq.w #1,d1 ; addq.l #1,d4 ;\skip2 cmp.b (a0)+,(a2)+ ; beq.s \skip3 ; addq.w #1,d2 ; addq.l #1,d4 ;\skip3 cmp.b (a0)+,(a2)+ ; beq.s \skip4 ; addq.w #1,d3 ; addq.l #1,d4 movem.l (a7)+,a0/a2 tst.w d4 bne.s \loop addq.l #4,a7 ;delete stack frame \exit move.l (a7)+,d0 ;restore previous sr trap #1 movem.l (a7)+,d0-d7/a0-a2 rts ;----------------------------------------------------- ; draw_sString ; ; > Draw a string on the screen, using an api92String ; structure. (very useful !) ; ;Input> a0.l : Address of an api92String structure ;Out> No register modified ; ;----------------------------------------------------- ; Format of the api92String structure : ; x.B : X ; x.B : Y ; x.x : Zero terminated string ;----------------------------------------------------- apilib@0002: _draw_sString: movem.l d0-d2/a0-a2,-(a7) clr.w d0 move.b (a0)+,d0 clr.w d1 move.b (a0)+,d1 move.w #4,-(a7) move.l a0,-(a7) move.w d1,-(a7) move.w d0,-(a7) TIOS_CALL DrawStrXY lea 10(a7),a7 movem.l (a7)+,d0-d2/a0-a2 rts ;----------------------------------------------- ; draw_String ; ; > The use of this function is to draw a string ; without passing parametters with the stack. ; Moreover it destroys no register. ; This function is used for size-optimization in ; programs ; ;input> d0.w : X ; d1.w : Y ; a1.l : Address of the string (0-terminated) ;out> No Register Modified ;----------------------------------------------- apilib@0003: _draw_StringSpecial DrawStringSpecial: movem.l d0-d2/a0-a2,-(a7) move.w #4,-(a7) move.l a1,-(a7) move.w d1,-(a7) move.w d0,-(a7) TIOS_CALL DrawStrXY lea 10(a7),a7 movem.l (a7)+,d0-d2/a0-a2 rts ;----------------------------------------------- ; draw_Char ; ; > The use of this function is to draw a char ; without passing parametters with the stack. ; Moreover it destroys no register. ; This function is used for size-optimization in ; programs ; ;input> d0.w : X ; d1.w : Y ; d2.w : Char Code ;out> No Register Modified ;----------------------------------------------- apilib@0004: _draw_CharSpecial: DrawCharSpecial: movem.l d0-d2/a0-a2,-(a7) ;#ifdef TIPLUS move.w #4,-(a7) move.w d2,-(a7) move.w d1,-(a7) move.w d0,-(a7) TIOS_CALL DrawChar addq.l #8,a7 ;#else move.l #$000000FF,-(a7) move.l #$000400FF,-(a7) move.w d1,-(a7) move.w d0,-(a7) move.w d2,-(a7) TIOS_CALL DrawCharXY lea 14(a7),a7 ;#endif movem.l (a7)+,d0-d2/a0-a2 rts ;----------------------------------------------------- ; draw_sSolidRect ; ; > Draw a solid rectangle on the screen, using an ; api92Rect structure ; ;Input> a0.l : Address of an api92Rect structure ;Out> a0.l : a0=a0+4 ; No Other registers modified ; ;----------------------------------------------------- ; Format of the api92Rect structure : ; x.B : X1 ; x.B : Y1 ; x.B : X2 ; x.B : Y2 ;----------------------------------------------------- apilib@0005: _draw_sSolidRect DrawEraseRect: addq.l #4,a0 movem.l d0-d1/a0-a1,-(a7) moveq.w #3,d0 ;4 laps clr.w d1 \lp move.b -(a0),d1 move.w d1,-(a7) dbra.s d0,\lp jsr _draw_EraseRect jsr _draw_FrameRect addq.l #8,a7 movem.l (a7)+,d0-d1/a0-a1 rts ;----------------------------------------------------- ; draw_HorizontalLine ; ; > Draw a horizontal line on the screen ; ;Input> d0.w : X ; d1.w : Y ; d2.w : Width of the line ;Out> No Register Modified ;----------------------------------------------------- apilib@0043: _draw_HorizontalLine: movem.l d0-d4/a0,-(a7) mulu.w #30,d1 move.l #LCD_MEM,a0 adda.w d1,a0 move.w d0,d1 ;Save x lsr.w #3,d1 ;divide by 8 adda.w d1,a0 and.w #7,d0 ;get only offset beq.s \skip1 moveq.w #7,d1 sub.w d0,d1 move.w d1,d0 cmp.w d0,d2 ;but if width<7 bhi \skip0 move.w d2,d0 \skip0 move.w d0,-(a7) \bit1 bset.b d1,(a0) subq.w #1,d1 dbra.s d0,\bit1 addq.l #1,a0 move.w (a7)+,d0 \skip1 sub.w d0,d2 move.w d2,d1 lsr.w #3,d1 ;Divide by 8 move.w d1,d3 ;save d1 beq.s \skip2 subq.w #1,d1 ;for dbra \drawline move.b #$FF,(a0)+ dbra.s d1,\drawline \skip2 lsl.w #3,d3 sub.w d3,d2 beq.s \skip3 moveq.w #7,d1 subq.w #1,d2 \bit2 bset.b d1,(a0) subq.l #1,d1 dbra.s d2,\bit2 \skip3 movem.l (a7)+,d0-d4/a0 rts ;----------------------------------------------------- ; SetFont ; ; > Set the current Font used. It has the advantage ; of changing no register ; (Used for size-optimization) ; ;Input> d0.w : Font Index : 0 = small (variable x 6) ; 1 = medium (6 x 8) ; 2 = large (8*10) ;Out> No register modified ;----------------------------------------------------- apilib@0006: _SetFont: SetFont: movem.l d0-d2/a0-a2,-(a7) move.w d0,-(a7) TIOS_CALL FontSetSys addq.l #2,a7 movem.l (a7)+,d0-d2/a0-a2 rts ;----------------------------------------------------- ; GetFont ; ; > Get the current Font used. It has the advantage ; of changing only the d0 register. ; ;Input> Nothing ; ;Out> d0.w : Font Index : 0 = small (variable x 6) ; 1 = medium (6 x 8) ; 2 = large (8*10) ; ; No Other register modified ;----------------------------------------------------- apilib@0007: _GetFont: GetFont: movem.l d1-d2/a0-a2,-(a7) TIOS_CALL FontGetSys and.w #$00FF,d0 movem.l (a7)+,d1-d2/a0-a2 rts ;----------------------------------------------------- ; GetFontWidthHeight ; ; > Get the width and the height of current font ; used ; Notice that the real width in small font is ; variable. The function will return 6 ; ;Input> Nothing ; ;Out> d0.w : Font Width ; d1.w : Font Height ; ; No Other register modified ;----------------------------------------------------- apilib@0008: _GetFontWidthHeight: GetFontWidthHeight: bsr GetFont tst.w d0 bne.s \no1 moveq.w #6,d0 moveq.w #5,d1 \no1 cmp.w #1,d0 bne.s \no2 moveq.w #6,d0 moveq.w #8,d1 \no2 cmp.w #2,d0 bne.s \no3 moveq.w #8,d0 moveq.w #10,d1 \no3 rts apilib@0026: _sInvertArea: movem.l d0-d3/a0,-(a7) clr.l d0 clr.l d1 clr.l d2 clr.l d3 move.b (a0)+,d0 move.b (a0)+,d1 move.b (a0)+,d2 move.b (a0)+,d3 bsr _InvertArea movem.l (a7)+,d0-d3/a0 rts ;------------------------------------------------------ ; InvertArea ; ; > Invert a non-aligned area on the screen ; ;Input> d0.w : X ; d1.w : Y ; d2.w : Width (in pixels) ; d3.w : Height (in pixels) ;Out> No Register Modified ;------------------------------------------------------ apilib@0009: _InvertArea: InvertArea: movem.l a0/d0-d5,-(a7) move.l #LCD_MEM,a0 ;memory address mulu.w #30,d1 ;y*30 adda d1,a0 subq.w #1,d3 \lines movem.l a0/d0/d2,-(a7) move.l d0,d1 ;save d0 lsr.w #3,d1 ;int(d1/8) adda d1,a0 ; lsl.w #3,d1 ;d1*8 move.w d0,d4 ;d4=X sub.w d1,d4 ;d4=d4-d1 moveq.w #8,d5 ; sub.w d4,d5 ;d5=8-d4 sub.w d5,d2 ;for after tst.w d5 beq.s \skip1 subq.w #1,d5 \lp bchg.b d5,(a0) dbra.s d5,\lp \skip1 move.w d2,d1 ;save d2 addq.l #1,a0 lsr.w #3,d2 move.w d2,d4 ;save d2 beq.s \skip2 ;if d2=d4 = 0 skip subq.w #1,d2 \lp2 not.b (a0)+ dbra.s d2,\lp2 \skip2 lsl.w #3,d4 sub.w d4,d1 tst.w d1 beq.s \no subq.w #1,d1 moveq.w #7,d2 \lp3 bchg.b d2,(a0) subq.w #1,d2 dbra.s d1,\lp3 \no movem.l (a7)+,a0/d0/d2 lea 30(a0),a0 ;adda #30,a0 dbra.s d3,\lines movem.l (a7)+,a0/d0-d5 rts ;----------------------------------------------------- ; ScreenToBuffer ; ; > Copy the entire screen into a 3840 bytes buffer ; ;Input> a1.l : Address of Buffer ;Out> No register modified ;----------------------------------------------------- apilib@000A: movem.l d0/a0-a1,-(a7) move.l #LCD_MEM,a0 bra.s CopyMemory ;----------------------------------------------------- ; BufferToScreen ; ; Copy the contents of a 3840 bytes buffer to the screen ; ;Input> a1.l : Address of Buffer ;Out> No register modified ;----------------------------------------------------- apilib@000B: movem.l d0/a0-a1,-(a7) move.l #LCD_MEM,a0 exg.l a0,a1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; internal function ; copy 3840 bytes from a0 to a1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CopyMemory: move.w #959,d0 \loop move.l (a0)+,(a1)+ dbra.s d0,\loop movem.l (a7)+,d0/a0-a1 rts ;----------------------------------------------------- ; ZapScreen ; ; > Clear completly the screen. (fast) ; ;Input> Nothing ;Out> No Register modified ;----------------------------------------------------- apilib@002C: _ZapScreen: movem.l d0-d7/a0-a6,-(sp) move.l a7,savea7 lea LCD_MEM,a7 add.l #3840,a7 movem.l zeroes,d0-d7/a0-a6 movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times movem.l d0-d7/a0-a6,-(a7) ; repeated 64 times move.l savea7,a7 movem.l (sp)+,d0-d7/a0-a6 rts zeroes dcb.l 15,0 savea7 dc.l 0 ;----------------------------------------------------- ; ClearScreen ; ; > Clear completly the screen and redraw the ; status bar ; ;Input> Nothing ;Out> No Register modified ;----------------------------------------------------- apilib@002D: _ClearScreen: movem.l d0/a0,-(sp) bsr _ZapScreen lea LCD_MEM,a0 move.w #LCDHEIGHT-7,d0 mulu.w #30,d0 adda.l d0,a0 move.l #$FFFFFFFF,d0 move.l d0,(a0)+ move.l d0,(a0)+ move.l d0,(a0)+ move.l d0,(a0)+ move.l d0,(a0)+ ;#ifdef TI89 ;#else move.l d0,(a0)+ move.l d0,(a0)+ move.w d0,(a0)+ ;#endif movem.l (sp)+,d0/a0 rts ;***************************************************** ; prep_rect: used by frame_rect and erase_rect ;***************************************************** prep_rect: move.l #0,d4 move.w $36(a7),d4 move.w d4,d5 lsl.w #5,d4 lsl.w #1,d5 sub.w d5,d4 add.l #LCD_MEM,d4 move.l d4,a0 move.l #0,d5 move.w $3A(a7),d5 move.w d5,d6 lsl.w #5,d5 lsl.w #1,d6 sub.w d6,d5 add.l #LCD_MEM,d5 move.l d5,a1 move.w $34(a7),d0 move.w d0,d6 lsr.w #3,d0 and.w #$7,d6 move.w $38(a7),d1 move.w d1,d7 lsr.w #3,d1 and.w #$7,d7 rts ;***************************************************** _draw_FrameRect: apilib@0029: movem.l d0-d7/a0-a2,-(a7) bsr prep_rect move.b #$FF,d2 move.b #$FF,d3 move.b #$80,d4 move.b #$01,d5 lsr.b d6,d2 lsr.b d6,d4 move.w #7,d6 sub.w d7,d6 lsl.b d6,d3 lsl.b d6,d5 move.w d0,d7 horz_loop: move.b #$FF,d6 cmp.w d0,d7 bne horz_not_left and.b d2,d6 horz_not_left: cmp.w d1,d7 bne horz_not_right and.b d3,d6 horz_not_right: or.b d6,0(a0,d7.w) or.b d6,0(a1,d7.w) add.w #1,d7 cmp.w d1,d7 bls horz_loop lea 30(a0),a2 vert_loop: or.b d4,0(a2,d0.w) or.b d5,0(a2,d1.w) lea 30(a2),a2 cmp.l a1,a2 bcs vert_loop movem.l (a7)+,d0-d7/a0-a2 rts ;***************************************************** _draw_EraseRect: apilib@002A: movem.l d0-d7/a0-a2,-(a7) bsr prep_rect move.b #$FF,d2 move.b #$FF,d3 lsr.b d6,d2 move.w #7,d6 sub.w d7,d6 lsl.b d6,d3 not.b d2 not.b d3 not.b d6 move.l a0,a2 vert_loop1: move.w d0,d7 horz_loop1: clr.b d6 cmp.w d0,d7 bne horz_not_left1 or.b d2,d6 horz_not_left1: cmp.w d1,d7 bne horz_not_right1 or.b d3,d6 horz_not_right1: and.b d6,0(a2,d7.w) add.w #1,d7 cmp.w d1,d7 bls horz_loop1 lea 30(a2),a2 cmp.l a1,a2 bls vert_loop1 movem.l (a7)+,d0-d7/a0-a2 rts ;------------------------------------------------- ; draw_GFX8x8 ; ; > Draw a non-aligned 8x8 sprite on the screen ; ;Input> d0.w : X ; d1.w : Y ; a0.l : Address of sprite data ;------------------------------------------------ apilib@0047: _draw_GFX8x8: move.l d2,-(a7) moveq.w #7,d2 bsr _draw_GFX8xn move.l (a7)+,d2 rts ;------------------------------------------------- ; draw_GFX8xn ; ; > Draw a non-aligned 8xn sprite on the screen ; ;Input> d0.w : X ; d1.w : Y ; d2.w : Number of lines - 1 ; a0.l : Address of sprite data ;------------------------------------------------ apilib@0048: _draw_GFX8xn: movem.l a0-a1/d0-d7,-(a7) move.w d2,-(a7) move.l #LCD_MEM,a1 mulu.w #30,d1 add.w d1,a1 move.w d0,d2 ;copy x lsr.w #3,d2 ;int(x/8) add.w d2,a1 lsl.w #3,d2 sub.w d2,d0 move.w #$FF00,d5 ror.w d0,d5 moveq.w #8,d6 sub.w d0,d6 move.w #$FF00,d7 rol.w d6,d7 move.w (a7)+,d2 ;NbLines \line move.b (a0)+,d3 tst.w d0 ;if on a byte bne.s \nozero ;no problem move.b d3,(a1)+ bra.s \loop \nozero move.b d3,d4 lsr.b d0,d3 and.b d5,(a1) or.b d3,(a1)+ lsl.b d6,d4 and.b d7,(a1) or.b d4,(a1) \loop lea 29(a1),a1 ;adda.w #29,a1 dbra.s d2,\line movem.l (a7)+,a0-a1/d0-d7 rts ;--------------------------------------------------- ; SaveScreenToPIC ; ; > The Api92::SaveScreenToPIC save a non-aligned ; area of the screen into a valid PIC file ; ;Input> d0.w : Folder Handle ; a0.l : File Name ; a1.l : Address of api92_Rect structure ;Out> d1.w : Error Code ; ; Format of api92_Rect structure : ; 00.b : X1 ; 01.b : Y1 ; 02.b : X2 ; 03.b : Y2 ;--------------------------------------------------- SPIC_X1 equ 0 SPIC_Y1 equ 2 SPIC_X2 equ 4 SPIC_Y2 equ 6 SPIC_HEIGHT equ 8 SPIC_WIDTH equ 10 apilib@0027: _SaveScreenToPIC: movem.l d0/d2-d7/a0-a4,-(a7) suba.w #12,a7 move.l a7,a6 clr.l (a6) clr.l 4(a6) move.b (a1)+,1(a6) move.b (a1)+,3(a6) move.b (a1)+,5(a6) move.b (a1)+,7(a6) move.w SPIC_X2(a6),SPIC_WIDTH(a6) move.w SPIC_X1(a6),d1 sub.w d1,SPIC_WIDTH(a6) addq.w #1,SPIC_WIDTH(a6) ;because save extremité move.w SPIC_Y2(a6),SPIC_HEIGHT(a6) move.w SPIC_Y1(a6),d1 sub.w d1,SPIC_HEIGHT(a6) clr.l d2 move.w SPIC_WIDTH(a6),d2 ;Get width move.w d2,d6 ;save width lsr.w #3,d2 ;divide by 8 and.w #7,d6 beq.s \skip addq.l #1,d2 \skip mulu.w SPIC_HEIGHT(a6),d2 addq.l #(4+1),d2 ;add some bytes clr.w d1 ;flag bsr _vat_CreateVar tst.w d1 bne.s \exit addq.l #2,a0 move.l SPIC_HEIGHT(a6),(a0)+ ;Height+Width move.l #LCD_MEM,a1 ;Get LCD addr move.w SPIC_Y1(a6),d0 ;Y1 mulu.w #30,d0 ;Y1*30 adda.w d0,a1 move.w (a6),d0 ;Get X1 lsr.w #3,d0 adda.w d0,a1 move.w SPIC_HEIGHT(a6),d7 subq.w #1,d7 ;for dbra \YLoop move.l a1,a2 ;save a1 move.w (a6),d4 ;Get X1 move.w d4,d0 ;save X1 and.w #7,d0 ;get offset in the byte moveq.w #7,d5 sub.w d0,d5 ;d5=current offset in src byte clr.w d2 ;current byte of dest moveq.w #7,d3 ;d3=current offset in dest byte \XLoop btst.b d5,(a2) beq.s \skip2 bset.b d3,d2 \skip2 tst.w d3 ;offset in dest null ? bne.s \skip3 move.b d2,(a0)+ clr.w d2 moveq.w #8,d3 \skip3 subq.w #1,d3 ;decrement d3 tst.w d5 ;offset in scr null ? bne.s \skip4 addq.l #1,a2 moveq.w #8,d5 \skip4 subq.w #1,d5 cmp.w SPIC_X2(a6),d4 ;End of line ? beq.s \endX addq.w #1,d4 ;pixel index bra.s \XLoop \endX cmp.w #7,d3 ;we've just copy it beq.s \skip5 ;skip move.b d2,(a0)+ \skip5 lea 30(a1),a1 dbra.s d7,\YLoop move.b #$DF,(a0)+ clr.l d1 ;no error \exit adda.w #12,a7 movem.l (a7)+,d0/d2-d7/a0-a4 rts