Path: ns-mx!uunet!elroy.jpl.nasa.gov!usc!samsung!umich!uflorida!kluge!serss0.fiu.edu From: acmfiu@serss0.fiu.edu (albert chin) Newsgroups: comp.sys.apple2 Subject: copying data real fast...code to do it Message-ID: <4202@kluge.fiu.edu> Date: 29 Jul 91 09:09:08 GMT Sender: news@kluge.fiu.edu Organization: Florida International University, Miami Lines: 361 the following routine copies data from an off-screen grafport to an on-screen window. as far as i am aware, this is the fastest possible method to do the copy. the off-screen grafport is guaranteed to remain in a bank. the destination is bank $01. this copy routine handles several copies. the only one this routine deals with is routine #1 which copies the entire off-screen grafport. things you need to know: 1. variables of the form ']' are direct page variables 2. variables of the form '@' are global variables 3. variables of the form '~' are constant variables 4. @grafport is the pointer to the on-screen window 5. @off_grafport is the pointer to the off-screen grafport 6. ~shr contains a table of pointers to the beginning of screen lines 7. VSCROLL_WIDTH is the length of the vertical scroll bar 8. cg is a macro that lda ]1,x pha lda ]1-2,x pha lda ]1-4,x pha lda ]1-6,x pha lda ]1-8,x pha if anyone has questions, feel free to email me. i hope the code is clear. albert chin ---------------------------- snip snip ------------------------------- ************************************************** * copy off-screen grafport to on-screen window * * content region. main entry point for copy * * routine. * * #1 copies entire grafport * * #2 copies grafport starting at x-register * * #3 copies grafport starting at x, ending in y * ************************************************** copy_grafport ent ]grafport = $c0 ;current grafport ]off_grafport = $c4 ;off-screen grafport ]rect = $c8 ;window port rectangle ]rect_global = $d0 ;global window port rectangle ]off_rect = $d8 ;off-screen port rectangle ]image = $e0 ;pointer to window pixel image ]off_image = $e4 ;pointer to off-screen pixel image ]x = $e8 ;number of bytes to copy ]height = $ea ;number of lines to copy ]vis_region = $ec ;handle/pointer to visible region ]which_copy = $f0 ;which copy_grafport routine to use ]begin_y = $f2 ;beginning coordinate to copy ]end_y = $f4 ;ending coordinate to copy ]max_x = $f6 ;max x value for on-screen window ]qd_MinRect = $00 ]qd_ImageRef = $0e ]qd_BoundsRect = $14 sta ]which_copy ;which copy_grafport routine to use stx ]begin_y ;where to begin copy (for 2, 3) sty ]end_y ;where to end copy (for 3) ldx @grafport ldy @grafport+2 stx ]grafport sty ]grafport+2 phy ;long - pointer to grafport phx _SetPort ldx @off_grafport ldy @off_grafport+2 stx ]off_grafport sty ]off_grafport+2 phy phx ldy #$1c ;get handle to visible region lda []grafport],y sta ]vis_region ldy #$1e lda []grafport],y sta ]vis_region+2 ldy #2 ;convert vis_region handle to pointer lda []vis_region],y tay lda []vis_region] sta ]vis_region sty ]vis_region+2 sec ldy #$16 ;if leftmost byte to copy begins lda []grafport],y ;at scroll bar, end sbc #VSCROLL_WIDTH sta ]max_x ldy #4 ;test leftmost byte lda []vis_region],y cmp ]max_x blt :1 brl :rts :1 lda ]which_copy ;copy routines here only setup cmp #COPY_GRAFPORT_3 ;parameters bne :copy_2 jsr copy_grafport_3 ;copy grafport from ]begin_y to ]end_y bra :continue :copy_2 cmp #COPY_GRAFPORT_2 bne :copy_1 jsr copy_grafport_2 ;copy grafport starting at ]begin_y bra :continue :copy_1 jsr copy_grafport_1 ;copy entire grafport :continue bcc :2 brl :rts :2 ldy #$16 ;leftmost coordinate for on-screen lda []grafport],y ;window sbc #VSCROLL_WIDTH sta ]max_x sec ldy #8 lda []vis_region],y cmp ]max_x blt :3 sec ldy #$16 ;leftmost coordinate for on-screen lda []grafport],y ;window ldy #8 sbc []vis_region],y sta ]max_x sec lda #VSCROLL_WIDTH sbc ]max_x sta ]max_x sec ldy #8 lda []vis_region],y sbc ]max_x bra :4 :3 ldy #8 lda []vis_region],y :4 sta ]rect_global+6 sta ]rect+6 sbc ]rect+2 dec dec dec lsr lsr sta ]x ;length in words to copy clc ;convert window port rectangle to tdc ;global coordinates adc #]rect_global pea #0 pha _LocalToGlobal clc tdc adc #]rect_global+4 pea #0 pha _LocalToGlobal phd lda qd_dp ;set quickdraw direct page tcd ldx @grafport ;temp location to retrieve bounds ldy @grafport+2 ;rectangle stx ]qd_MinRect sty ]qd_MinRect+2 ldy #8 ;set up bounds rectangle of window lda []qd_MinRect],y ;grafport sta ]qd_BoundsRect ldy #10 lda []qd_MinRect],y sta ]qd_BoundsRect+2 ldy #12 lda []qd_MinRect],y sta ]qd_BoundsRect+4 ldy #14 lda []qd_MinRect],y sta ]qd_BoundsRect+6 ldx ]rect ;set up rectangle cursor might be in ldy ]rect+2 stx ]qd_MinRect sty ]qd_MinRect+2 ldx ]rect+4 ldy ]rect+6 stx ]qd_MinRect+4 sty ]qd_MinRect+6 ldx #$2000 ;set up screen image where cursor ldy #$e1 ;exists stx ]qd_ImageRef sty ]qd_ImageRef+2 jsl ShieldCursor pld lsr ]rect+2 lsr ]rect+2 lsr ]rect_global+2 lsr ]rect_global+2 stz :off_left ldy #4 ;if window off left of screen, lda []vis_region],y ;adjust copy beq :right lda #TRUE sta :off_left :right sec ;if window off right of screen, ldy #$16 ;adjust copy lda []grafport],y sbc #VSCROLL_WIDTH ldy #8 cmp []vis_region],y blt :on_screen inc ]rect+2 :on_screen lda ]rect+4 inc asl tax clc ldy #2 lda []off_grafport],y adc ~shr,x adc ]rect+2 dec sta ]off_image ldy #4 lda []off_grafport],y sta ]off_image+2 lda ]rect_global+4 inc asl tax clc ldy #2 lda []grafport],y adc ~shr,x adc ]rect_global+2 adc ]x sta ]image ldy #4 lda []grafport],y sta ]image+2 sei tsc sta :stack ;save copy of stack pointer tdc sta :dp ;save copy of direct-page pointer inc ]x inc ]x lsr ]x ;number of bytes -> number of words sec lda #80 sbc ]x ;each word copy takes 4 bytes asl asl clc adc #:copy sta :copy_addr lda ]height sta :height ldy ]image ldx ]off_image shorta phb ;save copy of data bank register pla sta :db lda ]off_image+2 ;map data bank register to off-screen pha ;image plb stal WrCardRam ;map stack to aux memory longa :5 sec tya sbc #160 tay tcs sec txa sbc #160 tax ;index into copy routine hex 4c ;jmp :copy_addr dw 0 :6 ldal :height dec stal :height bpl :5 shorta stal WrMainRam ;map stack back to bank 00 longa ldal :stack ;restore stack pointer tcs ldal :dp ;restore direct-page register tcd shorta ldal :db ;restore data bank register pha plb longa cli phd lda qd_dp ;set quickdraw direct page tcd jsl UnshieldCursor pld :rts _SetPort jsr init_tick ;reset tick counter rts :stack dw 0 ;stack pointer :dp dw 0 ;direct-page pointer :db db 0 ;data bank register :height dw 0 :off_left dw 0 ;if window on outside left of screen :copy cg 158 cg 148 cg 138 cg 128 cg 118 cg 108 cg 98 cg 88 cg 78 cg 68 cg 58 cg 48 cg 38 cg 28 cg 18 lda: 8,x pha lda: 6,x pha lda: 4,x pha lda: 2,x pha ldal :off_left beq :end shorta lda: 1,x pha longa :end brl :6