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,$7c60toddpw@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.comdlyons@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.