acmfiu@serss0.fiu.edu (ACMFIU) (05/24/91)
below are three assembly routines. two i need help in optimizing and the third i need help to get it to work. because i'm not using TextEdit for my program, i need to blink the insertion cursor. everytime through my main event loop ('event_loop' below), i call 'blink_cursor' which accomplishes this. however, it doesn't blink the cursor at all. however, if you look at the line i have a '*' next to in the 'blink_cursor' routine, i can change it to 'blt' and it will start blinking only if "Cursor Flash" in the control panel keyboard setting is not set so the '*' is flush left. oddly enough, if i leave the 'bge' in and run this loop with GSBug everything works. this i don't understand. the next routine, 'scroll_rect', is used to scroll my off-screen grafport one line (line = length specified by ~line_height [height of line]). can anyone optimize this? the code is self-explanatory. the last routine, 'copy_grafport', is used to copy the data in an off-screen grafport to an on-screen grafport, namely my window. i also need this optimized. variables beginning with '}' are boolean variables ']' are DP variables '~' are constants (that can change) '@' global variables thanks, albert chin --------------------------------- snip here -------------------------------- ************************************************** * taskmaster event loop * ************************************************** event_loop equ * pha ;long - space for result pha _GetTick ;initialize ~num_ticks value plx ply stx ~num_ticks sty ~num_ticks+2 :1 jsr blink_cursor pha pea #$ffff pea #^taskrec pea #taskrec _TaskMaster pla ;ignore null events asl tax jsr (task_table,x) lda quit_flag beq :1 rts task_table dw :ignore ;nullEvt dw :ignore ;mouseDownEvt dw :ignore ;mouseUpEvt dw parse_key ;keyDownEvt dw :ignore ;undefined dw parse_key ;autoKeyEvt dw :ignore ;updateEvt dw :ignore ;undefined dw :ignore ;activateEvt dw :ignore ;switchEvt dw :ignore ;deskAccEvt dw :ignore ;driverEvt dw :ignore ;app1Evt dw :ignore ;app2Evt dw :ignore ;app3Evt dw :ignore ;app4Evt dw :ignore ;wInDesk dw :ignore ;wInMenuBar dw :ignore ;wClickCalled dw :ignore ;wInContent dw drag ;wInDrag dw :ignore ;wInGrow dw :ignore ;wInGoAway dw zoom ;wInZoom dw info ;wInInfo dw :ignore ;wInSpecial dw :ignore ;wInDeskItem dw :ignore ;wInFrame dw :ignore ;wInactMenu dw :ignore ;wClosedNDA dw :ignore ;wCalledSysEdit dw :ignore ;wTrackZoom dw :ignore ;wHitFrame :ignore rts ************************************************** * control blinking interval of vertical insert * * bar * ************************************************** blink_cursor equ * ]pen_pattern = $80 ;pen pattern ]num_ticks = $84 ;number of ticks pha ;long - space for result pha _GetCaretTime clc pla adc ~num_ticks sta ~num_ticks pla adc ~num_ticks+2 sta ~num_ticks+2 pha ;long - space for result pha _GetTick plx ply cpy ~num_ticks+2 bge :1 rts :1 cpx ~num_ticks bge :2 rts :2 stx ~num_ticks ;update ~num_ticks sty ~num_ticks+2 pha ;long - space for result pha _GetPort pha ;long - space for result pha _FrontWindow ;get current grafport. _SetPort lda }blink bne :off :on pea #15 ;word - paint pattern white clc ;long - pointer to pattern tdc adc #]pen_pattern pea #0 pha _SolidPattern clc ;long - pointer to pattern tdc adc #]pen_pattern pea #0 pha _SetPenPat ldx @x_coor ldy @y_coor phx ;word - horizontal coordinate phy ;word - vertical coordinate _MoveTo sec lda @y_coor sbc ~line_height inc inc ldx @x_coor phx ;horizontal point to draw line to pha ;vertical point to draw line to _LineTo lda #1 sta }blink bra :rts :off _PenNormal ;prepare to erase insertion bar ldx @x_coor ldy @y_coor phx ;word - horizontal coordinate phy ;word - vertical coordinate _MoveTo sec lda @y_coor sbc ~line_height inc inc ldx @x_coor phx ;horizontal point to draw line to pha ;vertical point to draw line to _LineTo stz }blink :rts _SetPort rts ************************************************** * scroll off-screen grafport up ~line_height * ************************************************** scroll_rect equ * ]off_grafport = $80 ;current grafport ]off_image = $84 ;off-screen pixel map - source ]image = $88 ;off-screen pixel map - destination ]y = $8c ;height of scrolling region pha ;long - space for result pha _GetPort plx ;long - pointer to current grafport ply stx ]off_grafport sty ]off_grafport+2 sec lda @y_coor sbc ~line_height sta ]y clc lda ~line_height asl tax ldy #2 lda []off_grafport],y sta ]image adc ~shr,x sta ]off_image ldy #4 lda []off_grafport],y sta ]image+2 adc #0 sta ]off_image+2 :1 clc lda ]off_image adc #160 sta ]off_image bcc :7 inc ]off_image+2 :7 clc lda ]image adc #160 sta ]image bcc :6 inc ]image+2 :6 ldy #158 lda []off_image],y sta []image],y ldy #156 lda []off_image],y sta []image],y ldy #154 lda []off_image],y sta []image],y ldy #152 lda []off_image],y sta []image],y ldy #150 lda []off_image],y sta []image],y ldy #148 lda []off_image],y sta []image],y ldy #146 lda []off_image],y sta []image],y ldy #144 lda []off_image],y sta []image],y ldy #142 lda []off_image],y sta []image],y ldy #140 lda []off_image],y sta []image],y ldy #138 lda []off_image],y sta []image],y ldy #136 lda []off_image],y sta []image],y ldy #134 lda []off_image],y sta []image],y ldy #132 lda []off_image],y sta []image],y ldy #130 lda []off_image],y sta []image],y ldy #128 lda []off_image],y sta []image],y ldy #126 lda []off_image],y sta []image],y ldy #124 lda []off_image],y sta []image],y ldy #122 lda []off_image],y sta []image],y ldy #120 lda []off_image],y sta []image],y ldy #118 lda []off_image],y sta []image],y ldy #116 lda []off_image],y sta []image],y ldy #114 lda []off_image],y sta []image],y ldy #112 lda []off_image],y sta []image],y ldy #110 lda []off_image],y sta []image],y ldy #108 lda []off_image],y sta []image],y ldy #106 lda []off_image],y sta []image],y ldy #104 lda []off_image],y sta []image],y ldy #102 lda []off_image],y sta []image],y ldy #100 lda []off_image],y sta []image],y ldy #98 lda []off_image],y sta []image],y ldy #96 lda []off_image],y sta []image],y ldy #94 lda []off_image],y sta []image],y ldy #92 lda []off_image],y sta []image],y ldy #90 lda []off_image],y sta []image],y ldy #88 lda []off_image],y sta []image],y ldy #86 lda []off_image],y sta []image],y ldy #84 lda []off_image],y sta []image],y ldy #82 lda []off_image],y sta []image],y ldy #80 lda []off_image],y sta []image],y ldy #78 lda []off_image],y sta []image],y ldy #76 lda []off_image],y sta []image],y ldy #74 lda []off_image],y sta []image],y ldy #72 lda []off_image],y sta []image],y ldy #70 lda []off_image],y sta []image],y ldy #68 lda []off_image],y sta []image],y ldy #66 lda []off_image],y sta []image],y ldy #64 lda []off_image],y sta []image],y ldy #62 lda []off_image],y sta []image],y ldy #60 lda []off_image],y sta []image],y ldy #58 lda []off_image],y sta []image],y ldy #56 lda []off_image],y sta []image],y ldy #54 lda []off_image],y sta []image],y ldy #52 lda []off_image],y sta []image],y ldy #50 lda []off_image],y sta []image],y ldy #48 lda []off_image],y sta []image],y ldy #46 lda []off_image],y sta []image],y ldy #44 lda []off_image],y sta []image],y ldy #42 lda []off_image],y sta []image],y ldy #40 lda []off_image],y sta []image],y ldy #38 lda []off_image],y sta []image],y ldy #36 lda []off_image],y sta []image],y ldy #34 lda []off_image],y sta []image],y ldy #32 lda []off_image],y sta []image],y ldy #30 lda []off_image],y sta []image],y ldy #28 lda []off_image],y sta []image],y ldy #26 lda []off_image],y sta []image],y ldy #24 lda []off_image],y sta []image],y ldy #22 lda []off_image],y sta []image],y ldy #20 lda []off_image],y sta []image],y ldy #18 lda []off_image],y sta []image],y ldy #16 lda []off_image],y sta []image],y ldy #14 lda []off_image],y sta []image],y ldy #12 lda []off_image],y sta []image],y ldy #10 lda []off_image],y sta []image],y ldy #8 lda []off_image],y sta []image],y ldy #6 lda []off_image],y sta []image],y ldy #4 lda []off_image],y sta []image],y ldy #2 lda []off_image],y sta []image],y lda []off_image] sta []image] dec ]y bmi :2 jmp :1 :2 ldx ~line_height ;prepare to erase the current line :3 clc ;as this line will be written over lda ]image adc #160 sta ]image bcc :4 inc ]image+2 :4 lda #0 ldy #638 :5 sta []image],y dey dey bpl :5 dex bpl :3 rts ************************************************** * copy entire off-screen grafport to on-screen * * window content region * ************************************************** copy_grafport equ * ]grafport = $80 ;current grafport ]off_grafport = $84 ;off-screen grafport ]rect = $88 ;window port rectangle ]rect_global = $90 ;global window port rectangle ]off_rect = $98 ;off-screen port rectangle ]image = $a0 ;pointer to window pixel image ]off_image = $a4 ;pointer to off-screen pixel image ]x = $a8 ]y = $aa ]vis_region = $ac ;handle/pointer to visible region ]point = $b0 ;mouse location ]pixelmap = $b4 ;window pixel map ]off_pixelmap = $b8 ;off-screen pixel map pha ;long - space for result pha _FrontWindow ;get current grafport. plx ply stx ]grafport sty ]grafport+2 phy ;long - pointer to grafport phx _SetPort ldy #ouserField+2 ;offset to user field in grafport lda []grafport],y ;record sta ]off_grafport+2 pha ldy #ouserField lda []grafport],y sta ]off_grafport pha 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 ldy #2 lda []vis_region],y cmp #200 ;if v1 > 200, end blt :1 brl :rts :1 sta ]rect_global sta ]rect ldy #4 lda []vis_region],y sta ]rect_global+2 sta ]rect+2 ldy #6 lda []vis_region],y dec sta ]rect_global+4 sta ]rect+4 sec sbc ]rect sta ]y ;height in bytes to copy clc ;for extra dec because of sbc ldy #8 lda []vis_region],y sta ]rect_global+6 sta ]rect+6 sbc ]rect+2 dec dec dec dec lsr lsr sta ]x ;length in bytes 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 lsr ]rect+2 lsr ]rect+2 lsr ]rect_global+2 lsr ]rect_global+2 pha ;word - space for result clc tdc adc #]point pea #0 ;long - pointer to point pha pea #0 ;long - pointer to point pha _GetMouse clc ;long - pointer to rectangle tdc adc #]rect pea #0 pha _PtInRect pla ;word - boolean if point in rectangle pha beq :2 _HideCursor :2 clc lda ]rect+4 inc asl tax ldy #2 lda []off_grafport],y adc ~shr,x adc ]rect+2 sta ]off_image ldy #4 lda []off_grafport],y adc #0 sta ]off_image+2 clc lda ]rect_global+4 inc asl tax ldy #2 lda []grafport],y adc ~shr,x adc ]rect_global+2 sta ]image ldy #4 lda []grafport],y adc #0 sta ]image+2 :3 sec lda ]off_image sbc #160 sta ]off_image bcs :5 dec ]off_image+2 :5 sec lda ]image sbc #160 sta ]image bcs :6 dec ]image+2 :6 ldy ]x :4 lda []off_image],y sta []image],y dey dey bpl :4 dec ]y bpl :3 pla ;boolean if point in rectangle beq :rts _ShowCursor :rts _SetPort rts ************************************************** * variables * ************************************************** * boolean flags * }esc dw 0 ;test if 'esc' key is pressed ;for emacs-style command-line }blink dw 0 ;if last blink of cursor was draw/erase * "constant" variables (might change) * ~right dw 0 ;max value for cursor on right - determined by portRect ~bottom dw 0 ;max value for cursor on bottom - determined by portRect ~line_height dw 0 ;height of current font ~num_ticks adrl 0 ;number of ticks of cursor ~shr dw $0000,$00a0,$0140,$01e0,$0280,$0320,$03c0,$0460 dw $0500,$05a0,$0640,$06e0,$0780,$0820,$08c0,$0960 dw $0a00,$0aa0,$0b40,$0be0,$0c80,$0d20,$0dc0,$0e60 dw $0f00,$0fa0,$1040,$10e0,$1180,$1220,$12c0,$1360 dw $1400,$14a0,$1540,$15e0,$1680,$1720,$17c0,$1860 dw $1900,$19a0,$1a40,$1ae0,$1b80,$1c20,$1cc0,$1d60 dw $1e00,$1ea0,$1f40,$1fe0,$2080,$2120,$21c0,$2260 dw $2300,$23a0,$2440,$24e0,$2580,$2620,$26c0,$2760 dw $2800,$28a0,$2940,$29e0,$2a80,$2b20,$2bc0,$2c60 dw $2d00,$2da0,$2e40,$2ee0,$2f80,$3020,$30c0,$3160 dw $3200,$32a0,$3340,$33e0,$3480,$3520,$35c0,$3660 dw $3700,$37a0,$3840,$38e0,$3980,$3a20,$3ac0,$3b60 dw $3c00,$3ca0,$3d40,$3de0,$3e80,$3f20,$3fc0,$4060 dw $4100,$41a0,$4240,$42e0,$4380,$4420,$44c0,$4560 dw $4600,$46a0,$4740,$47e0,$4880,$4920,$49c0,$4a60 dw $4b00,$4ba0,$4c40,$4ce0,$4d80,$4e20,$4ec0,$4f60 dw $5000,$50a0,$5140,$51e0,$5280,$5320,$53c0,$5460 dw $5500,$55a0,$5640,$56e0,$5780,$5820,$58c0,$5960 dw $5a00,$5aa0,$5b40,$5be0,$5c80,$5d20,$5dc0,$5e60 dw $5f00,$5fa0,$6040,$60e0,$6180,$6220,$62c0,$6360 dw $6400,$64a0,$6540,$65e0,$6680,$6720,$67c0,$6860 dw $6900,$69a0,$6a40,$6ae0,$6b80,$6c20,$6cc0,$6d60 dw $6e00,$6ea0,$6f40,$6fe0,$7080,$7120,$71c0,$7260 dw $7300,$73a0,$7440,$74e0,$7580,$7620,$76c0,$7760 dw $7800,$78a0,$7940,$79e0,$7a80,$7b20,$7bc0,$7c60
toddpw@nntp-server.caltech.edu (Todd P. Whitesel) (05/24/91)
acmfiu@serss0.fiu.edu (ACMFIU) writes: >below are three assembly routines. two i need help in optimizing and the >third i need help to get it to work. And how... First, I suggest you install a heartbeat task and use it to tell your event loop code when to blink. Read up in the Miscellaneous Tools chapter (I assume you know where that is...), hearbeat tasks are quite useful and convenient for this sort of thing. >the next routine, 'scroll_rect', is used to scroll my off-screen grafport >one line (line = length specified by ~line_height [height of line]). can >anyone optimize this? the code is self-explanatory. Well, if you want to make your source a lot easier to manage, make a macro that represents one or more loop iterations and edit the macro. Then you can experiment with faster unrolled code with far less stress than hand editing 80 copies of the same fragment. >the last routine, 'copy_grafport', is used to copy the data in an off-screen >grafport to an on-screen grafport, namely my window. i also need this >optimized. > _HideCursor Ugh. There's a ShieldCursor vector for this. It's in a technote, left an excercise for the reader. >:6 ldy ]x >:4 lda []off_image],y > sta []image],y > dey > dey > bpl :4 Jeezus. LHG at its slowest uses a loop like this. You can use MVP/MVN a lot of the time (yes, you really can use them -- get sneaky), and most of the time (except under Orca) you can map the stack into the shadowed graphics page and romp pixels to the screen. Sure it sounds sick but that's tough noogies. Think about it for a while and then mail me. Don't listen to Tim Meekins, or your code won't work with AppleTalk (in fact he's lucky it works at all -- do you EVER check to see where the standard GrafPort is, Tim?). Todd Whitesel toddpw @ tybalt.caltech.edu
meekins@kingkong.cis.ohio-state.edu (Tim Meekins) (05/24/91)
In article <1991May24.111453.27330@nntp-server.caltech.edu> toddpw@nntp-server.caltech.edu (Todd P. Whitesel) writes: >>:6 ldy ]x >>:4 lda []off_image],y >> sta []image],y >> dey >> dey >> bpl :4 > >Jeezus. LHG at its slowest uses a loop like this. You can use MVP/MVN a lot >of the time (yes, you really can use them -- get sneaky), and most of the >time (except under Orca) you can map the stack into the shadowed graphics >page and romp pixels to the screen. A lot also depends on where off_image and image point to. If you know they're in the same bank you can greatly speed this up. Also self-modifying code is handy in these situations. For minor speed improvement, try unrolling by a factor of 1. This will cut the bpl count in half. But then you need to know you're copying a min up 4 bytes instead of 2... > >Sure it sounds sick but that's tough noogies. Think about it for a while and >then mail me. Don't listen to Tim Meekins, or your code won't work with >AppleTalk (in fact he's lucky it works at all -- do you EVER check to see >where the standard GrafPort is, Tim?). > Come on Todd, that was only in ONE program a LONG time ago.. I challenge you to crash ZLaunch.... (Hmmm. well I'm assuming my newer demos work....) -- ++------------S-U-P-P-O-R-T---S-H-A-R-E-W-A-R-E---O-R---D-I-E-!-----------++ || Tim Meekins || Snail Mail: || Apple II || || meekins@cis.ohio-state.edu || 8372 Morris Rd. || Forever! || \\___timm@pro-tcc.cts.com________/\____Hilliard, OH 43026__/\_____________//
6600prao@ucsbuxa.ucsb.edu (Parik Rao) (05/25/91)
you can map the stack onto the graphic screen under orca. i have a init that allocates $01/2000, its the first init in my system. It also installs a cda that de-allocates shadowed-vid ram in case i wanna run prodos 8. You can also make your program a S16 program I guess, but the 1st method will allow you to keep it as a EXE file for a fast dev cycle. -- Apple II Forever | 6600prao@ucsbuxa.ucsb.edu | IBMs get the job done Parik Rao | Amiga - for the creative mind | Class of 1994 Macintosh - buy it or Apple will sue you.
ericmcg@pnet91.cts.com (Eric Mcgillicuddy) (05/25/91)
Do you want them optimized for speed or memory? Both right? Anyhow, the scroll_offscreen_grafport can be sped up considerably by using the MVP instruction. This is off the top of my head and untested, so..... :6 lda #num_bytes_2_move-1 ;159? _set_8_bit registers_XY ldx offimage+2 ;zero page variable sta move+1 ldx immage+2 stx move+2 ;self modifying code (note stx move+1) _set_16_bit_registers_XY ldx offimage ;holds address of LAST byte to move ldy image ;holds address of LAST byt of mvp #0,#0 ;destination - #0,#0 are dummy numbers That should do the copy much faster, 7 cycles per byte rather than 14 cycles per byte. A limitation is that the source and destination not cross banks. Use the same code with MVN to scroll DOWN. (or vice versa, it's late right now) Hope this is useful. UUCP: bkj386!pnet91!ericmcg INET: ericmcg@pnet91.cts.com
dlyons@Apple.COM (David A Lyons) (05/28/91)
In article <3638@kluge.fiu.edu> acmfiu@serss0.fiu.edu (ACMFIU) writes: >because i'm not using TextEdit for my program, i need to blink the insertion >cursor. everytime through my main event loop ('event_loop' below), i call >'blink_cursor' which accomplishes this. however, it doesn't blink the cursor >at all By the way (regarding a different message): If you're not getting null events, it's because you are getting an Update event which you are not handling. Window update events are not stored in the event queue-- if there is no higher-priority event, the system looks through all the windows front-to-back until it finds one with a non-empty update region. If you don't handle that by calling BeginUpdate, blahblahblah, EndUpdate, (which has the side-effect of emptying out the update region) then you'll get the same event again. I didn't examine your code closely enough to diagnose the real problem, but I did notice it barfs when the tick count value wraps around past zero (which happens every 2.2 years of continuous use)! -- I suggest a slightly simpler approach, using only the low word of the tick count, and also working properly when it wraps around past zero: pha pha _GetTick pla plx ;ignore high word tay ;keep copy of low word in Y sec sbc previous_ticks cmp blink_internal ;set earlier from GetCaretTime bcc dont_blink_it sty previous_ticks ... ;blink the thing, with InvertRect or whatever dont_blink_it Note that the calculation (Now - Previous) gives you a legitimate number of ticks even if it's something like $0005 minus $FFF0. That's $0015. (If you do "loop until current-ticks is greater-than-or-equal-to previous ticks plus increment" you can get stuck with "loop until X >= $FFFE", and X will go right past the big value back into the small values, if your main loop takes a significant amount of time per iteration.) -- David A. Lyons, Apple Computer, Inc. | DAL Systems Apple II System Software Engineer | P.O. Box 875 America Online: Dave Lyons | Cupertino, CA 95015-0875 GEnie:DAVE.LYONS CompuServe:72177,3233 Internet:dlyons@apple.com My opinions are my own, not Apple's.