a2d/desktop/mgtk.s

10310 lines
242 KiB
ArmAsm
Raw Normal View History

.setcpu "6502"
2017-09-17 18:18:47 +00:00
2017-09-30 02:51:11 +00:00
.include "apple2.inc"
2017-10-07 03:59:09 +00:00
.include "../inc/apple2.inc"
2017-09-30 22:32:38 +00:00
.include "../inc/prodos.inc"
2018-01-29 05:18:00 +00:00
.include "../mgtk.inc"
.include "../desktop.inc"
.include "../macros.inc"
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-02-21 16:06:38 +00:00
;;; MouseGraphics ToolKit
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 05:18:00 +00:00
.proc mgtk
.org $4000
2017-09-30 02:51:11 +00:00
2018-03-02 02:25:42 +00:00
screen_width := 560
screen_height := 192
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-07 03:59:09 +00:00
;;; ZP Usage
2017-10-07 20:59:25 +00:00
params_addr := $80
2018-01-29 16:25:56 +00:00
;; $8A initialized same way as current port (see $01 IMPL)
2017-12-16 05:36:09 +00:00
2017-10-15 02:45:51 +00:00
;; $A8 - Menu count
2018-03-24 04:35:53 +00:00
;; $A9-$AA - Address of current winfo
;; $AB-... - Copy of first 12 bytes of current winfo
2017-10-15 04:15:35 +00:00
2018-01-29 16:25:56 +00:00
;; $D0-$F3 - Current GrafPort
;; $D0-$DF - portmap
;; $D0-D3 - viewloc (x/y words)
;; $D4-D5 - mapbits - screen address = $2000
;; $D6-D7 - mapwidth - screen stride = $80
;; $D8-DF - maprect (x1/y1/x2/y2)
;; $E0-$E7 - penpattern
;; $E8-$E9 - colormasks (AND, OR)
;; $EA-$ED - penloc (x/y words)
;; $EE-$EF - penwidth/penheight
;; $F0 - penmode
;; $F1 - textback
;; $F2-$F3 - textfont
;; $F4-$F5 - Active port (???)
;; $F6-$FA - fill_eor_mask/x_offset/y_offset
;; $FB-$FC - glyph widths
2018-03-24 02:54:07 +00:00
;; $FD - font type (0=regular, $80=double width)
;; $FE - last glyph index (count is this + 1)
;; $FF - glyph height
2017-10-07 03:59:09 +00:00
2018-01-29 16:25:56 +00:00
current_grafport := $D0
current_portmap := $D0
current_viewloc_x := $D0
current_viewloc_y := $D2
current_mapbits := $D4
current_mapwidth := $D6
current_maprect_x1 := $D8
current_maprect_y1 := $DA
current_maprect_x2 := $DC
current_maprect_y2 := $DE
current_penpattern := $E0
current_colormasks := $E8
current_colormask_and := $E8
current_colormasks_or := $E9
current_penloc := $EA
current_penloc_x := $EA
current_penloc_y := $EC
current_pensize := $EE
current_penwidth := $EE
current_penheight := $EF
current_penmode := $F0
current_textback := $F1
current_textfont := $F2
2017-10-07 20:59:25 +00:00
2018-03-24 02:43:22 +00:00
active_port := $F4 ; address of live port block
2017-10-07 03:59:09 +00:00
2017-10-08 03:22:39 +00:00
fill_eor_mask := $F6
x_offset := $F7
y_offset := $F9
2017-10-08 03:22:39 +00:00
glyph_widths := $FB ; address
2018-03-24 02:54:07 +00:00
glyph_type := $FD ; 0=regular, $80=double width
glyph_last := $FE ; last glyph index
glyph_height_p := $FF ; glyph height
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 05:18:00 +00:00
;;; MGTK
2017-10-06 04:18:28 +00:00
2018-01-29 08:57:55 +00:00
.proc dispatch
2018-01-29 05:18:00 +00:00
.assert * = MGTK::MLI, error, "Entry point must be at $4000"
lda LOWSCR
sta SET80COL
2017-10-06 04:18:28 +00:00
bit preserve_zp_flag ; save ZP?
bpl adjust_stack
2018-01-29 05:18:00 +00:00
;; Save $80...$FF, swap in what MGTK needs at $F4...$FF
COPY_BYTES $80, $80, zp_saved
COPY_BYTES $C, active_saved, active_port
2018-01-29 16:25:56 +00:00
jsr apply_active_port_to_port
2017-10-06 04:18:28 +00:00
adjust_stack: ; Adjust stack to account for params
2017-10-07 20:59:25 +00:00
pla ; and stash address at params_addr.
sta params_addr
2017-09-17 18:18:47 +00:00
clc
2017-10-06 04:18:28 +00:00
adc #<3
2017-09-17 18:18:47 +00:00
tax
pla
2017-10-07 20:59:25 +00:00
sta params_addr+1
2017-10-06 04:18:28 +00:00
adc #>3
2017-09-17 18:18:47 +00:00
pha
txa
pha
2017-10-06 04:18:28 +00:00
2017-09-17 18:18:47 +00:00
tsx
2017-10-06 04:18:28 +00:00
stx stack_ptr_stash
ldy #1 ; Command index
2017-10-07 20:59:25 +00:00
lda (params_addr),y
2017-09-17 18:18:47 +00:00
asl a
tax
2018-03-24 02:43:22 +00:00
copy16 jump_table,x, jump_addr
2017-10-06 04:18:28 +00:00
2017-10-07 20:59:25 +00:00
iny ; Point params_addr at params
lda (params_addr),y
2017-09-17 18:18:47 +00:00
pha
iny
2017-10-07 20:59:25 +00:00
lda (params_addr),y
sta params_addr+1
2017-09-17 18:18:47 +00:00
pla
2017-10-07 20:59:25 +00:00
sta params_addr
2017-10-06 16:09:43 +00:00
;; Param length format is a byte pair;
;; * first byte is ZP address to copy bytes to
;; * second byte's high bit is "hide cursor" flag
;; * rest of second byte is # bytes to copy
2017-10-06 04:18:28 +00:00
ldy param_lengths+1,x ; Check param length...
2017-10-06 16:09:43 +00:00
bpl done_hiding
2017-10-06 04:18:28 +00:00
2017-10-06 16:09:43 +00:00
txa ; if high bit was set, stash
2017-10-07 20:59:25 +00:00
pha ; registers and params_addr and then
2017-10-06 16:09:43 +00:00
tya ; optionally hide cursor
2017-09-17 18:18:47 +00:00
pha
2017-10-07 20:59:25 +00:00
lda params_addr
2017-09-17 18:18:47 +00:00
pha
2017-10-07 20:59:25 +00:00
lda params_addr+1
2017-09-17 18:18:47 +00:00
pha
2018-02-18 19:33:21 +00:00
bit desktop_initialized_flag
2017-10-06 16:09:43 +00:00
bpl :+
2017-10-06 04:18:28 +00:00
jsr hide_cursor
2017-10-06 16:09:43 +00:00
: pla
2017-10-07 20:59:25 +00:00
sta params_addr+1
2017-09-17 18:18:47 +00:00
pla
2017-10-07 20:59:25 +00:00
sta params_addr
2017-09-17 18:18:47 +00:00
pla
2017-10-06 16:09:43 +00:00
and #$7F ; clear high bit in length count
2017-09-17 18:18:47 +00:00
tay
pla
tax
2017-10-06 04:18:28 +00:00
2017-10-06 16:09:43 +00:00
done_hiding:
lda param_lengths,x ; ZP offset for params
beq jump ; nothing to copy
2017-10-06 04:18:28 +00:00
sta store+1
2017-09-17 18:18:47 +00:00
dey
2017-10-07 20:59:25 +00:00
: lda (params_addr),y
2017-10-06 04:18:28 +00:00
store: sta $FF,y ; self modified
2017-09-18 15:10:19 +00:00
dey
2017-10-06 04:18:28 +00:00
bpl :-
2018-03-24 02:43:22 +00:00
jump_addr := *+1
2017-10-06 04:18:28 +00:00
jump: jsr $FFFF ; the actual call
2017-10-06 16:09:43 +00:00
;; Exposed for routines to call directly
cleanup:
2018-02-18 19:33:21 +00:00
bit desktop_initialized_flag
2017-10-06 16:09:43 +00:00
bpl :+
2017-10-06 04:18:28 +00:00
jsr show_cursor
2017-10-06 16:09:43 +00:00
: bit preserve_zp_flag
2017-10-06 04:18:28 +00:00
bpl exit_with_0
2018-01-29 16:25:56 +00:00
jsr apply_port_to_active_port
COPY_BYTES $C, active_port, active_saved
COPY_BYTES $80, zp_saved, $80
2017-10-06 04:18:28 +00:00
;; default is to return with A=0
exit_with_0:
lda #0
2017-10-06 16:09:43 +00:00
rts1: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-06 04:18:28 +00:00
;;; Routines can jmp here to exit with A set
2018-01-29 08:57:55 +00:00
exit_with_a:
2017-10-06 04:18:28 +00:00
pha
2018-01-29 08:57:55 +00:00
jsr dispatch::cleanup
2017-09-17 18:18:47 +00:00
pla
2017-10-06 04:18:28 +00:00
ldx stack_ptr_stash
2017-09-17 18:18:47 +00:00
txs
ldy #$FF
2017-10-06 04:18:28 +00:00
rts2: rts
2018-03-02 02:25:42 +00:00
;; TODO: Macro for exit_with_a
.macro exit_call arg
lda #arg
jmp exit_with_a
.endmacro
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 16:25:56 +00:00
;;; Copy port params (36 bytes) to/from active port addr
2017-09-17 18:18:47 +00:00
2018-01-29 16:25:56 +00:00
.proc apply_active_port_to_port
2018-05-26 01:39:43 +00:00
ldy #.sizeof(MGTK::GrafPort)-1
2018-01-29 16:25:56 +00:00
: lda (active_port),y
sta current_grafport,y
2017-09-17 18:18:47 +00:00
dey
2017-10-06 04:18:28 +00:00
bpl :-
2017-09-17 18:18:47 +00:00
rts
2017-10-06 04:18:28 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-01-29 16:25:56 +00:00
.proc apply_port_to_active_port
2018-05-26 01:39:43 +00:00
ldy #.sizeof(MGTK::GrafPort)-1
2018-01-29 16:25:56 +00:00
: lda current_grafport,y
sta (active_port),y
2017-09-17 18:18:47 +00:00
dey
2017-10-06 04:18:28 +00:00
bpl :-
2017-09-17 18:18:47 +00:00
rts
2017-10-06 04:18:28 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-06 04:18:28 +00:00
;;; Drawing calls show/hide cursor before/after
;;; A recursion count is kept to allow rentrancy.
hide_cursor_count:
.byte 0
2017-09-17 18:18:47 +00:00
2017-10-06 04:18:28 +00:00
.proc hide_cursor
dec hide_cursor_count
2018-01-29 08:57:55 +00:00
jmp HideCursorImpl
2017-10-06 04:18:28 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2017-10-06 04:18:28 +00:00
.proc show_cursor
bit hide_cursor_count
bpl rts2
inc hide_cursor_count
2018-01-29 08:57:55 +00:00
jmp ShowCursorImpl
2017-10-06 04:18:28 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 05:18:00 +00:00
;;; Jump table for MGTK entry point calls
2017-09-17 18:18:47 +00:00
2017-10-07 03:59:09 +00:00
;; jt_rts can be used if the only thing the
;; routine needs to do is copy params into
2018-01-29 16:25:56 +00:00
;; the zero page (port)
2018-01-29 08:57:55 +00:00
jt_rts := dispatch::rts1
2017-10-06 16:09:43 +00:00
2018-01-29 08:57:55 +00:00
jump_table:
.addr jt_rts ; $00 NoOp
2018-01-29 05:18:00 +00:00
;; ----------------------------------------
;; Graphics Primitives
;; Initialization Commands
2018-01-29 08:57:55 +00:00
.addr InitGrafImpl ; $01 InitGraf
.addr SetSwitchesImpl ; $02 SetSwitches
2018-01-29 05:18:00 +00:00
;; GrafPort Commands
2018-01-29 08:57:55 +00:00
.addr InitPortImpl ; $03 InitPort
.addr SetPortImpl ; $04 SetPort
.addr GetPortImpl ; $05 GetPort
.addr SetPortBitsImpl ; $06 SetPortBits
.addr SetPenModeImpl ; $07 SetPenMode
.addr SetPatternImpl ; $08 SetPattern
.addr jt_rts ; $09 SetColorMasks
.addr jt_rts ; $0A SetPenSize
.addr SetFontImpl ; $0B SetFont
.addr jt_rts ; $0C SetTextBG
2018-01-29 05:18:00 +00:00
;; Drawing Commands
2018-01-29 08:57:55 +00:00
.addr MoveImpl ; $0D Move
.addr jt_rts ; $0E MoveTo
.addr LineImpl ; $0F Line
.addr LineToImpl ; $10 LineTo
.addr PaintRectImpl ; $11 PaintRect
.addr FrameRectImpl ; $12 FrameRect
.addr InRectImpl ; $13 InRect
.addr PaintBitsImpl ; $14 PaintBits
.addr PaintPolyImpl ; $15 PaintPoly
.addr FramePolyImpl ; $16 FramePoly
.addr InPolyImpl ; $17 InPoly
2018-01-29 05:18:00 +00:00
;; Text Commands
2018-01-29 08:57:55 +00:00
.addr TextWidthImpl ; $18 TextWidth
.addr DrawTextImpl ; $19 DrawText
2018-01-29 05:18:00 +00:00
;; Utility Commands
2018-01-29 08:57:55 +00:00
.addr SetZP1Impl ; $1A SetZP1
.addr SetZP2Impl ; $1B SetZP2
.addr VersionImpl ; $1C Version
2018-01-29 05:18:00 +00:00
;; ----------------------------------------
2018-02-21 16:06:38 +00:00
;; MouseGraphics ToolKit
2018-01-29 05:18:00 +00:00
;; Initialization Calls
2018-01-29 08:57:55 +00:00
.addr StartDeskTopImpl ; $1D StartDeskTop
.addr StopDeskTopImpl ; $1E StopDeskTop
.addr SetUserHookImpl ; $1F SetUserHook
2018-02-18 19:33:21 +00:00
.addr AttachDriverImpl ; $20 AttachDriver
2018-01-29 08:57:55 +00:00
.addr ScaleMouseImpl ; $21 ScaleMouseImpl
.addr KeyboardMouse ; $22 KeyboardMouse
.addr GetIntHandlerImpl ; $23 GetIntHandler
2018-01-29 05:18:00 +00:00
;; Cursor Manager Calls
2018-01-29 08:57:55 +00:00
.addr SetCursorImpl ; $24 SetCursor
.addr ShowCursorImpl ; $25 ShowCursor
.addr HideCursorImpl ; $26 HideCursor
.addr ObscureCursorImpl ; $27 ObscureCursor
.addr GetCursorAddrImpl ; $28 GetCursorAddr
2018-01-29 05:18:00 +00:00
;; Event Manager Calls
2018-01-29 08:57:55 +00:00
.addr CheckEventsImpl ; $29 CheckEvents
.addr GetEventImpl ; $2A GetEvent
.addr FlushEventsImpl ; $2B FlushEvents
.addr PeekEventImpl ; $2C PeekEvent
.addr PostEventImpl ; $2D PostEvent
.addr SetKeyEventImpl ; $2E SetKeyEvent
2018-01-29 05:18:00 +00:00
;; Menu Manager Calls
2018-01-29 08:57:55 +00:00
.addr InitMenuImpl ; $2F InitMenu
.addr SetMenuImpl ; $30 SetMenu
.addr MenuSelectImpl ; $31 MenuSelect
.addr MenuKeyImpl ; $32 MenuKey
.addr HiliteMenuImpl ; $33 HiliteMenu
.addr DisableMenuImpl ; $34 DisableMenu
.addr DisableItemImpl ; $35 DisableItem
.addr CheckItemImpl ; $36 CheckItem
.addr SetMarkImpl ; $37 SetMark
2018-01-29 05:18:00 +00:00
;; Window Manager Calls
2018-01-29 08:57:55 +00:00
.addr OpenWindowImpl ; $38 OpenWindow
.addr CloseWindowImpl ; $39 CloseWindow
.addr CloseAllImpl ; $3A CloseAll
.addr GetWinPtrImpl ; $3B GetWinPtr
.addr GetWinPortImpl ; $3C GetWinPort
.addr SetWinPortImpl ; $3D SetWinPort
.addr BeginUpdateImpl ; $3E BeginUpdate
.addr EndUpdateImpl ; $3F EndUpdate
.addr FindWindowImpl ; $40 FindWindow
.addr FrontWindowImpl ; $41 FrontWindow
.addr SelectWindowImpl ; $42 SelectWindow
.addr TrackGoAwayImpl ; $43 TrackGoAway
.addr DragWindowImpl ; $44 DragWindow
.addr GrowWindowImpl ; $45 GrowWindow
.addr ScreenToWindowImpl ; $46 ScreenToWindow
.addr WindowToScreenImpl ; $47 WindowToScreenImpl
2018-01-29 05:18:00 +00:00
;; Control Manager Calls
2018-01-29 08:57:55 +00:00
.addr FindControlImpl ; $48 FindControl
.addr SetCtlMaxImpl ; $49 SetCtlMax
.addr TrackThumbImpl ; $4A TrackThumb
.addr UpdateThumbImpl ; $4B UpdateThumb
.addr ActivateCtlImpl ; $4C ActivateCtl
2018-03-24 02:43:22 +00:00
;; Extra Calls
.addr BitBltImpl ; $4D BitBlt
.addr SetMenuSelectionImpl; $4E SetMenuSelection
2017-10-01 23:17:04 +00:00
;; Entry point param lengths
2017-10-06 16:09:43 +00:00
;; (length, ZP destination, hide cursor flag)
2017-10-03 03:19:43 +00:00
param_lengths:
2017-10-06 16:09:43 +00:00
.macro PARAM_DEFN length, zp, cursor
2017-10-12 15:55:14 +00:00
.byte zp, ((length) | ((cursor) << 7))
2017-10-06 16:09:43 +00:00
.endmacro
2018-02-18 20:18:42 +00:00
;; ----------------------------------------
;; Graphics Primitives
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $00 NoOp
2018-02-18 20:18:42 +00:00
;; Initialization
PARAM_DEFN 0, $00, 0 ; $01 InitGraf
PARAM_DEFN 1, $82, 0 ; $02 SetSwitches
;; GrafPort
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $03 InitPort
PARAM_DEFN 36, current_grafport, 0 ; $04 SetPort
PARAM_DEFN 0, $00, 0 ; $05 GetPort
PARAM_DEFN 16, current_portmap, 0 ; $06 SetPortBits
PARAM_DEFN 1, current_penmode, 0 ; $07 SetPenMode
PARAM_DEFN 8, current_penpattern, 0 ; $08 SetPattern
PARAM_DEFN 2, current_colormasks, 0 ; $09 SetColorMasks
PARAM_DEFN 2, current_pensize, 0 ; $0A SetPenSize
PARAM_DEFN 0, $00, 0 ; $0B SetFont
PARAM_DEFN 1, current_textback, 0 ; $0C SetTextBG
2018-02-18 20:18:42 +00:00
;; Drawing
2018-01-29 16:25:56 +00:00
PARAM_DEFN 4, $A1, 0 ; $0D Move
PARAM_DEFN 4, current_penloc, 0 ; $0E MoveTo
PARAM_DEFN 4, $A1, 1 ; $0F Line
PARAM_DEFN 4, $92, 1 ; $10 LineTo
PARAM_DEFN 8, $92, 1 ; $11 PaintRect
PARAM_DEFN 8, $9F, 1 ; $12 FrameRect
PARAM_DEFN 8, $92, 0 ; $13 InRect
PARAM_DEFN 16, $8A, 0 ; $14 PaintBits
PARAM_DEFN 0, $00, 1 ; $15 PaintPoly
PARAM_DEFN 0, $00, 1 ; $16 FramePoly
PARAM_DEFN 0, $00, 0 ; $17 InPoly
2018-02-18 20:18:42 +00:00
;; Text
2018-01-29 16:25:56 +00:00
PARAM_DEFN 3, $A1, 0 ; $18 TextWidth
PARAM_DEFN 3, $A1, 1 ; $19 DrawText
2018-02-18 20:18:42 +00:00
;; Utility
2018-01-29 16:25:56 +00:00
PARAM_DEFN 1, $82, 0 ; $1A SetZP1
PARAM_DEFN 1, $82, 0 ; $1B SetZP2
PARAM_DEFN 0, $00, 0 ; $1C Version
2018-02-18 20:18:42 +00:00
;; ----------------------------------------
2018-02-21 16:06:38 +00:00
;; MouseGraphics ToolKit Calls
2018-02-18 20:18:42 +00:00
;; Initialization
2018-01-29 16:25:56 +00:00
PARAM_DEFN 12, $82, 0 ; $1D StartDeskTop
PARAM_DEFN 0, $00, 0 ; $1E StopDeskTop
2018-02-18 20:18:42 +00:00
PARAM_DEFN 3, $82, 0 ; $1F SetUserHook
2018-02-18 19:33:21 +00:00
PARAM_DEFN 2, $82, 0 ; $20 AttachDriver
2018-01-29 16:25:56 +00:00
PARAM_DEFN 2, $82, 0 ; $21 ScaleMouse
PARAM_DEFN 0, $00, 0 ; $22 KeyboardMouse
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $23 GetIntHandler
2018-02-18 20:18:42 +00:00
;; Cursor Manager
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $24 SetCursor
PARAM_DEFN 0, $00, 0 ; $25 ShowCursor
PARAM_DEFN 0, $00, 0 ; $26 HideCursor
PARAM_DEFN 0, $00, 0 ; $27 ObscureCursor
PARAM_DEFN 0, $00, 0 ; $28 GetCursorAddr
2018-02-18 20:18:42 +00:00
;; Event Manager
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $29 CheckEvents
PARAM_DEFN 0, $00, 0 ; $2A GetEvent
PARAM_DEFN 0, $00, 0 ; $2B FlushEvents
PARAM_DEFN 0, $00, 0 ; $2C PeekEvent
PARAM_DEFN 5, $82, 0 ; $2D PostEvent
PARAM_DEFN 1, $82, 0 ; $2E SetKeyEvent
2018-02-18 20:18:42 +00:00
;; Menu Manager
2018-01-29 16:25:56 +00:00
PARAM_DEFN 4, $82, 0 ; $2F InitMenu
PARAM_DEFN 0, $00, 0 ; $30 SetMenu
PARAM_DEFN 0, $00, 0 ; $31 MenuSelect
PARAM_DEFN 4, $C7, 0 ; $32 MenuKey
PARAM_DEFN 1, $C7, 0 ; $33 HiliteMenu
PARAM_DEFN 2, $C7, 0 ; $34 DisableMenu
PARAM_DEFN 3, $C7, 0 ; $35 DisableItem
PARAM_DEFN 3, $C7, 0 ; $36 CheckItem
PARAM_DEFN 4, $C7, 0 ; $37 SetMark
2018-02-18 20:18:42 +00:00
;; Window Manager
2018-01-29 16:25:56 +00:00
PARAM_DEFN 0, $00, 0 ; $38 OpenWindow
PARAM_DEFN 1, $82, 0 ; $39 CloseWindow
PARAM_DEFN 0, $00, 0 ; $3A CloseAll
PARAM_DEFN 1, $82, 0 ; $3B GetWinPtr
PARAM_DEFN 3, $82, 0 ; $3C GetWinPort
PARAM_DEFN 2, $82, 0 ; $3D SetWinPort
PARAM_DEFN 1, $82, 0 ; $3E BeginUpdate
PARAM_DEFN 1, $82, 0 ; $3F EndUpdate
PARAM_DEFN 4, current_penloc, 0 ; $40 FindWindow
PARAM_DEFN 0, $00, 0 ; $41 FrontWindow
PARAM_DEFN 1, $82, 0 ; $42 SelectWindow
PARAM_DEFN 0, $00, 0 ; $43 TrackGoAway
PARAM_DEFN 5, $82, 0 ; $44 DragWindow
PARAM_DEFN 5, $82, 0 ; $45 GrowWindow
PARAM_DEFN 5, $82, 0 ; $46 ScreenToWindow
PARAM_DEFN 5, $82, 0 ; $47 WindowToScreen
2018-02-18 20:18:42 +00:00
;; Control Manager
2018-01-29 16:25:56 +00:00
PARAM_DEFN 4, current_penloc, 0 ; $48 FindControl
PARAM_DEFN 2, $82, 0 ; $49 SetCtlMax
2018-01-29 16:25:56 +00:00
PARAM_DEFN 5, $82, 0 ; $4A TrackThumb
PARAM_DEFN 2, $8C, 0 ; $4B UpdateThumb
2018-01-29 16:25:56 +00:00
PARAM_DEFN 2, $8C, 0 ; $4C ActivateCtl
2018-03-26 04:04:15 +00:00
;; Extra Calls
PARAM_DEFN 16, $8A, 0 ; $4D BitBlt
2018-03-26 04:04:15 +00:00
PARAM_DEFN 2, $82, 0 ; $4E SetMenuSelection
2017-10-06 16:09:43 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
;;; Pre-Shift Tables
2017-10-06 16:09:43 +00:00
shift_1_aux:
.byte $00,$02,$04,$06,$08,$0A,$0C,$0E
2017-09-18 15:10:19 +00:00
.byte $10,$12,$14,$16,$18,$1A,$1C,$1E
.byte $20,$22,$24,$26,$28,$2A,$2C,$2E
.byte $30,$32,$34,$36,$38,$3A,$3C,$3E
.byte $40,$42,$44,$46,$48,$4A,$4C,$4E
.byte $50,$52,$54,$56,$58,$5A,$5C,$5E
.byte $60,$62,$64,$66,$68,$6A,$6C,$6E
.byte $70,$72,$74,$76,$78,$7A,$7C,$7E
.byte $00,$02,$04,$06,$08,$0A,$0C,$0E
.byte $10,$12,$14,$16,$18,$1A,$1C,$1E
.byte $20,$22,$24,$26,$28,$2A,$2C,$2E
.byte $30,$32,$34,$36,$38,$3A,$3C,$3E
.byte $40,$42,$44,$46,$48,$4A,$4C,$4E
.byte $50,$52,$54,$56,$58,$5A,$5C,$5E
.byte $60,$62,$64,$66,$68,$6A,$6C,$6E
.byte $70,$72,$74,$76,$78,$7A,$7C,$7E
2017-10-08 15:42:27 +00:00
shift_1_main:
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-09-18 15:10:19 +00:00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
2017-09-30 02:14:47 +00:00
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
2017-10-08 15:42:27 +00:00
shift_2_aux:
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
2017-09-30 02:14:47 +00:00
.byte $20,$24,$28,$2C,$30,$34,$38,$3C
.byte $40,$44,$48,$4C,$50,$54,$58,$5C
.byte $60,$64,$68,$6C,$70,$74,$78,$7C
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $20,$24,$28,$2C,$30,$34,$38,$3C
.byte $40,$44,$48,$4C,$50,$54,$58,$5C
.byte $60,$64,$68,$6C,$70,$74,$78,$7C
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $20,$24,$28,$2C,$30,$34,$38,$3C
.byte $40,$44,$48,$4C,$50,$54,$58,$5C
.byte $60,$64,$68,$6C,$70,$74,$78,$7C
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $20,$24,$28,$2C,$30,$34,$38,$3C
.byte $40,$44,$48,$4C,$50,$54,$58,$5C
.byte $60,$64,$68,$6C,$70,$74,$78,$7C
2017-10-08 15:42:27 +00:00
shift_2_main:
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-09-30 02:14:47 +00:00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $03,$03,$03,$03,$03,$03,$03,$03
2017-10-08 15:42:27 +00:00
shift_3_aux:
.byte $00,$08,$10,$18,$20,$28,$30,$38
2017-09-30 02:14:47 +00:00
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
.byte $00,$08,$10,$18,$20,$28,$30,$38
.byte $40,$48,$50,$58,$60,$68,$70,$78
2017-10-08 15:42:27 +00:00
shift_3_main:
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-09-30 02:14:47 +00:00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $04,$04,$04,$04,$04,$04,$04,$04
.byte $04,$04,$04,$04,$04,$04,$04,$04
.byte $05,$05,$05,$05,$05,$05,$05,$05
.byte $05,$05,$05,$05,$05,$05,$05,$05
.byte $06,$06,$06,$06,$06,$06,$06,$06
.byte $06,$06,$06,$06,$06,$06,$06,$06
.byte $07,$07,$07,$07,$07,$07,$07,$07
.byte $07,$07,$07,$07,$07,$07,$07,$07
2017-10-08 15:42:27 +00:00
shift_4_aux:
.byte $00,$10,$20,$30,$40,$50,$60,$70
2017-09-30 02:14:47 +00:00
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
.byte $00,$10,$20,$30,$40,$50,$60,$70
2017-10-08 15:42:27 +00:00
shift_4_main:
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-09-30 02:14:47 +00:00
.byte $01,$01,$01,$01,$01,$01,$01,$01
.byte $02,$02,$02,$02,$02,$02,$02,$02
.byte $03,$03,$03,$03,$03,$03,$03,$03
.byte $04,$04,$04,$04,$04,$04,$04,$04
.byte $05,$05,$05,$05,$05,$05,$05,$05
.byte $06,$06,$06,$06,$06,$06,$06,$06
.byte $07,$07,$07,$07,$07,$07,$07,$07
.byte $08,$08,$08,$08,$08,$08,$08,$08
.byte $09,$09,$09,$09,$09,$09,$09,$09
.byte $0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A
.byte $0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B
.byte $0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C
.byte $0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D
.byte $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E
.byte $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
2017-10-08 15:42:27 +00:00
shift_5_aux:
.byte $00,$20,$40,$60,$00,$20,$40,$60
2017-09-30 02:14:47 +00:00
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
.byte $00,$20,$40,$60,$00,$20,$40,$60
2017-10-08 15:42:27 +00:00
shift_5_main:
.byte $00,$00,$00,$00,$01,$01,$01,$01
2017-09-30 02:14:47 +00:00
.byte $02,$02,$02,$02,$03,$03,$03,$03
.byte $04,$04,$04,$04,$05,$05,$05,$05
.byte $06,$06,$06,$06,$07,$07,$07,$07
.byte $08,$08,$08,$08,$09,$09,$09,$09
.byte $0A,$0A,$0A,$0A,$0B,$0B,$0B,$0B
.byte $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D
.byte $0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F
.byte $10,$10,$10,$10,$11,$11,$11,$11
.byte $12,$12,$12,$12,$13,$13,$13,$13
.byte $14,$14,$14,$14,$15,$15,$15,$15
.byte $16,$16,$16,$16,$17,$17,$17,$17
.byte $18,$18,$18,$18,$19,$19,$19,$19
.byte $1A,$1A,$1A,$1A,$1B,$1B,$1B,$1B
.byte $1C,$1C,$1C,$1C,$1D,$1D,$1D,$1D
.byte $1E,$1E,$1E,$1E,$1F,$1F,$1F,$1F
2017-10-08 15:42:27 +00:00
shift_6_aux:
.byte $00,$40,$00,$40,$00,$40,$00,$40
2017-09-30 02:14:47 +00:00
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
.byte $00,$40,$00,$40,$00,$40,$00,$40
2017-10-08 15:42:27 +00:00
shift_6_main:
.byte $00,$00,$01,$01,$02,$02,$03,$03
2017-09-30 02:14:47 +00:00
.byte $04,$04,$05,$05,$06,$06,$07,$07
.byte $08,$08,$09,$09,$0A,$0A,$0B,$0B
.byte $0C,$0C,$0D,$0D,$0E,$0E,$0F,$0F
.byte $10,$10,$11,$11,$12,$12,$13,$13
.byte $14,$14,$15,$15,$16,$16,$17,$17
.byte $18,$18,$19,$19,$1A,$1A,$1B,$1B
.byte $1C,$1C,$1D,$1D,$1E,$1E,$1F,$1F
.byte $20,$20,$21,$21,$22,$22,$23,$23
.byte $24,$24,$25,$25,$26,$26,$27,$27
.byte $28,$28,$29,$29,$2A,$2A,$2B,$2B
.byte $2C,$2C,$2D,$2D,$2E,$2E,$2F,$2F
.byte $30,$30,$31,$31,$32,$32,$33,$33
.byte $34,$34,$35,$35,$36,$36,$37,$37
.byte $38,$38,$39,$39,$3A,$3A,$3B,$3B
.byte $3C,$3C,$3D,$3D,$3E,$3E,$3F,$3F
2017-10-08 15:42:27 +00:00
div7_table:
.byte $00,$00,$00,$00,$00,$00,$00
.byte $01,$01,$01,$01,$01,$01,$01,$02
2017-09-18 15:10:19 +00:00
.byte $02,$02,$02,$02,$02,$02,$03,$03
.byte $03,$03,$03,$03,$03,$04,$04,$04
.byte $04,$04,$04,$04,$05,$05,$05,$05
.byte $05,$05,$05,$06,$06,$06,$06,$06
.byte $06,$06,$07,$07,$07,$07,$07,$07
2017-09-30 02:14:47 +00:00
.byte $07,$08,$08,$08,$08,$08,$08,$08
.byte $09,$09,$09,$09,$09,$09,$09,$0A
.byte $0A,$0A,$0A,$0A,$0A,$0A,$0B,$0B
.byte $0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C
.byte $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D
.byte $0D,$0D,$0D,$0E,$0E,$0E,$0E,$0E
.byte $0E,$0E,$0F,$0F,$0F,$0F,$0F,$0F
.byte $0F,$10,$10,$10,$10,$10,$10,$10
.byte $11,$11,$11,$11,$11,$11,$11,$12
.byte $12,$12,$12,$12,$12,$12,$13,$13
.byte $13,$13,$13,$13,$13,$14,$14,$14
.byte $14,$14,$14,$14,$15,$15,$15,$15
.byte $15,$15,$15,$16,$16,$16,$16,$16
.byte $16,$16,$17,$17,$17,$17,$17,$17
.byte $17,$18,$18,$18,$18,$18,$18,$18
.byte $19,$19,$19,$19,$19,$19,$19,$1A
.byte $1A,$1A,$1A,$1A,$1A,$1A,$1B,$1B
.byte $1B,$1B,$1B,$1B,$1B,$1C,$1C,$1C
.byte $1C,$1C,$1C,$1C,$1D,$1D,$1D,$1D
.byte $1D,$1D,$1D,$1E,$1E,$1E,$1E,$1E
.byte $1E,$1E,$1F,$1F,$1F,$1F,$1F,$1F
.byte $1F,$20,$20,$20,$20,$20,$20,$20
.byte $21,$21,$21,$21,$21,$21,$21,$22
.byte $22,$22,$22,$22,$22,$22,$23,$23
.byte $23,$23,$23,$23,$23,$24,$24,$24
.byte $24
mod7_table:
.byte $00,$01,$02,$03
.byte $04,$05,$06,$00,$01,$02,$03,$04
2017-09-18 15:10:19 +00:00
.byte $05,$06,$00,$01,$02,$03,$04,$05
.byte $06,$00,$01,$02,$03,$04,$05,$06
.byte $00,$01,$02,$03,$04,$05,$06,$00
.byte $01,$02,$03,$04,$05,$06,$00,$01
.byte $02,$03,$04,$05,$06,$00,$01,$02
.byte $03,$04,$05,$06,$00,$01,$02,$03
.byte $04,$05,$06,$00,$01,$02,$03,$04
.byte $05,$06,$00,$01,$02,$03,$04,$05
.byte $06,$00,$01,$02,$03,$04,$05,$06
.byte $00,$01,$02,$03,$04,$05,$06,$00
.byte $01,$02,$03,$04,$05,$06,$00,$01
.byte $02,$03,$04,$05,$06,$00,$01,$02
.byte $03,$04,$05,$06,$00,$01,$02,$03
.byte $04,$05,$06,$00,$01,$02,$03,$04
.byte $05,$06,$00,$01,$02,$03,$04,$05
2017-09-18 15:10:19 +00:00
.byte $06,$00,$01,$02,$03,$04,$05,$06
.byte $00,$01,$02,$03,$04,$05,$06,$00
.byte $01,$02,$03,$04,$05,$06,$00,$01
.byte $02,$03,$04,$05,$06,$00,$01,$02
.byte $03,$04,$05,$06,$00,$01,$02,$03
.byte $04,$05,$06,$00,$01,$02,$03,$04
.byte $05,$06,$00,$01,$02,$03,$04,$05
.byte $06,$00,$01,$02,$03,$04,$05,$06
.byte $00,$01,$02,$03,$04,$05,$06,$00
.byte $01,$02,$03,$04,$05,$06,$00,$01
.byte $02,$03,$04,$05,$06,$00,$01,$02
.byte $03,$04,$05,$06,$00,$01,$02,$03
.byte $04,$05,$06,$00,$01,$02,$03,$04
.byte $05,$06,$00,$01,$02,$03,$04,$05
.byte $06,$00,$01,$02,$03,$04,$05,$06
2017-09-30 02:14:47 +00:00
.byte $00,$01,$02,$03
2017-09-30 22:32:38 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-06 16:09:43 +00:00
2017-09-30 22:32:38 +00:00
hires_table_lo:
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-09-18 15:10:19 +00:00
.byte $80,$80,$80,$80,$80,$80,$80,$80
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $80,$80,$80,$80,$80,$80,$80,$80
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $80,$80,$80,$80,$80,$80,$80,$80
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $80,$80,$80,$80,$80,$80,$80,$80
.byte $28,$28,$28,$28,$28,$28,$28,$28
.byte $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
.byte $28,$28,$28,$28,$28,$28,$28,$28
.byte $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
.byte $28,$28,$28,$28,$28,$28,$28,$28
.byte $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
.byte $28,$28,$28,$28,$28,$28,$28,$28
.byte $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
.byte $50,$50,$50,$50,$50,$50,$50,$50
.byte $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
.byte $50,$50,$50,$50,$50,$50,$50,$50
.byte $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
.byte $50,$50,$50,$50,$50,$50,$50,$50
.byte $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
.byte $50,$50,$50,$50,$50,$50,$50,$50
.byte $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
2017-09-30 22:32:38 +00:00
hires_table_hi:
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
2017-09-18 15:10:19 +00:00
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
2017-09-30 02:14:47 +00:00
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $00,$04,$08,$0C,$10,$14,$18,$1C
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $01,$05,$09,$0D,$11,$15,$19,$1D
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
.byte $02,$06,$0A,$0E,$12,$16,$1A,$1E
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
.byte $03,$07,$0B,$0F,$13,$17,$1B,$1F
2017-09-30 22:32:38 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; Routines called during PaintRect etc based on
2018-01-29 16:25:56 +00:00
;;; current_penmode
2017-10-06 16:09:43 +00:00
;; ZP usage
src_addr := $82 ; pointer to source bitmap
vid_addr := $84 ; pointer to video memory
left_bytes := $86 ; offset of leftmost coordinate in chars (0-39)
bits_addr := $8E ; pointer to pattern/bitmap
2018-03-30 14:58:10 +00:00
left_mod14 := $87 ; starting x-coordinate mod 14
left_sidemask := $88 ; bitmask applied to clip left edge of rect
right_sidemask := $89 ; bitmask applied to clip right edge of rect
src_y_coord := $8C
src_mapwidth := $90 ; source stride; $80 = DHGR layout
width_bytes := $91 ; width of rectangle in chars
left_masks_table := $92 ; bitmasks for left edge indexed by page (0=main, 1=aux)
right_masks_table := $96 ; bitmasks for right edge indexed by page (0=main, 1=aux)
top := $94 ; top/starting/current y-coordinate
bottom := $98 ; bottom/ending/maximum y-coordinate
left := $92
right := $96
fixed_div_dividend := $A1 ; parameters used by fixed_div proc
fixed_div_divisor := $A3
fixed_div_quotient := $9F ; fixed 16.16 format
;; Text page usage (main/aux)
pattern_buffer := $0400 ; buffer for currently selected pattern (page-aligned)
bitmap_buffer := $0601 ; scratchpad area for drawing bitmaps/patterns
poly_maxima_links := $0428
poly_maxima_prev_vertex := $0468
poly_maxima_next_vertex := $04A8
poly_maxima_slope0 := $0528
poly_maxima_slope1 := $04E8
poly_maxima_slope2 := $0568
poly_maxima_slope3 := $05A8
poly_maxima_yl_table := $05E8
poly_vertex_prev_link := $0680
poly_vertex_next_link := $06BC
poly_xl_buffer := $0700
poly_xh_buffer := $073C
poly_yl_buffer := $0780
poly_yh_buffer := $07BC
.assert <pattern_buffer = 0, error, "pattern_buffer must be page-aligned"
.proc fillmode_copy
lda (vid_addr),y
eor (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and right_sidemask
eor (vid_addr),y
2017-10-08 03:22:39 +00:00
bcc :+
loop: lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
2018-01-29 16:25:56 +00:00
: and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
dey
2017-10-08 03:22:39 +00:00
bne loop
.endproc
.proc fillmode_copy_onechar
lda (vid_addr),y
eor (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and left_sidemask
eor (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
rts
2017-10-08 03:22:39 +00:00
.endproc
2017-10-03 03:25:53 +00:00
.proc fillmode_or
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and right_sidemask
2017-10-08 03:22:39 +00:00
bcc :+
loop: lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
: ora (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
dey
2017-10-08 03:22:39 +00:00
bne loop
.endproc
.proc fillmode_or_onechar
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and left_sidemask
ora (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
rts
2017-10-08 03:22:39 +00:00
.endproc
2017-10-03 03:25:53 +00:00
.proc fillmode2_xor
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and right_sidemask
2017-10-08 03:22:39 +00:00
bcc :+
loop: lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
: eor (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
dey
2017-10-08 03:22:39 +00:00
bne loop
.endproc
.proc fillmode2_xor_onechar
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and left_sidemask
eor (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
rts
2017-10-08 03:22:39 +00:00
.endproc
2017-10-03 03:25:53 +00:00
.proc fillmode_bic
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and right_sidemask
2017-10-08 03:22:39 +00:00
bcc :+
loop: lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
: eor #$FF
and (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
dey
2017-10-08 03:22:39 +00:00
bne loop
.endproc
.proc fillmode_bic_onechar
lda (bits_addr),y
2017-10-08 03:22:39 +00:00
eor fill_eor_mask
and left_sidemask
2017-10-03 03:25:53 +00:00
eor #$FF
and (vid_addr),y
2018-01-29 16:25:56 +00:00
and current_colormask_and
ora current_colormasks_or
sta (vid_addr),y
2017-10-03 03:25:53 +00:00
rts
2017-10-08 03:22:39 +00:00
.endproc
2017-10-03 03:25:53 +00:00
;; Main fill loop.
.proc fill_next_line
cpx bottom ; fill done?
beq :+
2017-10-03 03:25:53 +00:00
inx
get_srcbits_jmp:
get_srcbits_jmp_addr := *+1
jmp start_fill_jmp ; patched to *_get_srcbits if there
; is a source bitmap
: rts
.endproc
;; Copy a line of source data from a non-display bitmap buffer to
;; the staging buffer at $0601.
.proc ndbm_get_srcbits
lda load_addr
adc src_mapwidth
sta load_addr
bcc :+
inc load_addr+1
: ldy src_width_bytes
:
load_addr := *+1
lda $FFFF,y ; off-screen BMP will be patched here
2017-10-03 03:25:53 +00:00
and #$7F
sta bitmap_buffer,y
2017-10-03 03:25:53 +00:00
dey
bpl :-
bmi shift_bits_clc_jmp
.endproc
;; Copy a line of source data from the DHGR screen to the staging
;; buffer at $0601.
.proc dhgr_get_srcbits
index := $81
src_byte_off := $8A ; char offset within source line
ldy src_y_coord
inc src_y_coord
2017-10-03 03:25:53 +00:00
lda hires_table_hi,y
ora $80
sta src_addr+1
2017-10-03 03:25:53 +00:00
lda hires_table_lo,y
adc src_byte_off
sta src_addr
get_bits:
stx index
2017-10-14 06:23:31 +00:00
ldy #0
ldx #0
loop: sta HISCR
lda (src_addr),y
2017-10-03 03:25:53 +00:00
and #$7F
sta LOWSCR
offset1_addr := *+1
sta bitmap_buffer,x
lda (src_addr),y
2017-10-03 03:25:53 +00:00
and #$7F
offset2_addr := *+1
sta bitmap_buffer+1,x
2017-10-03 03:25:53 +00:00
iny
inx
inx
cpx src_width_bytes
bcc loop
beq loop
ldx index
shift_bits_clc_jmp:
clc
shift_bits_jmp:
shift_bits_jmp_addr := *+1
jmp shift_line_jmp ; patched to dhgr_shift_bits when needed
.endproc
shift_bits_clc_jmp := dhgr_get_srcbits::shift_bits_clc_jmp
;; Subprocedure used to shift bitmap data by a number of bits.
.proc dhgr_shift_bits
index := $82
stx index
ldy src_width_bytes
2017-10-03 03:25:53 +00:00
lda #$00
loop: ldx bitmap_buffer,y
shift_main_addr := *+1
ora shift_1_main,x
offset2_addr := *+1
sta bitmap_buffer+1,y
shift_aux_addr := *+1
lda shift_1_aux,x
2017-10-03 03:25:53 +00:00
dey
bpl loop
offset1_addr := *+1
sta bitmap_buffer
ldx index
shift_line_jmp:
shift_line_jmp_addr := *+1
jmp dhgr_next_line ; patched to dhgr_shift_line when needed
.endproc
shift_line_jmp := dhgr_shift_bits::shift_line_jmp
;; Subprocedure used to shift bitmap data by an integral number of
;; chars.
.proc dhgr_shift_line
index := $82
2017-10-03 03:25:53 +00:00
stx index
2017-10-14 06:23:31 +00:00
ldx #0
ldy #0
loop:
offset1_addr := *+1
lda bitmap_buffer,x
sta HISCR
sta bitmap_buffer,y
sta LOWSCR
offset2_addr := *+1
lda bitmap_buffer+1,x
sta bitmap_buffer,y
2017-10-03 03:25:53 +00:00
inx
inx
iny
cpy width_bytes
bcc loop
beq loop
ldx index
jmp dhgr_next_line
.endproc
2017-10-03 03:25:53 +00:00
;; Entry point to start bit blit operation.
.proc bit_blit
ldx top
2017-10-03 03:25:53 +00:00
clc
jmp fill_next_line::get_srcbits_jmp
.endproc
;; Entry point to start fill after fill mode and destination have
;; been set.
.proc do_fill
ldx no_srcbits_addr ; Disable srcbits fetching
stx fill_next_line::get_srcbits_jmp_addr ; for fill operation.
ldx no_srcbits_addr+1
stx fill_next_line::get_srcbits_jmp_addr+1
ldx top
;; Fall-through
.endproc
start_fill_jmp:
start_fill_jmp_addr := *+1
jmp dhgr_start_fill ; patched to *_start_fill
;; Start a fill targeting a non-display bitmap (NDBM)
.proc ndbm_start_fill
txa ; pattern y-offset
2017-10-03 03:25:53 +00:00
ror a
ror a
ror a
and #$C0 ; to high 2 bits
ora left_bytes
sta src_addr
2017-10-03 03:25:53 +00:00
lda #>pattern_buffer
adc #0
sta src_addr+1
jmp dhgr_get_srcbits::get_bits
.endproc
;; Start a fill targeting the DHGR screen.
.proc dhgr_start_fill
txa ; pattern y-offset
2017-10-03 03:25:53 +00:00
ror a
ror a
ror a
and #$C0 ; to high 2 bits
ora left_bytes
sta bits_addr
lda #>pattern_buffer
2017-10-14 06:23:31 +00:00
adc #0
sta bits_addr+1
next_line_jmp_addr := *+1
jmp dhgr_next_line
.endproc
2017-10-03 03:25:53 +00:00
;; Advance to the next line and fill (non-display bitmap
;; destination.)
.proc ndbm_next_line
lda vid_addr
2017-10-03 03:25:53 +00:00
clc
2018-01-29 16:25:56 +00:00
adc current_mapwidth
sta vid_addr
bcc :+
inc vid_addr+1
2017-10-03 03:25:53 +00:00
clc
: ldy width_bytes
jsr fillmode_jmp
jmp fill_next_line
.endproc
2017-10-03 03:25:53 +00:00
;; Set vid_addr for the next line and fill (DHGR destination.)
.proc dhgr_next_line
lda hires_table_hi,x
2018-01-29 16:25:56 +00:00
ora current_mapbits+1
sta vid_addr+1
2017-10-03 03:25:53 +00:00
lda hires_table_lo,x
clc
adc left_bytes
sta vid_addr
ldy #1 ; aux mem
jsr dhgr_fill_line
ldy #0 ; main mem
jsr dhgr_fill_line
jmp fill_next_line
.endproc
;; Fill one line in either main or aux screen memory.
.proc dhgr_fill_line
sta LOWSCR,y
2017-10-03 03:25:53 +00:00
lda left_masks_table,y
2017-10-03 03:25:53 +00:00
ora #$80
sta left_sidemask
lda right_masks_table,y
2017-10-03 03:25:53 +00:00
ora #$80
sta right_sidemask
ldy width_bytes
;; Fall-through
.endproc
fillmode_jmp:
jmp fillmode_copy ; modified with fillmode routine
2017-10-03 03:25:53 +00:00
;; Address of jump used when drawing from a pattern rather than
;; source data bits.
no_srcbits_addr:
.addr start_fill_jmp
main_right_masks:
.byte $00,$00,$00,$00,$00,$00,$00
aux_right_masks:
.byte $01,$03,$07,$0F,$1F,$3F,$7F
main_left_masks:
.byte $7F,$7F,$7F,$7F,$7F,$7F,$7F
aux_left_masks:
.byte $7F,$7E,$7C,$78,$70,$60,$40
.byte $00,$00,$00,$00,$00,$00,$00
2017-10-03 03:25:53 +00:00
2017-10-08 03:22:39 +00:00
;; Tables used for fill modes
; Fill routines that handle >1 char between left and right limits.
2017-10-08 03:22:39 +00:00
fill_mode_table:
.addr fillmode_copy,fillmode_or,fillmode2_xor,fillmode_bic
.addr fillmode_copy,fillmode_or,fillmode2_xor,fillmode_bic
2017-10-08 03:22:39 +00:00
; Fill routines that handle only 1 char.
fill_mode_table_onechar:
.addr fillmode_copy_onechar,fillmode_or_onechar,fillmode2_xor_onechar,fillmode_bic_onechar
.addr fillmode_copy_onechar,fillmode_or_onechar,fillmode2_xor_onechar,fillmode_bic_onechar
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetPenMode
2017-10-03 03:05:07 +00:00
.proc SetPenModeImpl
2018-01-29 16:25:56 +00:00
lda current_penmode
2017-10-14 06:23:31 +00:00
ldx #0
cmp #4
2017-10-08 03:22:39 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
ldx #$7F
2017-10-08 03:22:39 +00:00
: stx fill_eor_mask
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-01-29 08:57:55 +00:00
;; Called from PaintRect, DrawText, etc to configure
2017-10-08 03:22:39 +00:00
;; fill routines from mode.
.proc set_up_fill_mode
x1 := $92
x2 := $96
x1_bytes := $86
x2_bytes := $82
2018-03-22 02:29:14 +00:00
add16 x_offset, x2, x2
add16 y_offset, bottom, bottom
2018-03-22 02:29:14 +00:00
add16 x_offset, x1, x1
add16 y_offset, top, top
lsr x2+1
2017-10-08 03:22:39 +00:00
beq :+
jmp rl_ge256
2017-09-17 18:18:47 +00:00
: lda x2
2017-09-18 15:10:19 +00:00
ror a
2017-09-17 18:18:47 +00:00
tax
lda div7_table,x
ldy mod7_table,x
set_x2_bytes:
sta x2_bytes
2017-09-17 18:18:47 +00:00
tya
rol a
tay
lda aux_right_masks,y
sta right_masks_table+1
lda main_right_masks,y
sta right_masks_table
lsr x1+1
bne ll_ge256
lda x1
2017-09-17 18:18:47 +00:00
ror a
tax
lda div7_table,x
ldy mod7_table,x
set_x1_bytes:
sta x1_bytes
2017-09-30 02:14:47 +00:00
tya
2017-09-17 18:18:47 +00:00
rol a
tay
2018-03-30 14:58:10 +00:00
sty left_mod14
lda aux_left_masks,y
sta left_masks_table+1
lda main_left_masks,y
sta left_masks_table
lda x2_bytes
2017-09-17 18:18:47 +00:00
sec
sbc x1_bytes
set_width: ; Set width for destination.
sta width_bytes
2017-09-17 18:18:47 +00:00
pha
2018-01-29 16:25:56 +00:00
lda current_penmode
2017-09-17 18:18:47 +00:00
asl a
tax
pla
bne :+ ; Check if one or more than one is needed
lda left_masks_table+1 ; Only one char is needed, so combine
and right_masks_table+1 ; the left and right masks and use the
sta left_masks_table+1 ; one-char fill subroutine.
sta right_masks_table+1
lda left_masks_table
and right_masks_table
sta left_masks_table
sta right_masks_table
2018-03-26 03:18:43 +00:00
copy16 fill_mode_table_onechar,x, fillmode_jmp+1
2017-09-17 18:18:47 +00:00
rts
2018-03-26 03:18:43 +00:00
: copy16 fill_mode_table,x, fillmode_jmp+1
2017-09-17 18:18:47 +00:00
rts
ll_ge256: ; Divmod for left limit >= 256
lda x1
2017-09-17 18:18:47 +00:00
ror a
tax
php
lda div7_table+4,x
2017-09-17 18:18:47 +00:00
clc
adc #$24
plp
ldy mod7_table+4,x
bpl set_x1_bytes
rl_ge256: ; Divmod for right limit >= 256
lda x2
2017-09-17 18:18:47 +00:00
ror a
tax
php
lda div7_table+4,x
2017-09-17 18:18:47 +00:00
clc
adc #$24
plp
ldy mod7_table+4,x
bmi divmod7
jmp set_x2_bytes
.endproc
2017-09-17 18:18:47 +00:00
.proc divmod7
lsr a
bne :+
2017-09-17 18:18:47 +00:00
txa
ror a
tax
lda div7_table,x
ldy mod7_table,x
2017-09-17 18:18:47 +00:00
rts
: txa
2017-09-17 18:18:47 +00:00
ror a
tax
php
lda div7_table+4,x
2017-09-17 18:18:47 +00:00
clc
adc #$24
plp
ldy mod7_table+4,x
2017-09-17 18:18:47 +00:00
rts
.endproc
;; Set up destination (for either on-screen or off-screen bitmap.)
.proc set_dest
DEST_NDBM := 0 ; draw to off-screen bitmap
DEST_DHGR := 1 ; draw to DHGR screen
2017-09-17 18:18:47 +00:00
lda left_bytes
ldx top
2018-01-29 16:25:56 +00:00
ldy current_mapwidth
jsr ndbm_calc_dest
2017-09-17 18:18:47 +00:00
clc
2018-01-29 16:25:56 +00:00
adc current_mapbits
sta vid_addr
2017-09-17 18:18:47 +00:00
tya
2018-01-29 16:25:56 +00:00
adc current_mapbits+1
sta vid_addr+1
lda #2*DEST_DHGR
2017-09-17 18:18:47 +00:00
tax
tay
2018-01-29 16:25:56 +00:00
bit current_mapwidth
bmi on_screen ; negative for on-screen destination
2018-03-26 03:18:43 +00:00
copy16 #bitmap_buffer, bits_addr
jsr ndbm_fix_width
2017-09-17 18:18:47 +00:00
txa
inx
stx src_width_bytes
jsr set_up_fill_mode::set_width
2018-03-26 03:18:43 +00:00
copy16 shift_line_jmp_addr, dhgr_get_srcbits::shift_bits_jmp_addr
lda #2*DEST_NDBM
ldx #2*DEST_NDBM
ldy #2*DEST_NDBM
on_screen:
pha
lda next_line_table,x
sta dhgr_start_fill::next_line_jmp_addr
lda next_line_table+1,x
sta dhgr_start_fill::next_line_jmp_addr+1
2017-09-17 18:18:47 +00:00
pla
tax
2018-03-26 03:18:43 +00:00
copy16 start_fill_table,x, start_fill_jmp+1
copy16 shift_line_table,y, dhgr_shift_bits::shift_line_jmp_addr
2017-09-17 18:18:47 +00:00
rts
.endproc
;; Fix up the width and masks for an off-screen destination,
2017-09-17 18:18:47 +00:00
ndbm_fix_width:
lda width_bytes
2017-09-17 18:18:47 +00:00
asl a
tax
inx
lda left_masks_table+1
bne :+
2017-09-17 18:18:47 +00:00
dex
inc bits_addr
inc16 vid_addr
lda left_masks_table
: sta left_sidemask
lda right_masks_table
bne :+
2017-09-17 18:18:47 +00:00
dex
lda right_masks_table+1
: sta right_sidemask
2017-09-17 18:18:47 +00:00
rts
;; DEST_NDBM DEST_DHGR
shift_line_jmp_addr:
.addr shift_line_jmp
start_fill_table:
.addr ndbm_start_fill, dhgr_start_fill
next_line_table:
.addr ndbm_next_line, dhgr_next_line
shift_line_table:
.addr ndbm_next_line, dhgr_shift_line
;; Set source for bitmap transfer (either on-screen or off-screen bitmap.)
.proc set_source
SRC_NDBM := 0
SRC_DHGR := 1
ldx src_y_coord
ldy src_mapwidth
bmi :+
2018-04-02 15:00:43 +00:00
jsr mult_x_y
: clc
adc bits_addr
sta ndbm_get_srcbits::load_addr
2017-09-17 18:18:47 +00:00
tya
adc bits_addr+1
sta ndbm_get_srcbits::load_addr+1
ldx #2*SRC_DHGR
bit src_mapwidth
bmi :+
ldx #2*SRC_NDBM
2018-03-26 03:18:43 +00:00
: copy16 get_srcbits_table,x, fill_next_line::get_srcbits_jmp_addr
2017-09-17 18:18:47 +00:00
rts
;; SRC_NDBM SRC_DHGR
get_srcbits_table:
.addr ndbm_get_srcbits, dhgr_get_srcbits
.endproc
;; Calculate destination for off-screen bitmap.
2017-09-17 18:18:47 +00:00
.proc ndbm_calc_dest
bmi on_screen ; do nothing for on-screen destination
2017-09-17 18:18:47 +00:00
asl a
2018-04-02 15:00:43 +00:00
mult_x_y:
stx $82
2017-10-07 20:59:25 +00:00
sty $83
ldx #8
loop: lsr $83
bcc :+
2017-09-17 18:18:47 +00:00
clc
2017-10-07 20:59:25 +00:00
adc $82
: ror a
ror vid_addr
2017-09-17 18:18:47 +00:00
dex
bne loop
2017-10-07 20:59:25 +00:00
sty $82
2017-09-17 18:18:47 +00:00
tay
lda vid_addr
2017-09-17 18:18:47 +00:00
sec
2017-10-07 20:59:25 +00:00
sbc $82
bcs on_screen
2017-09-17 18:18:47 +00:00
dey
on_screen:
rts
.endproc
2018-04-02 15:00:43 +00:00
mult_x_y := ndbm_calc_dest::mult_x_y
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetPattern
2017-10-03 03:05:07 +00:00
;; Expands the pattern to 8 rows of DHGR-style bitmaps at
;; $0400, $0440, $0480, $04C0, $0500, $0540, $0580, $05C0
;; (using both main and aux mem.)
.proc SetPatternImpl
lda #<pattern_buffer
sta bits_addr
lda y_offset
and #7
2017-09-17 18:18:47 +00:00
lsr a
ror bits_addr
2017-09-17 18:18:47 +00:00
lsr a
ror bits_addr
adc #>pattern_buffer
sta bits_addr+1
ldx #7
loop: lda x_offset
and #7
2017-09-17 18:18:47 +00:00
tay
2018-01-29 16:25:56 +00:00
lda current_penpattern,x
: dey
bmi :+
2017-09-17 18:18:47 +00:00
cmp #$80
rol a
bne :-
: ldy #$27
: pha
2017-09-17 18:18:47 +00:00
lsr a
sta LOWSCR
sta (bits_addr),y
2017-09-17 18:18:47 +00:00
pla
ror a
pha
lsr a
sta HISCR
sta (bits_addr),y
2017-09-17 18:18:47 +00:00
pla
ror a
dey
bpl :-
lda bits_addr
2017-09-17 18:18:47 +00:00
sec
sbc #$40
sta bits_addr
bcs next
ldy bits_addr+1
2017-09-17 18:18:47 +00:00
dey
cpy #>pattern_buffer
bcs :+
ldy #>pattern_buffer+1
: sty bits_addr+1
next: dex
bpl loop
sta LOWSCR
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; FrameRect
2017-10-03 03:05:07 +00:00
;;; 8 bytes of params, copied to $9F
frect_ctr: .byte 0
2017-10-07 22:07:12 +00:00
.proc FrameRectImpl
2017-10-07 22:07:12 +00:00
left := $9F
top := $A1
2017-10-07 22:07:12 +00:00
right := $A3
bottom := $A5
2017-10-07 22:07:12 +00:00
ldy #3
rloop: COPY_BYTES 8, left, left_masks_table
ldx rect_sides,y
lda left,x
2017-09-17 18:18:47 +00:00
pha
2017-09-30 02:14:47 +00:00
lda $A0,x
ldx rect_coords,y
2017-09-17 18:18:47 +00:00
sta $93,x
pla
sta left_masks_table,x
sty frect_ctr
jsr draw_line
ldy frect_ctr
2017-09-17 18:18:47 +00:00
dey
bpl rloop
COPY_BYTES 4, left, current_penloc
.endproc
prts: rts
rect_sides:
.byte 0,2,4,6
rect_coords:
.byte 4,6,0,2
2017-09-17 18:18:47 +00:00
.proc draw_line
x2 := right
2017-10-07 22:07:12 +00:00
lda current_penwidth ; Also: draw horizontal line $92 to $96 at $98
2017-09-30 02:14:47 +00:00
sec
2017-10-07 22:07:12 +00:00
sbc #1
2017-09-30 02:14:47 +00:00
cmp #$FF
beq prts
adc x2
sta x2
bcc :+
inc x2+1
2017-10-07 22:07:12 +00:00
: lda current_penheight
2017-09-17 18:18:47 +00:00
sec
2017-10-07 22:07:12 +00:00
sbc #1
2017-09-17 18:18:47 +00:00
cmp #$FF
beq prts
adc bottom
sta bottom
2018-01-29 08:57:55 +00:00
bcc PaintRectImpl
inc bottom+1
2017-10-03 03:05:07 +00:00
;; Fall through...
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; PaintRect
;;; 8 bytes of params, copied to $92
2017-10-07 20:59:25 +00:00
.proc PaintRectImpl
jsr check_rect
do_paint:
jsr clip_rect
bcc prts
2017-10-08 03:22:39 +00:00
jsr set_up_fill_mode
jsr set_dest
jmp do_fill
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; InRect
2017-10-03 03:05:07 +00:00
;;; 8 bytes of params, copied to $92
2017-10-07 20:59:25 +00:00
2018-01-29 08:57:55 +00:00
.proc InRectImpl
jsr check_rect
ldax current_penloc_x
2017-10-07 22:07:12 +00:00
cpx left+1
2017-10-03 04:00:31 +00:00
bmi fail
bne :+
2017-10-07 22:07:12 +00:00
cmp left
2017-10-03 04:00:31 +00:00
bcc fail
2017-10-07 22:07:12 +00:00
: cpx right+1
2017-10-03 04:00:31 +00:00
bmi :+
bne fail
2017-10-07 22:07:12 +00:00
cmp right
2017-10-03 04:00:31 +00:00
bcc :+
bne fail
: ldax current_penloc_y
2017-10-07 22:07:12 +00:00
cpx top+1
2017-10-03 04:00:31 +00:00
bmi fail
bne :+
2017-10-07 22:07:12 +00:00
cmp top
2017-10-03 04:00:31 +00:00
bcc fail
2017-10-07 22:07:12 +00:00
: cpx bottom+1
2017-10-03 04:00:31 +00:00
bmi :+
bne fail
2017-10-07 22:07:12 +00:00
cmp bottom
2017-10-03 04:00:31 +00:00
bcc :+
bne fail
2018-03-30 14:58:10 +00:00
: exit_call MGTK::inrect_inside ; success!
2017-09-17 18:18:47 +00:00
2017-10-03 04:00:31 +00:00
fail: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetPortBits
2017-10-03 03:05:07 +00:00
.proc SetPortBitsImpl
sub16 current_viewloc_x, current_maprect_x1, x_offset
sub16 current_viewloc_y, current_maprect_y1, y_offset
2017-09-17 18:18:47 +00:00
rts
.endproc
clipped_left := $9B ; number of bits clipped off left side
clipped_top := $9D ; number of bits clipped off top side
2017-09-17 18:18:47 +00:00
.proc clip_rect
lda current_maprect_x2+1
cmp left+1
bmi fail
bne in_left
2018-01-29 16:25:56 +00:00
lda current_maprect_x2
cmp left
bcs in_left
fail: clc
fail2: rts
2017-09-17 18:18:47 +00:00
in_left:
lda right+1
2018-01-29 16:25:56 +00:00
cmp current_maprect_x1+1
bmi fail
bne in_right
lda right
2018-01-29 16:25:56 +00:00
cmp current_maprect_x1
bcc fail2
in_right:
lda current_maprect_y2+1
cmp top+1
bmi fail
bne in_bottom
2018-01-29 16:25:56 +00:00
lda current_maprect_y2
cmp top
bcc fail2
in_bottom:
lda bottom+1
2018-01-29 16:25:56 +00:00
cmp current_maprect_y1+1
bmi fail
bne in_top
lda bottom
2018-01-29 16:25:56 +00:00
cmp current_maprect_y1
bcc fail2
in_top: ldy #0
lda left
2017-09-17 18:18:47 +00:00
sec
2018-01-29 16:25:56 +00:00
sbc current_maprect_x1
2017-09-17 18:18:47 +00:00
tax
lda left+1
2018-01-29 16:25:56 +00:00
sbc current_maprect_x1+1
bpl :+
stx clipped_left
sta clipped_left+1
copy16 current_maprect_x1, left
2017-09-17 18:18:47 +00:00
iny
: lda current_maprect_x2
2017-09-17 18:18:47 +00:00
sec
sbc right
2017-09-17 18:18:47 +00:00
tax
2018-01-29 16:25:56 +00:00
lda current_maprect_x2+1
sbc right+1
bpl :+
copy16 current_maprect_x2, right
2017-09-17 18:18:47 +00:00
tya
ora #$04
tay
: lda top
2017-09-17 18:18:47 +00:00
sec
2018-01-29 16:25:56 +00:00
sbc current_maprect_y1
2017-09-17 18:18:47 +00:00
tax
lda top+1
2018-01-29 16:25:56 +00:00
sbc current_maprect_y1+1
bpl :+
stx clipped_top
sta clipped_top+1
copy16 current_maprect_y1, top
2017-09-17 18:18:47 +00:00
iny
iny
: lda current_maprect_y2
2017-09-17 18:18:47 +00:00
sec
sbc bottom
2017-09-17 18:18:47 +00:00
tax
2018-01-29 16:25:56 +00:00
lda current_maprect_y2+1
sbc bottom+1
bpl :+
copy16 current_maprect_y2, bottom
2017-09-17 18:18:47 +00:00
tya
ora #$08
tay
: sty $9A
2017-09-17 18:18:47 +00:00
sec
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc check_rect
2017-09-17 18:18:47 +00:00
sec
lda right
sbc left
lda right+1
sbc left+1
bmi bad_rect
sec
lda bottom
sbc top
lda bottom+1
sbc top+1
bmi bad_rect
2017-09-17 18:18:47 +00:00
rts
bad_rect:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::empty_object
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 16 bytes of params, copied to $8A
src_width_bytes:
.res 1 ; width of source data in chars
unused_width:
.res 1 ; holds the width of data, but is not used ???
2017-10-03 02:48:21 +00:00
.proc PaintBitsImpl
2017-10-07 22:07:12 +00:00
dbi_left := $8A
dbi_top := $8C
dbi_bitmap := $8E ; aka bits_addr
dbi_stride := $90 ; aka src_mapwidth
dbi_hoff := $92 ; aka left
dbi_voff := $94 ; aka top
dbi_width := $96 ; aka right
dbi_height := $98 ; aka bottom
2017-10-07 22:07:12 +00:00
dbi_x := $9B
dbi_y := $9D
offset := $82
2017-10-07 22:07:12 +00:00
ldx #3 ; copy left/top to $9B/$9D
: lda dbi_left,x ; and hoff/voff to $8A/$8C (overwriting left/top)
sta dbi_x,x
lda dbi_hoff,x
sta dbi_left,x
2017-09-17 18:18:47 +00:00
dex
2017-10-07 22:07:12 +00:00
bpl :-
sub16 dbi_width, dbi_hoff, offset
2017-10-07 22:07:12 +00:00
lda dbi_x
sta left
2017-10-07 22:07:12 +00:00
2017-09-17 18:18:47 +00:00
clc
adc offset
sta right
2017-10-07 22:07:12 +00:00
lda dbi_x+1
sta left+1
adc offset+1
sta right+1
2017-10-07 22:07:12 +00:00
sub16 dbi_height, dbi_voff, offset
2017-10-07 22:07:12 +00:00
lda dbi_y
sta top
2017-09-17 18:18:47 +00:00
clc
adc offset
sta bottom
2017-10-07 22:07:12 +00:00
lda dbi_y+1
sta top+1
adc offset+1
sta bottom+1
;; fall through to BitBlt
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-04 15:31:53 +00:00
;;; $4D BitBlt
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 16 bytes of params, copied to $8A
src_byte_off := $8A ; char offset within source line
bit_offset := $9B
shift_bytes := $81
.proc BitBltImpl
lda #0
sta clipped_left
sta clipped_left+1
sta clipped_top
lda bits_addr+1
2017-09-30 02:14:47 +00:00
sta $80
jsr clip_rect
bcs :+
2017-09-17 18:18:47 +00:00
rts
: jsr set_up_fill_mode
lda width_bytes
2017-09-17 18:18:47 +00:00
asl a
ldx left_masks_table+1 ; need left mask on aux?
beq :+
2017-10-14 06:23:31 +00:00
adc #1
: ldx right_masks_table ; need right mask on main?
beq :+
2017-10-14 06:23:31 +00:00
adc #1
: sta unused_width
sta src_width_bytes ; adjusted width in chars
2017-10-14 06:23:31 +00:00
lda #2
sta shift_bytes
lda #0 ; Calculate starting Y-coordinate
sec ; = dbi_top - clipped_top
sbc clipped_top
2017-09-17 18:18:47 +00:00
clc
adc PaintBitsImpl::dbi_top
sta PaintBitsImpl::dbi_top
lda #0 ; Calculate starting X-coordinate
sec ; = dbi_left - clipped_left
sbc clipped_left
2017-09-17 18:18:47 +00:00
tax
2017-10-14 06:23:31 +00:00
lda #0
sbc clipped_left+1
2017-09-17 18:18:47 +00:00
tay
2017-09-17 18:18:47 +00:00
txa
clc
adc PaintBitsImpl::dbi_left
2017-09-17 18:18:47 +00:00
tax
tya
adc PaintBitsImpl::dbi_left+1
jsr divmod7
sta src_byte_off
tya ; bit offset between src and dest
2017-09-17 18:18:47 +00:00
rol a
2017-10-14 06:23:31 +00:00
cmp #7
ldx #1
bcc :+
2017-09-17 18:18:47 +00:00
dex
2017-10-14 06:23:31 +00:00
sbc #7
: stx dhgr_get_srcbits::offset1_addr
2017-09-17 18:18:47 +00:00
inx
stx dhgr_get_srcbits::offset2_addr
sta bit_offset
lda src_byte_off
2017-09-17 18:18:47 +00:00
rol a
jsr set_source
jsr set_dest
copy16 #bitmap_buffer, bits_addr
ldx #1
2018-03-30 14:58:10 +00:00
lda left_mod14
2017-09-17 18:18:47 +00:00
sec
sbc #7
bcc :+
2018-03-30 14:58:10 +00:00
sta left_mod14
2017-09-17 18:18:47 +00:00
dex
: stx dhgr_shift_line::offset1_addr
2017-09-17 18:18:47 +00:00
inx
stx dhgr_shift_line::offset2_addr
2018-03-30 14:58:10 +00:00
lda left_mod14
2017-09-17 18:18:47 +00:00
sec
sbc bit_offset
bcs :+
2017-10-14 06:23:31 +00:00
adc #7
inc src_width_bytes
dec shift_bytes
: tay ; check if bit shift required
bne :+
ldx #2*BITS_NO_BITSHIFT
beq no_bitshift
: tya
2017-09-17 18:18:47 +00:00
asl a
tay
2018-03-26 03:18:43 +00:00
copy16 shift_table_main,y, dhgr_shift_bits::shift_main_addr
2018-03-26 03:18:43 +00:00
copy16 shift_table_aux,y, dhgr_shift_bits::shift_aux_addr
ldy shift_bytes
sty dhgr_shift_bits::offset2_addr
2017-09-17 18:18:47 +00:00
dey
sty dhgr_shift_bits::offset1_addr
ldx #2*BITS_BITSHIFT
no_bitshift:
copy16 shift_bits_table,x, dhgr_get_srcbits::shift_bits_jmp_addr
jmp bit_blit
2017-09-17 18:18:47 +00:00
BITS_NO_BITSHIFT := 0
BITS_BITSHIFT := 1
;; BITS_NO_BITSHIFT BITS_BITSHIFT
shift_bits_table:
.addr shift_line_jmp, dhgr_shift_bits
.endproc
2017-10-08 15:42:27 +00:00
shift_table_aux := *-2
.addr shift_1_aux,shift_2_aux,shift_3_aux
.addr shift_4_aux,shift_5_aux,shift_6_aux
2017-10-08 15:42:27 +00:00
shift_table_main := *-2
.addr shift_1_main,shift_2_main,shift_3_main
.addr shift_4_main,shift_5_main,shift_6_main
2017-10-07 03:59:09 +00:00
2017-10-14 06:23:31 +00:00
vertex_limit := $B3
vertices_count := $B4
poly_oper := $BA ; positive = paint; negative = test
start_index := $AE
poly_oper_paint := $00
poly_oper_test := $80
.proc load_poly
point_index := $82
low_point := $A7
max_poly_points := 60
stx $B0
2017-09-17 18:18:47 +00:00
asl a
asl a ; # of vertices * 4 = length
sta vertex_limit
2017-10-14 06:23:31 +00:00
;; Initialize rect to first point of polygon.
2017-10-14 06:23:31 +00:00
ldy #3 ; Copy params_addr... to $92... and $96...
: lda (params_addr),y
sta left,y
sta right,y
2017-09-17 18:18:47 +00:00
dey
2017-10-14 06:23:31 +00:00
bpl :-
copy16 top, low_point ; y coord
2017-10-14 06:23:31 +00:00
ldy #0
stx start_index
loop: stx point_index
2017-10-07 20:59:25 +00:00
lda (params_addr),y
sta poly_xl_buffer,x
2017-09-17 18:18:47 +00:00
pha
iny
2017-10-07 20:59:25 +00:00
lda (params_addr),y
sta poly_xh_buffer,x
2017-09-17 18:18:47 +00:00
tax
pla
iny
cpx left+1
bmi :+
bne in_left
cmp left
bcs in_left
: stax left
bcc in_right
in_left:
cpx right+1
bmi in_right
bne :+
cmp right
bcc in_right
: stax right
in_right:
ldx point_index
2017-10-07 20:59:25 +00:00
lda (params_addr),y
sta poly_yl_buffer,x
2017-09-17 18:18:47 +00:00
pha
iny
2017-10-07 20:59:25 +00:00
lda (params_addr),y
sta poly_yh_buffer,x
2017-09-17 18:18:47 +00:00
tax
pla
iny
cpx top+1
bmi :+
bne in_top
cmp top
bcs in_top
: stax top
bcc in_bottom
in_top: cpx bottom+1
bmi in_bottom
bne :+
cmp bottom
bcc in_bottom
: stax bottom
in_bottom:
cpx low_point+1
stx low_point+1
bmi set_low_point
bne :+
cmp low_point
bcc set_low_point
beq set_low_point
: ldx point_index
stx start_index
set_low_point:
sta low_point
ldx point_index
2017-09-17 18:18:47 +00:00
inx
cpx #max_poly_points
beq bad_poly
cpy vertex_limit
bcc loop
lda top
cmp bottom
bne :+
lda top+1
cmp bottom+1
beq bad_poly
: stx vertex_limit
bit poly_oper
bpl :+
2017-09-17 18:18:47 +00:00
sec
rts
: jmp clip_rect
.endproc
2017-09-17 18:18:47 +00:00
.proc next_poly
lda vertices_count
bpl orts
2017-09-17 18:18:47 +00:00
asl a
asl a
2017-10-07 20:59:25 +00:00
adc params_addr
sta params_addr
2017-10-14 06:23:31 +00:00
bcc ora_2_param_bytes
2017-10-07 20:59:25 +00:00
inc params_addr+1
;; Fall-through
.endproc
2017-10-14 06:23:31 +00:00
;; ORAs together first two bytes at (params_addr) and stores
;; in $B4, then advances params_addr
ora_2_param_bytes:
ldy #0
2017-10-07 20:59:25 +00:00
lda (params_addr),y
2017-09-17 18:18:47 +00:00
iny
2017-10-07 20:59:25 +00:00
ora (params_addr),y
sta vertices_count
2018-02-26 00:06:17 +00:00
inc16 params_addr
inc16 params_addr
ldy #$80
orts: rts
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; InPoly
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
InPolyImpl:
lda #poly_oper_test
bne PaintPolyImpl_entry2
2017-10-04 15:31:53 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; PaintPoly
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
;; also called from the end of LineToImpl
num_maxima := $AD
max_num_maxima := 8
low_vertex := $B0
.proc PaintPolyImpl
lda #poly_oper_paint
entry2: sta poly_oper
2017-10-14 06:23:31 +00:00
ldx #0
stx num_maxima
2017-10-14 06:23:31 +00:00
jsr ora_2_param_bytes
loop: jsr load_poly
bcs process_poly
ldx low_vertex
next: jsr next_poly
bmi loop
jmp fill_polys
bad_poly:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::bad_object
.endproc
temp_yh := $83
next_vertex := $AA
current_vertex := $AC
loop_ctr := $AF
.proc process_poly
ldy #1
sty loop_ctr ; do 2 iterations of the following loop
ldy start_index ; starting vertex
cpy low_vertex ; lowest vertex
bne :+
ldy vertex_limit ; highest vertex
: dey
sty $AB ; one before starting vertex
2017-09-17 18:18:47 +00:00
php
loop: sty current_vertex ; current vertex
2017-09-17 18:18:47 +00:00
iny
cpy vertex_limit
bne :+
ldy low_vertex
: sty next_vertex ; next vertex
cpy start_index ; have we come around complete circle?
bne :+
dec loop_ctr ; this completes one loop
: lda poly_yl_buffer,y
ldx poly_yh_buffer,y
stx temp_yh
vloop: sty $A9 ; starting from next vertex, search ahead
iny ; for a subsequent vertex with differing y
cpy vertex_limit
bne :+
ldy low_vertex
:
cmp poly_yl_buffer,y
bne :+
ldx poly_yh_buffer,y
cpx temp_yh
beq vloop
: ldx $AB ; find y difference with current vertex
2017-09-17 18:18:47 +00:00
sec
sbc poly_yl_buffer,x
lda temp_yh
sbc poly_yh_buffer,x
bmi y_less
lda $A9 ; vertex before new vertex
plp ; check maxima flag
bmi new_maxima ; if set, go create new maxima
2017-09-17 18:18:47 +00:00
tay
sta poly_vertex_prev_link,x ; link current vertex -> vertex before new vertex
lda next_vertex
sta poly_vertex_next_link,x ; link current vertex -> next vertex
bpl next
new_maxima:
ldx num_maxima
cpx #2*max_num_maxima ; too many maxima points (documented limitation)
bcs bad_poly
sta poly_maxima_prev_vertex,x ; vertex before new vertex
lda next_vertex
sta poly_maxima_next_vertex,x ; current vertex
2017-09-30 02:14:47 +00:00
ldy $AB
lda poly_vertex_prev_link,y
sta poly_maxima_prev_vertex+1,x
lda poly_vertex_next_link,y
sta poly_maxima_next_vertex+1,x
lda poly_yl_buffer,y
sta poly_maxima_yl_table,x
sta poly_maxima_yl_table+1,x
lda poly_yh_buffer,y
sta poly_maxima_yh_table,x
sta poly_maxima_yh_table+1,x
lda poly_xl_buffer,y
sta poly_maxima_xl_table+1,x
lda poly_xh_buffer,y
sta poly_maxima_xh_table+1,x
ldy current_vertex
lda poly_xl_buffer,y
sta poly_maxima_xl_table,x
lda poly_xh_buffer,y
sta poly_maxima_xh_table,x
2017-09-17 18:18:47 +00:00
inx
inx
stx num_maxima
2017-09-17 18:18:47 +00:00
ldy $A9
bpl next
y_less: plp ; check maxima flag
bmi :+
2017-09-17 18:18:47 +00:00
lda #$80
sta poly_vertex_prev_link,x ; link current vertex -> #$80
: ldy next_vertex
2017-09-17 18:18:47 +00:00
txa
sta poly_vertex_prev_link,y ; link next vertex -> current vertex
lda current_vertex
sta poly_vertex_next_link,y
lda #$80 ; set negative flag so next iteration captures a maxima
next: php
2017-09-17 18:18:47 +00:00
sty $AB
ldy $A9
bit loop_ctr
bmi :+
jmp loop
: plp
ldx vertex_limit
jmp PaintPolyImpl::next
.endproc
2017-09-17 18:18:47 +00:00
scan_y := $A9
lr_flag := $AB
start_maxima := $B1
2017-09-17 18:18:47 +00:00
.proc fill_polys
ldx #0
stx start_maxima
2017-09-17 18:18:47 +00:00
lda #$80
sta poly_maxima_links
2017-09-17 18:18:47 +00:00
sta $B2
loop: inx
cpx num_maxima
bcc :+
beq links_done
2017-09-17 18:18:47 +00:00
rts
: lda start_maxima
next_link:
tay
lda poly_maxima_yl_table,x
cmp poly_maxima_yl_table,y
bcs x_ge_y
tya ; poly_maxima_y[xReg] < poly_maxima_y[yReg]
sta poly_maxima_links,x ; then xReg linked to yReg
cpy start_maxima
beq :+ ; if yReg was the start, set the start to xReg
2017-10-07 20:59:25 +00:00
ldy $82
2017-09-17 18:18:47 +00:00
txa
sta poly_maxima_links,y ; else $82 linked to xReg
jmp loop
: stx start_maxima ; set start to xReg
bcs loop ; always
x_ge_y: sty $82 ; poly_maxima_y[xReg] >= poly_maxima_y[yReg]
lda poly_maxima_links,y
bpl next_link ; if yReg was the end
sta poly_maxima_links,x ; then set xReg as end
2017-09-17 18:18:47 +00:00
txa
sta poly_maxima_links,y ; and link yReg to xReg
bpl loop ; always
links_done:
ldx start_maxima
lda poly_maxima_yl_table,x
sta scan_y
sta top
lda poly_maxima_yh_table,x
sta scan_y+1
sta top+1
scan_loop:
ldx start_maxima
2017-09-17 18:18:47 +00:00
bmi L5534
scan_next:
lda poly_maxima_yl_table,x
cmp scan_y
2017-09-17 18:18:47 +00:00
bne L5532
lda poly_maxima_yh_table,x
cmp scan_y+1
2017-09-17 18:18:47 +00:00
bne L5532
lda poly_maxima_links,x
2017-10-07 20:59:25 +00:00
sta $82
jsr calc_slope
2017-09-17 18:18:47 +00:00
lda $B2
bmi L5517
2017-09-17 18:18:47 +00:00
L54E0: tay
lda poly_maxima_xh_table,x
cmp poly_maxima_xh_table,y
2017-09-17 18:18:47 +00:00
bmi L5520
bne :+
lda poly_maxima_xl_table,x
cmp poly_maxima_xl_table,y
2017-09-17 18:18:47 +00:00
bcc L5520
bne :+
lda poly_maxima_x_frach,x
cmp poly_maxima_x_frach,y
2017-09-17 18:18:47 +00:00
bcc L5520
bne :+
lda poly_maxima_x_fracl,x
cmp poly_maxima_x_fracl,y
2017-09-17 18:18:47 +00:00
bcc L5520
: sty $83
lda poly_maxima_links,y
2017-09-30 02:14:47 +00:00
bpl L54E0
sta poly_maxima_links,x
2017-09-30 02:14:47 +00:00
txa
sta poly_maxima_links,y
2017-09-17 18:18:47 +00:00
bpl L552E
L5517: sta poly_maxima_links,x
2017-09-17 18:18:47 +00:00
stx $B2
jmp L552E
done: rts
2017-09-17 18:18:47 +00:00
L5520: tya
cpy $B2
beq L5517
sta poly_maxima_links,x
2017-09-17 18:18:47 +00:00
txa
2017-10-07 20:59:25 +00:00
ldy $83
sta poly_maxima_links,y
2017-10-07 20:59:25 +00:00
L552E: ldx $82
bpl scan_next
2017-09-17 18:18:47 +00:00
L5532: stx $B1
L5534: lda #0
sta lr_flag
2017-09-17 18:18:47 +00:00
lda $B2
2017-10-07 20:59:25 +00:00
sta $83
bmi done
scan_loop2:
tax
lda scan_y
cmp poly_maxima_yl_table,x
bne scan_point
lda scan_y+1
cmp poly_maxima_yh_table,x
bne scan_point
ldy poly_maxima_prev_vertex,x
lda poly_vertex_prev_link,y
bpl shift_point
2017-09-17 18:18:47 +00:00
cpx $B2
beq :+
2017-10-07 20:59:25 +00:00
ldy $83
lda poly_maxima_links,x
sta poly_maxima_links,y
jmp scan_next_link
2017-09-17 18:18:47 +00:00
: lda poly_maxima_links,x
2017-09-17 18:18:47 +00:00
sta $B2
jmp scan_next_link
shift_point:
sta poly_maxima_prev_vertex,x
lda poly_xl_buffer,y
sta poly_maxima_xl_table,x
lda poly_xh_buffer,y
sta poly_maxima_xh_table,x
lda poly_vertex_next_link,y
sta poly_maxima_next_vertex,x
jsr calc_slope
scan_point:
stx current_vertex
ldy poly_maxima_xh_table,x
lda poly_maxima_xl_table,x
2017-09-17 18:18:47 +00:00
tax
lda lr_flag ; alternate flag left/right
2017-09-17 18:18:47 +00:00
eor #$FF
sta lr_flag
bpl :+
stx left
sty left+1
bmi skip_rect
: stx right
sty right+1
cpy left+1
bmi :+
bne no_swap_lr
cpx left
bcs no_swap_lr
: lda left
stx left
sta right
lda left+1
sty left+1
sta right+1
no_swap_lr:
lda scan_y
sta top
sta bottom
lda scan_y+1
sta top+1
sta bottom+1
bit poly_oper
bpl do_paint
2018-01-29 08:57:55 +00:00
jsr InRectImpl
jmp skip_rect
do_paint:
jsr PaintRectImpl::do_paint
skip_rect:
ldx current_vertex
2017-09-17 18:18:47 +00:00
lda poly_maxima_x_fracl,x
2017-09-17 18:18:47 +00:00
clc
adc poly_maxima_slope0,x
sta poly_maxima_x_fracl,x
lda poly_maxima_x_frach,x
adc poly_maxima_slope1,x
sta poly_maxima_x_frach,x
lda poly_maxima_xl_table,x
adc poly_maxima_slope2,x
sta poly_maxima_xl_table,x
lda poly_maxima_xh_table,x
adc poly_maxima_slope3,x
sta poly_maxima_xh_table,x
lda poly_maxima_links,x
scan_next_link:
bmi :+
jmp scan_loop2
: inc16 scan_y
jmp scan_loop
.endproc
.proc calc_slope
index := $84
2018-03-26 03:18:43 +00:00
ldy poly_maxima_next_vertex,x
lda poly_yl_buffer,y
sta poly_maxima_yl_table,x
2017-09-17 18:18:47 +00:00
sec
sbc scan_y
sta <fixed_div_divisor
lda poly_yh_buffer,y
sta poly_maxima_yh_table,x
sbc scan_y+1
sta <fixed_div_divisor+1
lda poly_xl_buffer,y
sec
sbc poly_maxima_xl_table,x
sta <fixed_div_dividend
lda poly_xh_buffer,y
sbc poly_maxima_xh_table,x
sta <fixed_div_dividend+1
2018-03-26 03:18:43 +00:00
2017-09-17 18:18:47 +00:00
php
bpl :+
sub16 #0, fixed_div_dividend, fixed_div_dividend
: stx index
jsr fixed_div2
ldx index
2017-09-17 18:18:47 +00:00
plp
bpl :+
2018-03-26 03:18:43 +00:00
sub16 #0, fixed_div_quotient, fixed_div_quotient
2017-10-14 06:23:31 +00:00
lda #0
sbc fixed_div_quotient+2
sta fixed_div_quotient+2
2017-10-14 06:23:31 +00:00
lda #0
sbc fixed_div_quotient+3
sta fixed_div_quotient+3
2018-03-26 03:18:43 +00:00
: lda fixed_div_quotient+3
sta poly_maxima_slope3,x
2017-09-17 18:18:47 +00:00
cmp #$80
ror a
pha
lda fixed_div_quotient+2
sta poly_maxima_slope2,x
2017-09-17 18:18:47 +00:00
ror a
pha
lda fixed_div_quotient+1
sta poly_maxima_slope1,x
2017-09-17 18:18:47 +00:00
ror a
pha
lda fixed_div_quotient
sta poly_maxima_slope0,x
2017-09-17 18:18:47 +00:00
ror a
sta poly_maxima_x_fracl,x
2017-09-17 18:18:47 +00:00
pla
clc
adc #$80
sta poly_maxima_x_frach,x
2017-09-17 18:18:47 +00:00
pla
adc poly_maxima_xl_table,x
sta poly_maxima_xl_table,x
2017-09-17 18:18:47 +00:00
pla
adc poly_maxima_xh_table,x
sta poly_maxima_xh_table,x
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
PaintPolyImpl_entry2 := PaintPolyImpl::entry2
bad_poly := PaintPolyImpl::bad_poly
.proc fixed_div
dividend := $A1 ; 16.0 format
divisor := $A3 ; 16.0 format
quotient := $9F ; 16.16 format
temp := $A5
lda dividend+1
entry2: ora dividend
bne :+
sta quotient
sta quotient+1
sta dividend
sta dividend+1
beq done ; always
: ldy #32
lda #0
sta quotient
sta quotient+1
sta temp
sta temp+1
loop: asl quotient
rol quotient+1
rol dividend
rol dividend+1
rol temp
rol temp+1
lda temp
2017-09-17 18:18:47 +00:00
sec
sbc divisor
2017-09-17 18:18:47 +00:00
tax
lda temp+1
sbc divisor+1
bcc :+
stx temp
sta temp+1
inc quotient
:
dey
bne loop
done: rts
.endproc
fixed_div2 := fixed_div::entry2
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; FramePoly
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc FramePolyImpl
2017-10-14 06:23:31 +00:00
lda #0
sta poly_oper
2017-10-14 06:23:31 +00:00
jsr ora_2_param_bytes
ptr := $B7
draw_line_params := $92
poly_loop:
copy16 params_addr, ptr
lda vertices_count ; ORAd param bytes
2017-09-17 18:18:47 +00:00
sta $B6
2017-10-14 06:23:31 +00:00
ldx #0
jsr load_poly
bcc next
2017-10-14 06:23:31 +00:00
2017-09-17 18:18:47 +00:00
lda $B3
2017-10-14 06:23:31 +00:00
sta $B5 ; loop counter
;; Loop for drawing
ldy #0
loop: dec $B5
beq endloop
2017-09-17 18:18:47 +00:00
sty $B9
2017-10-14 06:23:31 +00:00
ldx #0
: lda (ptr),y
sta draw_line_params,x
2017-09-17 18:18:47 +00:00
iny
inx
2017-10-14 06:23:31 +00:00
cpx #8
bne :-
jsr DRAW_LINE_ABS_IMPL_do_draw_line
2017-10-14 06:23:31 +00:00
2017-09-17 18:18:47 +00:00
lda $B9
clc
2017-10-14 06:23:31 +00:00
adc #4
2017-09-17 18:18:47 +00:00
tay
2017-10-14 06:23:31 +00:00
bne loop
endloop:
;; Draw from last point back to start
ldx #0
: lda (ptr),y
sta draw_line_params,x
2017-09-17 18:18:47 +00:00
iny
inx
2017-10-14 06:23:31 +00:00
cpx #4
bne :-
ldy #3
: lda (ptr),y
sta draw_line_params+4,y
2018-01-29 16:25:56 +00:00
sta current_penloc,y
2017-09-17 18:18:47 +00:00
dey
2017-10-14 06:23:31 +00:00
bpl :-
jsr DRAW_LINE_ABS_IMPL_do_draw_line
2017-10-14 06:23:31 +00:00
;; Handle multiple segments, e.g. when drawing outlines for multi icons?
next: ldx #1
2017-10-14 06:23:31 +00:00
: lda ptr,x
2017-09-30 02:14:47 +00:00
sta $80,x
2017-09-17 18:18:47 +00:00
lda $B5,x
sta $B3,x
dex
2017-10-14 06:23:31 +00:00
bpl :-
jsr next_poly ; Advance to next polygon in list
bmi poly_loop
2017-09-17 18:18:47 +00:00
rts
2017-10-14 06:23:31 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; Move
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $A1
2018-01-29 08:57:55 +00:00
.proc MoveImpl
2017-10-08 15:42:27 +00:00
xdelta := $A1
ydelta := $A3
ldax xdelta
2017-10-08 15:42:27 +00:00
jsr adjust_xpos
ldax ydelta
2017-09-17 18:18:47 +00:00
clc
2018-01-29 16:25:56 +00:00
adc current_penloc_y
sta current_penloc_y
2017-09-17 18:18:47 +00:00
txa
2018-01-29 16:25:56 +00:00
adc current_penloc_y+1
sta current_penloc_y+1
2017-09-17 18:18:47 +00:00
rts
2017-10-08 15:42:27 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-01-29 16:25:56 +00:00
;; Adjust current_penloc_x by (X,A)
2017-10-08 15:42:27 +00:00
.proc adjust_xpos
clc
2018-01-29 16:25:56 +00:00
adc current_penloc_x
sta current_penloc_x
2017-09-17 18:18:47 +00:00
txa
2018-01-29 16:25:56 +00:00
adc current_penloc_x+1
sta current_penloc_x+1
2017-09-17 18:18:47 +00:00
rts
2017-10-08 15:42:27 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; LineImpl
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $A1
2018-01-29 08:57:55 +00:00
.proc LineImpl
2017-10-07 22:07:12 +00:00
xdelta := $A1
ydelta := $A2
ldx #2 ; Convert relative x/y to absolute x/y at $92,$94
loop: add16 xdelta,x, current_penloc_x,x, $92,x
2017-09-17 18:18:47 +00:00
dex
dex
2017-10-07 22:07:12 +00:00
bpl loop
;; fall through
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; LineTo
2017-10-04 15:31:53 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $92
2018-01-29 08:57:55 +00:00
.proc LineToImpl
2017-10-08 15:42:27 +00:00
params := $92
xend := params + 0
yend := params + 2
2017-10-14 06:23:31 +00:00
pt1 := $92
x1 := pt1
y1 := pt1+2
pt2 := $96
x2 := pt2
y2 := pt2+2
loop_ctr := $82
temp_pt := $83
2017-10-08 15:42:27 +00:00
ldx #3
: lda current_penloc,x ; move pos to $96, assign params to pos
2017-10-14 06:23:31 +00:00
sta pt2,x
lda pt1,x
2018-01-29 16:25:56 +00:00
sta current_penloc,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-10-08 15:42:27 +00:00
2017-10-14 06:23:31 +00:00
;; Called from elsewhere; draw $92,$94 to $96,$98; values modified
do_draw_line:
2017-10-14 06:23:31 +00:00
lda y2+1
cmp y1+1
bmi swap_start_end
2017-09-17 18:18:47 +00:00
bne L57BF
2017-10-14 06:23:31 +00:00
lda y2
cmp y1
bcc swap_start_end
2017-09-17 18:18:47 +00:00
bne L57BF
2017-10-14 06:23:31 +00:00
;; y1 == y2
lda x1
ldx x1+1
cpx x2+1
bmi draw_line_jmp
bne :+
2017-10-14 06:23:31 +00:00
cmp x2
bcc draw_line_jmp
2017-10-14 06:23:31 +00:00
: ldy x2 ; swap so x1 < x2
2017-10-14 06:23:31 +00:00
sta x2
sty x1
ldy x2+1
stx x2+1
sty x1+1
draw_line_jmp:
jmp draw_line
2017-09-17 18:18:47 +00:00
swap_start_end:
ldx #3 ; Swap start/end
: lda pt1,x
2017-09-17 18:18:47 +00:00
tay
lda pt2,x
sta pt1,x
2017-09-17 18:18:47 +00:00
tya
sta pt2,x
2017-09-17 18:18:47 +00:00
dex
2017-10-14 06:23:31 +00:00
bpl :-
2018-01-29 16:25:56 +00:00
L57BF: ldx current_penwidth
2017-09-17 18:18:47 +00:00
dex
stx $A2
2018-01-29 16:25:56 +00:00
lda current_penheight
2017-09-17 18:18:47 +00:00
sta $A4
2017-10-14 06:23:31 +00:00
lda #0
2017-09-17 18:18:47 +00:00
sta $A1
sta $A3
lda x1
ldx x1+1
cpx x2+1
2017-09-17 18:18:47 +00:00
bmi L57E9
bne L57E1
cmp x2
2017-09-17 18:18:47 +00:00
bcc L57E9
bne L57E1
jmp draw_line
2017-09-17 18:18:47 +00:00
L57E1: lda $A1
ldx $A2
sta $A2
stx $A1
L57E9: ldy #5 ; do 6 points
loop: sty loop_ctr
ldx pt_offsets,y ; offset into the pt1,pt2 structure
2017-10-14 06:23:31 +00:00
ldy #3
: lda pt1,x
sta temp_pt,y
2017-09-17 18:18:47 +00:00
dex
dey
bpl :-
ldy loop_ctr
ldx penwidth_flags,y ; when =1, will add the current_penwidth
2017-09-17 18:18:47 +00:00
lda $A1,x
clc
adc temp_pt
sta temp_pt
bcc :+
inc temp_pt+1
:
ldx penheight_flags,y ; when =2, will add the current_penheight
2017-09-17 18:18:47 +00:00
lda $A3,x
clc
adc temp_pt+2
sta temp_pt+2
bcc :+
inc temp_pt+3
:
tya
2017-09-17 18:18:47 +00:00
asl a
asl a
tay
2017-10-14 06:23:31 +00:00
ldx #0
: lda temp_pt,x
sta paint_poly_points,y
2017-09-17 18:18:47 +00:00
iny
inx
2017-10-14 06:23:31 +00:00
cpx #4
bne :-
ldy loop_ctr
2017-09-17 18:18:47 +00:00
dey
bpl loop
copy16 paint_poly_params_addr, params_addr
2018-01-29 08:57:55 +00:00
jmp PaintPolyImpl
2017-09-30 02:14:47 +00:00
paint_poly_params_addr:
.addr paint_poly_params
;; Points 0 1 2 3 4 5
pt_offsets:
.byte 3, 3, 7, 7, 7, 3
penwidth_flags:
.byte 0, 0, 0, 1, 1, 1
penheight_flags:
.byte 0, 1, 1, 1, 0, 0
2018-03-26 03:18:43 +00:00
;; params for a PaintPoly call
paint_poly_params:
.byte 6 ; number of points
.byte 0
paint_poly_points:
.res 4*6 ; points
2017-10-08 15:42:27 +00:00
.endproc
DRAW_LINE_ABS_IMPL_do_draw_line := LineToImpl::do_draw_line
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetFont
2017-10-04 15:31:53 +00:00
2018-03-30 14:58:10 +00:00
.define max_font_height 16
2018-01-29 08:57:55 +00:00
.proc SetFontImpl
2018-03-26 03:18:43 +00:00
copy16 params_addr, current_textfont ; set font to passed address
2017-10-08 03:22:39 +00:00
;; Compute addresses of each row of the glyphs.
prepare_font:
2018-03-24 02:54:07 +00:00
ldy #0 ; copy first 3 bytes of font defn (type, lastchar, height) to $FD-$FF
2018-01-29 16:25:56 +00:00
: lda (current_textfont),y
2017-09-17 18:18:47 +00:00
sta $FD,y
iny
2017-10-08 03:22:39 +00:00
cpy #3
bne :-
2018-03-30 14:58:10 +00:00
cmp #max_font_height+1 ; if height >= 17, skip this next bit
bcs end
2017-10-08 03:22:39 +00:00
ldax current_textfont
2017-09-17 18:18:47 +00:00
clc
2017-10-08 03:22:39 +00:00
adc #3
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax glyph_widths ; set $FB/$FC to start of widths
2017-10-08 03:22:39 +00:00
2017-09-17 18:18:47 +00:00
sec
adc glyph_last
bcc :+
2017-09-17 18:18:47 +00:00
inx
2017-10-08 03:22:39 +00:00
: ldy #0 ; loop 0... height-1
loop: sta glyph_row_lo,y
2017-09-17 18:18:47 +00:00
pha
txa
sta glyph_row_hi,y
2017-09-17 18:18:47 +00:00
pla
2017-09-17 18:18:47 +00:00
sec
adc glyph_last
2017-10-08 03:22:39 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
inx
2018-03-24 02:54:07 +00:00
: bit glyph_type ; ($80 = double width, so double the offset)
2017-10-08 03:22:39 +00:00
bpl :+
2017-09-17 18:18:47 +00:00
sec
adc glyph_last
2017-10-08 03:22:39 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
inx
2017-10-08 03:22:39 +00:00
: iny
cpy glyph_height_p
bne loop
2017-09-17 18:18:47 +00:00
rts
2018-11-18 04:34:17 +00:00
end: exit_call MGTK::Error::font_too_big
.endproc
2017-09-17 18:18:47 +00:00
glyph_row_lo:
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
glyph_row_hi:
2017-09-30 02:14:47 +00:00
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; TextWidth
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $A1
2018-01-29 08:57:55 +00:00
.proc TextWidthImpl
jsr measure_text
2017-10-06 16:09:43 +00:00
ldy #3 ; Store result (X,A) at params+3
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
txa
iny
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
;; Call with data at ($A1), length in $A3, result in (X,A)
.proc measure_text
data := $A1
length := $A3
accum := $82
ldx #0
ldy #0
sty accum
loop: sty accum+1
lda (data),y
2017-09-17 18:18:47 +00:00
tay
txa
clc
adc (glyph_widths),y
bcc :+
inc accum
: tax
ldy accum+1
2017-09-17 18:18:47 +00:00
iny
cpy length
bne loop
2017-09-17 18:18:47 +00:00
txa
ldx accum
2017-09-17 18:18:47 +00:00
rts
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-09-17 18:18:47 +00:00
2018-03-30 14:58:10 +00:00
;; Turn the current penloc into left, right, top, and bottom.
;;
;; Inputs:
;; A = width
;; $FF = height
;;
.proc penloc_to_bounds
sec
2017-10-14 06:23:31 +00:00
sbc #1
2018-03-30 14:58:10 +00:00
bcs :+
2017-09-17 18:18:47 +00:00
dex
2018-03-30 14:58:10 +00:00
: clc
2018-01-29 16:25:56 +00:00
adc current_penloc_x
2018-03-30 14:58:10 +00:00
sta right
2017-09-17 18:18:47 +00:00
txa
2018-01-29 16:25:56 +00:00
adc current_penloc_x+1
2018-03-30 14:58:10 +00:00
sta right+1
copy16 current_penloc_x, left
2018-01-29 16:25:56 +00:00
lda current_penloc_y
2018-03-30 14:58:10 +00:00
sta bottom
2018-01-29 16:25:56 +00:00
ldx current_penloc_y+1
2018-03-30 14:58:10 +00:00
stx bottom+1
2017-09-17 18:18:47 +00:00
clc
2017-10-14 06:23:31 +00:00
adc #1
2018-03-30 14:58:10 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
inx
2018-03-30 14:58:10 +00:00
: sec
sbc glyph_height_p
bcs :+
2017-09-17 18:18:47 +00:00
dex
2018-03-30 14:58:10 +00:00
: stax top
2017-09-17 18:18:47 +00:00
rts
2018-03-30 14:58:10 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $A1
2018-03-26 03:18:43 +00:00
.proc DrawTextImpl
2018-03-30 14:58:10 +00:00
text_bits_buf := $00
vid_addrs_table := $20
shift_aux_ptr := $40
shift_main_ptr := $42
blit_mask := $80
doublewidth_flag := $81
remaining_width := $9A
vid_page := $9C
text_index := $9F
2018-03-26 03:18:43 +00:00
text_addr := $A1 ; param
text_len := $A3 ; param
text_width := $A4 ; computed
2018-03-30 14:58:10 +00:00
2017-12-16 05:36:09 +00:00
jsr maybe_unstash_low_zp
jsr measure_text
2018-03-26 03:18:43 +00:00
stax text_width
2018-03-30 14:58:10 +00:00
2017-10-14 06:23:31 +00:00
ldy #0
2018-03-30 14:58:10 +00:00
sty text_index
2017-09-30 02:14:47 +00:00
sty $A0
2018-03-30 14:58:10 +00:00
sty clipped_left
sty clipped_top
jsr penloc_to_bounds
jsr clip_rect
2018-03-30 14:58:10 +00:00
bcc text_clipped
2017-09-30 02:14:47 +00:00
tya
2017-09-17 18:18:47 +00:00
ror a
2018-03-30 14:58:10 +00:00
bcc no_left_clip
2017-10-14 06:23:31 +00:00
ldy #0
2018-03-30 14:58:10 +00:00
ldx vid_page
left_clip_loop:
sty text_index
2018-03-26 03:18:43 +00:00
lda (text_addr),y
2017-09-17 18:18:47 +00:00
tay
lda (glyph_widths),y
2017-09-17 18:18:47 +00:00
clc
2018-03-30 14:58:10 +00:00
adc clipped_left ; exit loop when first partially or
bcc :+ ; fully visible glyph is found
2017-09-17 18:18:47 +00:00
inx
2018-03-30 14:58:10 +00:00
beq no_left_clip
: sta clipped_left
ldy text_index
2017-09-17 18:18:47 +00:00
iny
2018-03-30 14:58:10 +00:00
bne left_clip_loop
no_left_clip:
jsr set_up_fill_mode
jsr set_dest
2018-03-30 14:58:10 +00:00
lda left_mod14
2017-09-17 18:18:47 +00:00
clc
2018-03-30 14:58:10 +00:00
adc clipped_left
bpl :+
inc width_bytes
2017-09-30 02:14:47 +00:00
dec $A0
2018-03-30 14:58:10 +00:00
adc #14
: sta left_mod14
lda width_bytes
inc width_bytes
2018-01-29 16:25:56 +00:00
ldy current_mapwidth
2018-03-30 14:58:10 +00:00
bpl text_clip_ndbm
;; For an on-screen destination, width_bytes is set up for the
;; pattern blitter, which thinks in terms of double (main & aux)
;; transfers. We actually want single transfers here, so we need to
;; double it and restore the carry.
2017-09-17 18:18:47 +00:00
asl a
tax
2018-03-30 14:58:10 +00:00
lda left_mod14
2017-10-14 06:23:31 +00:00
cmp #7
2018-03-30 14:58:10 +00:00
bcs :+
2017-09-17 18:18:47 +00:00
inx
2018-03-30 14:58:10 +00:00
: lda right
beq :+
2017-09-17 18:18:47 +00:00
inx
2018-03-30 14:58:10 +00:00
: stx width_bytes
text_clip_ndbm:
lda left_mod14
2017-09-17 18:18:47 +00:00
sec
2017-10-14 06:23:31 +00:00
sbc #7
2018-03-30 14:58:10 +00:00
bcc :+
sta left_mod14
:
lda #0
rol a ; if left_mod14 was >= 7, then A=1 else A=0
eor #1 ; if left_mod14 <7, then A=1 (aux) else A=0 (main)
sta vid_page
2017-09-17 18:18:47 +00:00
tax
2018-03-30 14:58:10 +00:00
sta LOWSCR,x ; set starting page
jsr do_draw
sta LOWSCR
2018-03-30 14:58:10 +00:00
text_clipped:
jsr maybe_stash_low_zp
2018-03-26 03:18:43 +00:00
ldax text_width
2017-10-08 15:42:27 +00:00
jmp adjust_xpos
2017-09-17 18:18:47 +00:00
2018-03-30 14:58:10 +00:00
do_draw:
lda bottom
2017-09-17 18:18:47 +00:00
sec
2018-03-30 14:58:10 +00:00
sbc top
2017-09-17 18:18:47 +00:00
asl a
tax
2018-03-30 14:58:10 +00:00
;; Calculate offsets to the draw and blit routines so that they draw
;; the exact number of needed lines.
lda shifted_draw_line_table,x
sta shifted_draw_jmp_addr
lda shifted_draw_line_table+1,x
sta shifted_draw_jmp_addr+1
lda unshifted_draw_line_table,x
sta unshifted_draw_jmp_addr
lda unshifted_draw_line_table+1,x
sta unshifted_draw_jmp_addr+1
lda unmasked_blit_line_table,x
sta unmasked_blit_jmp_addr
lda unmasked_blit_line_table+1,x
sta unmasked_blit_jmp_addr+1
lda masked_blit_line_table,x
sta masked_blit_jmp_addr
lda masked_blit_line_table+1,x
sta masked_blit_jmp_addr+1
2017-09-17 18:18:47 +00:00
txa
lsr a
tax
sec
2017-09-30 02:14:47 +00:00
stx $80
2017-09-17 18:18:47 +00:00
stx $81
2017-10-14 06:23:31 +00:00
lda #0
2018-03-30 14:58:10 +00:00
sbc clipped_top
sta clipped_top
2017-09-17 18:18:47 +00:00
tay
2018-03-30 14:58:10 +00:00
ldx #(max_font_height-1)*shifted_draw_line_size
2017-09-17 18:18:47 +00:00
sec
2018-03-30 14:58:10 +00:00
: lda glyph_row_lo,y
sta shifted_draw_linemax+1,x
lda glyph_row_hi,y
2018-03-30 14:58:10 +00:00
sta shifted_draw_linemax+2,x
2017-09-17 18:18:47 +00:00
txa
2018-03-30 14:58:10 +00:00
sbc #shifted_draw_line_size
2017-09-17 18:18:47 +00:00
tax
iny
2017-09-30 02:14:47 +00:00
dec $80
2018-03-30 14:58:10 +00:00
bpl :-
ldy clipped_top
ldx #(max_font_height-1)*unshifted_draw_line_size
2017-09-17 18:18:47 +00:00
sec
2018-03-30 14:58:10 +00:00
: lda glyph_row_lo,y
sta unshifted_draw_linemax+1,x
lda glyph_row_hi,y
2018-03-30 14:58:10 +00:00
sta unshifted_draw_linemax+2,x
2017-09-17 18:18:47 +00:00
txa
2018-03-30 14:58:10 +00:00
sbc #unshifted_draw_line_size
2017-09-17 18:18:47 +00:00
tax
iny
dec $81
2018-03-30 14:58:10 +00:00
bpl :-
ldy top
ldx #0
;; Populate the pointers in vid_addrs_table for the lines we are
;; going to be drawing to.
text_dest_loop:
bit current_mapwidth
bmi text_dest_dhgr
lda vid_addr
2017-09-17 18:18:47 +00:00
clc
2018-01-29 16:25:56 +00:00
adc current_mapwidth
2018-03-30 14:58:10 +00:00
sta vid_addr
sta vid_addrs_table,x
lda vid_addr+1
adc #0
sta vid_addr+1
sta vid_addrs_table+1,x
bne text_dest_next
text_dest_dhgr:
lda hires_table_lo,y
2017-09-17 18:18:47 +00:00
clc
2018-03-30 14:58:10 +00:00
adc left_bytes
sta vid_addrs_table,x
2017-09-30 22:32:38 +00:00
lda hires_table_hi,y
2018-01-29 16:25:56 +00:00
ora current_mapbits+1
2018-03-30 14:58:10 +00:00
sta vid_addrs_table+1,x
text_dest_next:
cpy bottom
beq :+
2017-09-30 02:14:47 +00:00
iny
2017-09-17 18:18:47 +00:00
inx
inx
2018-03-30 14:58:10 +00:00
bne text_dest_loop
:
ldx #15
lda #0
: sta text_bits_buf,x
2017-09-17 18:18:47 +00:00
dex
2018-03-30 14:58:10 +00:00
bpl :-
sta doublewidth_flag
sta shift_aux_ptr ; zero
2017-09-17 18:18:47 +00:00
lda #$80
2018-03-30 14:58:10 +00:00
sta shift_main_ptr
ldy text_index
next_glyph:
lda (text_addr),y
2017-09-17 18:18:47 +00:00
tay
2018-03-30 14:58:10 +00:00
bit doublewidth_flag
bpl :+
2017-09-17 18:18:47 +00:00
sec
2018-03-30 14:58:10 +00:00
adc glyph_last
:
tax
lda (glyph_widths),y
2018-03-30 14:58:10 +00:00
beq zero_width_glyph
ldy left_mod14
bne shifted_draw
;; Transfer one column of one glyph into the text_bits_buf[0..15]
unshifted_draw_jmp_addr := *+1
jmp unshifted_draw_linemax ; patched to jump into following block
;; Unrolled loop from max_font_height-1 down to 0
unshifted_draw_linemax:
.repeat max_font_height, line
.ident (.sprintf ("unshifted_draw_line_%d", max_font_height-line-1)):
: lda $FFFF,x
sta text_bits_buf+max_font_height-line-1
.ifndef unshifted_draw_line_size
unshifted_draw_line_size := * - :-
.else
.assert unshifted_draw_line_size = * - :-, error, "unshifted_draw_line_size inconsistent"
.endif
.endrepeat
zero_width_glyph:
jmp do_blit
;; Transfer one column of one glyph, shifting it into
;; text_bits_buf[0..15] and text_bits_buf[16..31] by left_mod14 bits.
shifted_draw:
tya
2017-09-17 18:18:47 +00:00
asl a
tay
2018-03-30 14:58:10 +00:00
copy16 shift_table_aux,y, shift_aux_ptr
copy16 shift_table_main,y, shift_main_ptr
shifted_draw_jmp_addr := *+1
jmp shifted_draw_linemax ; patched to jump into following block
;; Unrolled loop from max_font_height-1 down to 0
shifted_draw_linemax:
.repeat max_font_height, line
.ident (.sprintf ("shifted_draw_line_%d", max_font_height-line-1)):
: ldy $FFFF,x ; All of these $FFFFs are modified
lda (shift_main_ptr),y
sta text_bits_buf+16+max_font_height-line-1
lda (shift_aux_ptr),y
ora text_bits_buf+max_font_height-line-1
sta text_bits_buf+max_font_height-line-1
.ifndef shifted_draw_line_size
shifted_draw_line_size := * - :-
.else
.assert shifted_draw_line_size = * - :-, error, "shifted_draw_line_size inconsistent"
.endif
.endrepeat
do_blit:
bit doublewidth_flag
bpl :+
inc text_index ; completed a double-width glyph
lda #0
sta doublewidth_flag
lda remaining_width
bne advance_x ; always
: txa
2017-09-17 18:18:47 +00:00
tay
lda (glyph_widths),y
2018-03-30 14:58:10 +00:00
cmp #8
bcs :+
inc text_index ; completed a single-width glyph
bcc advance_x
: sbc #7
sta remaining_width
ror doublewidth_flag ; will set to negative
lda #7 ; did the first 7 pixels of a
; double-width glyph
advance_x:
clc
adc left_mod14
cmp #7
bcs advance_byte
sta left_mod14
L5BFF: ldy text_index
2018-03-26 03:18:43 +00:00
cpy text_len
2018-03-30 14:58:10 +00:00
beq :+
jmp next_glyph
2017-09-17 18:18:47 +00:00
2018-03-30 14:58:10 +00:00
: ldy $A0
jmp last_blit
advance_byte:
sbc #7
sta left_mod14
2017-09-17 18:18:47 +00:00
2017-09-30 02:14:47 +00:00
ldy $A0
2018-03-30 14:58:10 +00:00
bne :+
jmp first_blit
2017-09-17 18:18:47 +00:00
: bmi next_byte
2018-03-30 14:58:10 +00:00
dec width_bytes
bne unmasked_blit
jmp last_blit
2017-09-17 18:18:47 +00:00
2018-03-30 14:58:10 +00:00
unmasked_blit:
unmasked_blit_jmp_addr := *+1
jmp unmasked_blit_linemax ; patched to jump into block below
2017-09-30 02:14:47 +00:00
;;; Per JB: "looks like the quickdraw fast-path draw unclipped pattern slab"
2018-03-30 14:58:10 +00:00
;; Unrolled loop from max_font_height-1 down to 0
unmasked_blit_linemax:
.repeat max_font_height, line
.ident (.sprintf ("unmasked_blit_line_%d", max_font_height-line-1)):
: lda text_bits_buf+max_font_height-line-1
2018-01-29 16:25:56 +00:00
eor current_textback
2018-03-30 14:58:10 +00:00
sta (vid_addrs_table + 2*(max_font_height-line-1)),y
.ifndef unmasked_blit_line_size
unmasked_blit_line_size := * - :-
.else
.assert unmasked_blit_line_size = * - :-, error, "unmasked_blit_line_size inconsistent"
.endif
.endrepeat
next_byte:
bit current_mapwidth
2018-03-30 14:58:10 +00:00
bpl text_ndbm
2018-03-30 14:58:10 +00:00
lda vid_page
eor #1
2017-09-17 18:18:47 +00:00
tax
2018-03-30 14:58:10 +00:00
sta vid_page
sta LOWSCR,x
2018-03-30 14:58:10 +00:00
beq :+
text_ndbm:
inc $A0
:
COPY_BYTES 16, text_bits_buf+16, text_bits_buf
2017-09-17 18:18:47 +00:00
jmp L5BFF
2018-03-30 14:58:10 +00:00
;; This is the first (left-most) blit, so it needs masks. If this is
;; also the last blit, apply the right mask as well.
first_blit:
ldx vid_page
lda left_masks_table,x
dec width_bytes
beq single_byte_blit
jsr masked_blit
jmp next_byte
2017-09-17 18:18:47 +00:00
2018-03-30 14:58:10 +00:00
single_byte_blit: ; a single byte length blit; i.e. start
and right_masks_table,x ; and end bytes are the same
bne masked_blit
2017-09-17 18:18:47 +00:00
rts
2018-03-30 14:58:10 +00:00
;; This is the last (right-most) blit, so we have to set up masking.
last_blit:
ldx vid_page
lda right_masks_table,x
masked_blit:
ora #$80
sta blit_mask
masked_blit_jmp_addr := *+1
jmp masked_blit_linemax
2017-09-30 02:14:47 +00:00
;;; Per JB: "looks like the quickdraw slow-path draw clipped pattern slab"
2018-03-30 14:58:10 +00:00
;; Unrolled loop from max_font_height-1 down to 0
masked_blit_linemax:
.repeat max_font_height, line
.ident (.sprintf ("masked_blit_line_%d", max_font_height-line-1)):
: lda text_bits_buf+max_font_height-line-1
2018-01-29 16:25:56 +00:00
eor current_textback
2018-03-30 14:58:10 +00:00
eor (vid_addrs_table + 2*(max_font_height-line-1)),y
and blit_mask
eor (vid_addrs_table + 2*(max_font_height-line-1)),y
sta (vid_addrs_table + 2*(max_font_height-line-1)),y
.ifndef masked_blit_line_size
masked_blit_line_size := * - :-
.else
.assert masked_blit_line_size = * - :-, error, "masked_blit_line_size inconsistent"
.endif
.endrepeat
2017-09-17 18:18:47 +00:00
rts
2018-03-30 14:58:10 +00:00
shifted_draw_line_table:
.repeat max_font_height, line
.addr .ident (.sprintf ("shifted_draw_line_%d", line))
.endrepeat
unshifted_draw_line_table:
.repeat max_font_height, line
.addr .ident (.sprintf ("unshifted_draw_line_%d", line))
.endrepeat
unmasked_blit_line_table:
.repeat max_font_height, line
.addr .ident (.sprintf ("unmasked_blit_line_%d", line))
.endrepeat
masked_blit_line_table:
.repeat max_font_height, line
.addr .ident (.sprintf ("masked_blit_line_%d", line))
.endrepeat
2018-03-26 03:18:43 +00:00
.endproc
;;; ============================================================
2017-10-07 20:59:25 +00:00
2017-12-16 05:36:09 +00:00
low_zp_stash_buffer:
poly_maxima_yh_table:
.res 16
2017-10-07 20:59:25 +00:00
poly_maxima_x_frach:
.res 16
2017-10-07 20:59:25 +00:00
poly_maxima_x_fracl:
.res 16
poly_maxima_xl_table:
.res 16
poly_maxima_xh_table:
.res 16
2017-10-07 20:59:25 +00:00
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; InitGraf
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc InitGrafImpl
lda #$71 ; %0001 lo nibble = HiRes, Page 1, Full, Graphics
sta $82 ; (why is high nibble 7 ???)
2018-01-29 08:57:55 +00:00
jsr SetSwitchesImpl
2018-01-29 16:25:56 +00:00
;; Initialize port
2018-05-26 01:39:43 +00:00
ldx #.sizeof(MGTK::GrafPort)-1
2018-01-29 16:25:56 +00:00
loop: lda standard_port,x
2017-09-17 18:18:47 +00:00
sta $8A,x
2018-01-29 16:25:56 +00:00
sta current_grafport,x
2017-09-17 18:18:47 +00:00
dex
bpl loop
ldax saved_port_addr
2018-01-29 16:25:56 +00:00
jsr assign_and_prepare_port
2017-09-17 18:18:47 +00:00
lda #$7F
2017-10-08 03:22:39 +00:00
sta fill_eor_mask
2018-01-29 08:57:55 +00:00
jsr PaintRectImpl
2017-09-17 18:18:47 +00:00
lda #$00
2017-10-08 03:22:39 +00:00
sta fill_eor_mask
2017-09-17 18:18:47 +00:00
rts
2018-01-29 16:25:56 +00:00
saved_port_addr:
.addr saved_port
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetSwitches
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte param, copied to $82
;;; Toggle display softswitches
;;; bit 0: LoRes if clear, HiRes if set
;;; bit 1: Page 1 if clear, Page 2 if set
;;; bit 2: Full screen if clear, split screen if set
;;; bit 3: Graphics if clear, text if set
2018-01-29 08:57:55 +00:00
.proc SetSwitchesImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
switches: .res 1
END_PARAM_BLOCK
lda DHIRESON ; enable dhr graphics
sta SET80VID
ldx #3
2018-04-28 23:22:33 +00:00
loop: lsr params::switches ; shift low bit into carry
lda table,x
2017-09-17 18:18:47 +00:00
rol a
tay ; y = table[x] * 2 + carry
bcs store
lda $C000,y ; why load vs. store ???
bcc :+
store: sta $C000,y
: dex
bpl loop
2017-09-17 18:18:47 +00:00
rts
table: .byte <(TXTCLR / 2), <(MIXCLR / 2), <(LOWSCR / 2), <(LORES / 2)
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetPort
2017-10-03 03:05:07 +00:00
2018-01-29 08:57:55 +00:00
.proc SetPortImpl
ldax params_addr
;; fall through
.endproc
2018-01-29 16:25:56 +00:00
;; Call with port address in (X,A)
assign_and_prepare_port:
stax active_port
;; fall through
2018-01-29 16:25:56 +00:00
;; Initializes font (if needed), port, pattern, and fill mode
prepare_port:
lda current_textfont+1
beq :+ ; only prepare font if necessary
2018-01-29 08:57:55 +00:00
jsr SetFontImpl::prepare_font
: jsr SetPortBitsImpl
jsr SetPatternImpl
jmp SetPenModeImpl
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetPort
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc GetPortImpl
2018-01-29 16:25:56 +00:00
jsr apply_port_to_active_port
ldax active_port
;; fall through
2017-10-12 15:04:27 +00:00
.endproc
;; Store result (X,A) at params
store_xa_at_params:
ldy #0
;; Store result (X,A) at params+Y
2018-02-28 02:38:18 +00:00
store_xa_at_y:
sta (params_addr),y
2017-09-17 18:18:47 +00:00
txa
iny
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
rts
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; InitPort
2017-10-03 03:05:07 +00:00
2018-01-29 08:57:55 +00:00
.proc InitPortImpl
2018-05-26 01:39:43 +00:00
ldy #.sizeof(MGTK::GrafPort)-1 ; Store 36 bytes at params
2018-01-29 16:25:56 +00:00
loop: lda standard_port,y
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
dey
2017-10-07 22:07:12 +00:00
bpl loop
.endproc
rts3: rts
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetZP1
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
2018-01-29 08:57:55 +00:00
.proc SetZP1Impl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
flag: .res 1
END_PARAM_BLOCK
2017-10-07 22:07:12 +00:00
2018-04-28 23:22:33 +00:00
lda params::flag
2017-10-06 04:18:28 +00:00
cmp preserve_zp_flag
2017-10-07 22:07:12 +00:00
beq rts3
2017-10-06 04:18:28 +00:00
sta preserve_zp_flag
2017-10-07 22:07:12 +00:00
bcc rts3
2018-01-29 08:57:55 +00:00
jmp dispatch::cleanup
2017-10-07 22:07:12 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetZP2
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
2017-12-31 05:22:06 +00:00
;;; If high bit set stash ZP $00-$43 to buffer if not already stashed.
2017-12-16 05:36:09 +00:00
;;; If high bit clear unstash ZP $00-$43 from buffer if not already unstashed.
2018-01-29 08:57:55 +00:00
.proc SetZP2Impl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
flag: .res 1
END_PARAM_BLOCK
lda params::flag
2017-12-16 05:36:09 +00:00
cmp low_zp_stash_flag
2017-10-07 22:07:12 +00:00
beq rts3
2017-12-16 05:36:09 +00:00
sta low_zp_stash_flag
bcc unstash
maybe_stash:
bit low_zp_stash_flag
bpl end
;; Copy buffer to ZP $00-$43
stash: COPY_BYTES $44, low_zp_stash_buffer, $00
2017-09-17 18:18:47 +00:00
2017-12-16 05:36:09 +00:00
end: rts
2017-10-03 02:48:21 +00:00
2017-12-16 05:36:09 +00:00
maybe_unstash:
bit low_zp_stash_flag
bpl end
;; Copy ZP $00-$43 to buffer
unstash:
COPY_BYTES $44, $00, low_zp_stash_buffer
2017-09-17 18:18:47 +00:00
rts
2017-12-16 05:36:09 +00:00
.endproc
2018-01-29 08:57:55 +00:00
maybe_stash_low_zp := SetZP2Impl::maybe_stash
maybe_unstash_low_zp := SetZP2Impl::maybe_unstash
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; Version
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc VersionImpl
ldy #5 ; Store 6 bytes at params
2018-01-29 08:57:55 +00:00
loop: lda version,y
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-30 02:14:47 +00:00
dey
bpl loop
2017-09-17 18:18:47 +00:00
rts
2018-01-29 08:57:55 +00:00
.proc version
major: .byte 1 ; 1.0.0
minor: .byte 0
patch: .byte 0
2018-01-30 04:14:34 +00:00
status: .byte 'F' ; Final???
2018-01-29 08:57:55 +00:00
release:.byte 1 ; ???
.byte 0 ; ???
.endproc
.endproc
2017-10-07 03:59:09 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-07 03:59:09 +00:00
2018-01-29 05:18:00 +00:00
preserve_zp_flag: ; if high bit set, ZP saved during MGTK calls
.byte $80
2017-10-07 03:59:09 +00:00
2017-12-16 05:36:09 +00:00
low_zp_stash_flag:
.byte $80
2017-10-07 03:59:09 +00:00
stack_ptr_stash:
.byte 0
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 16:25:56 +00:00
;;; Standard GrafPort
.proc standard_port
viewloc: .word 0, 0
mapbits: .addr MGTK::screen_mapbits
mapwidth: .word MGTK::screen_mapwidth
2018-03-02 02:25:42 +00:00
maprect: .word 0, 0, screen_width-1, screen_height-1
2018-01-29 16:25:56 +00:00
penpattern: .res 8, $FF
colormasks: .byte MGTK::colormask_and, MGTK::colormask_or
penloc: .word 0, 0
penwidth: .byte 1
penheight: .byte 1
mode: .byte 0
textback: .byte 0
textfont: .addr 0
2017-10-07 03:59:09 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-06 04:18:28 +00:00
2018-01-29 16:25:56 +00:00
.proc saved_port
viewloc: .word 0, 0
mapbits: .addr MGTK::screen_mapbits
mapwidth: .word MGTK::screen_mapwidth
2018-03-02 02:25:42 +00:00
maprect: .word 0, 0, screen_width-1, screen_height-1
2018-01-29 16:25:56 +00:00
penpattern: .res 8, $FF
colormasks: .byte MGTK::colormask_and, MGTK::colormask_or
penloc: .word 0, 0
penwidth: .byte 1
penheight: .byte 1
mode: .byte 0
textback: .byte 0
textfont: .addr 0
.endproc
active_saved: ; saved copy of $F4...$FF when ZP swapped
2018-01-29 16:25:56 +00:00
.addr saved_port
.res 10, 0
zp_saved: ; top half of ZP for when preserve_zp_flag set
.res 128, 0
2017-10-06 04:18:28 +00:00
2017-10-14 19:51:25 +00:00
;; cursor shown/hidden flags/counts
cursor_flag: ; high bit clear if cursor drawn, set if not drawn
.byte 0
cursor_count:
.byte $FF ; decremented on hide, incremented on shown; 0 = visible
.proc set_pos_params
xcoord: .word 0
ycoord: .word 0
.endproc
mouse_state:
mouse_x: .word 0
mouse_y: .word 0
mouse_status: .byte 0 ; bit 7 = is down, bit 6 = was down, still down
2018-03-24 04:27:58 +00:00
mouse_scale_x: .byte $00
mouse_scale_y: .byte $00
mouse_hooked_flag: ; High bit set if mouse is "hooked", and calls
.byte 0 ; bypassed; never appears to be set.
mouse_hook:
.addr 0
2017-10-14 19:51:25 +00:00
cursor_hotspot_x: .byte $00
cursor_hotspot_y: .byte $00
cursor_mod7:
.res 1
cursor_bits:
.res 3
cursor_mask:
.res 3
cursor_savebits:
.res 3*MGTK::cursor_height ; Saved 3 screen bytes per row.
cursor_data:
.res 4 ; Saved values of cursor_char..cursor_y2.
pointer_cursor:
.byte px(%0000000),px(%0000000)
.byte px(%0100000),px(%0000000)
.byte px(%0110000),px(%0000000)
.byte px(%0111000),px(%0000000)
.byte px(%0111100),px(%0000000)
.byte px(%0111110),px(%0000000)
.byte px(%0111111),px(%0000000)
.byte px(%0101100),px(%0000000)
.byte px(%0000110),px(%0000000)
.byte px(%0000110),px(%0000000)
.byte px(%0000011),px(%0000000)
.byte px(%0000000),px(%0000000)
.byte px(%1100000),px(%0000000)
.byte px(%1110000),px(%0000000)
.byte px(%1111000),px(%0000000)
.byte px(%1111100),px(%0000000)
.byte px(%1111110),px(%0000000)
.byte px(%1111111),px(%0000000)
.byte px(%1111111),px(%1000000)
.byte px(%1111111),px(%0000000)
.byte px(%0001111),px(%0000000)
.byte px(%0001111),px(%0000000)
.byte px(%0000111),px(%1000000)
.byte px(%0000111),px(%1000000)
.byte 1,1
pointer_cursor_addr:
.addr pointer_cursor
.proc set_pointer_cursor
lda #$FF
2017-10-14 19:51:25 +00:00
sta cursor_count
lda #0
sta cursor_flag
lda pointer_cursor_addr
sta params_addr
lda pointer_cursor_addr+1
sta params_addr+1
2017-10-07 20:59:25 +00:00
;; fall through
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetCursor
2017-10-03 03:05:07 +00:00
2017-10-14 19:51:25 +00:00
.proc SetCursorImpl
2017-10-03 03:05:07 +00:00
php
2017-09-17 18:18:47 +00:00
sei
ldax params_addr
stax active_cursor
2017-09-17 18:18:47 +00:00
clc
2018-05-26 07:35:28 +00:00
adc #MGTK::Cursor::mask
2017-10-14 19:51:25 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax active_cursor_mask
2018-05-26 07:35:28 +00:00
ldy #MGTK::Cursor::hotspot
2017-10-07 20:59:25 +00:00
lda (params_addr),y
2017-10-14 19:51:25 +00:00
sta cursor_hotspot_x
2017-09-17 18:18:47 +00:00
iny
2017-10-07 20:59:25 +00:00
lda (params_addr),y
2017-10-14 19:51:25 +00:00
sta cursor_hotspot_y
jsr restore_cursor_background
jsr draw_cursor
2017-09-17 18:18:47 +00:00
plp
.endproc
srts: rts
cursor_bytes := $82
cursor_softswitch := $83
cursor_y1 := $84
cursor_y2 := $85
2017-09-17 18:18:47 +00:00
vid_ptr := $88
.proc update_cursor
2017-10-14 19:51:25 +00:00
lda cursor_count ; hidden? if so, skip
bne srts
2017-10-14 19:51:25 +00:00
bit cursor_flag
bmi srts
;; Fall-through
.endproc
2017-10-14 19:51:25 +00:00
.proc draw_cursor
lda #0
2017-10-14 19:51:25 +00:00
sta cursor_count
sta cursor_flag
lda set_pos_params::ycoord
2017-09-17 18:18:47 +00:00
clc
2017-10-14 19:51:25 +00:00
sbc cursor_hotspot_y
sta cursor_y1
2017-09-17 18:18:47 +00:00
clc
adc #MGTK::cursor_height
sta cursor_y2
lda set_pos_params::xcoord
2017-09-17 18:18:47 +00:00
sec
2017-10-14 19:51:25 +00:00
sbc cursor_hotspot_x
2017-09-17 18:18:47 +00:00
tax
lda set_pos_params::xcoord+1
sbc #0
bpl :+
txa ; X-coord is negative: X-reg = X-coord + 256
ror a ; Will shift in zero: X-reg = X-coord/2 + 128
tax ; Negative mod7 table starts at 252 (since 252%7 = 0), and goes backwards
ldy mod7_table+252-128,x ; Index (X-coord / 2 = X-reg - 128) relative to mod7_table+252
lda #$FF ; Char index = -1
bmi set_divmod
: jsr divmod7
set_divmod:
sta cursor_bytes ; char index in line
2017-09-17 18:18:47 +00:00
tya
rol a
cmp #7
bcc :+
sbc #7
: tay
lda #<LOWSCR/2
rol a ; if mod >= 7, then will be HISCR, else LOWSCR
eor #1
sta cursor_softswitch ; $C0xx softswitch index
sty cursor_mod7
2017-09-17 18:18:47 +00:00
tya
asl a
tay
copy16 shift_table_main,y, cursor_shift_main_addr
copy16 shift_table_aux,y, cursor_shift_aux_addr
ldx #3
: lda cursor_bytes,x
sta cursor_data,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-09-17 18:18:47 +00:00
ldx #$17
stx left_bytes
2017-09-17 18:18:47 +00:00
ldx #$23
ldy cursor_y2
dloop: cpy #192
bcc :+
jmp drnext
2017-09-17 18:18:47 +00:00
: lda hires_table_lo,y
sta vid_ptr
2017-09-30 22:32:38 +00:00
lda hires_table_hi,y
2017-09-17 18:18:47 +00:00
ora #$20
sta vid_ptr+1
sty cursor_y2
stx left_mod14
ldy left_bytes
2017-09-17 18:18:47 +00:00
ldx #$01
:
2017-10-14 19:51:25 +00:00
active_cursor := * + 1
2017-09-30 02:51:11 +00:00
lda $FFFF,y
sta cursor_bits,x
2017-10-14 19:51:25 +00:00
active_cursor_mask := * + 1
2017-09-30 02:51:11 +00:00
lda $FFFF,y
sta cursor_mask,x
2017-09-17 18:18:47 +00:00
dey
dex
bpl :-
lda #0
sta cursor_bits+2
sta cursor_mask+2
ldy cursor_mod7
beq no_shift
ldy #5
: ldx cursor_bits-1,y
cursor_shift_main_addr := * + 1
2017-09-30 02:14:47 +00:00
ora $FF80,x
sta cursor_bits,y
cursor_shift_aux_addr := * + 1
2017-09-30 02:14:47 +00:00
lda $FF00,x
2017-09-17 18:18:47 +00:00
dey
bne :-
sta cursor_bits
no_shift:
ldx left_mod14
ldy cursor_bytes
lda cursor_softswitch
jsr set_switch
bcs :+
lda (vid_ptr),y
sta cursor_savebits,x
lda cursor_mask
ora (vid_ptr),y
eor cursor_bits
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
jsr switch_page
bcs :+
lda (vid_ptr),y
sta cursor_savebits,x
lda cursor_mask+1
ora (vid_ptr),y
eor cursor_bits+1
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
jsr switch_page
bcs :+
lda (vid_ptr),y
sta cursor_savebits,x
lda cursor_mask+2
ora (vid_ptr),y
eor cursor_bits+2
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
ldy cursor_y2
drnext:
dec left_bytes
dec left_bytes
2017-09-17 18:18:47 +00:00
dey
cpy cursor_y1
beq lowscr_rts
jmp dloop
.endproc
drts: rts
active_cursor := draw_cursor::active_cursor
active_cursor_mask := draw_cursor::active_cursor_mask
2017-09-17 18:18:47 +00:00
.proc restore_cursor_background
2017-10-14 19:51:25 +00:00
lda cursor_count ; already hidden?
bne drts
2017-10-14 19:51:25 +00:00
bit cursor_flag
bmi drts
2017-10-14 19:51:25 +00:00
COPY_BYTES 4, cursor_data, cursor_bytes
2017-09-17 18:18:47 +00:00
ldx #$23
ldy cursor_y2
cloop: cpy #192
bcs cnext
2017-09-30 22:32:38 +00:00
lda hires_table_lo,y
sta vid_ptr
2017-09-30 22:32:38 +00:00
lda hires_table_hi,y
2017-09-17 18:18:47 +00:00
ora #$20
sta vid_ptr+1
sty cursor_y2
ldy cursor_bytes
lda cursor_softswitch
jsr set_switch
bcs :+
lda cursor_savebits,x
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
jsr switch_page
bcs :+
lda cursor_savebits,x
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
jsr switch_page
bcs :+
lda cursor_savebits,x
sta (vid_ptr),y
2017-09-17 18:18:47 +00:00
dex
:
ldy cursor_y2
cnext: dey
cpy cursor_y1
bne cloop
.endproc
lowscr_rts:
sta LOWSCR
2017-09-30 02:14:47 +00:00
rts
2017-09-17 18:18:47 +00:00
.proc switch_page
lda set_switch_sta_addr
eor #1
cmp #<LOWSCR
beq set_switch
2017-09-17 18:18:47 +00:00
iny
;; Fall through
.endproc
.proc set_switch
sta switch_sta_addr
switch_sta_addr := *+1
sta $C0FF
cpy #$28
2017-09-17 18:18:47 +00:00
rts
.endproc
set_switch_sta_addr := set_switch::switch_sta_addr
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; ShowCursor
2017-10-03 03:05:07 +00:00
2018-01-29 08:57:55 +00:00
.proc ShowCursorImpl
2017-10-03 03:05:07 +00:00
php
2017-09-17 18:18:47 +00:00
sei
2017-10-14 19:51:25 +00:00
lda cursor_count
2017-10-07 20:59:25 +00:00
beq done
2017-10-14 19:51:25 +00:00
inc cursor_count
2017-10-07 20:59:25 +00:00
bmi done
beq :+
2017-10-14 19:51:25 +00:00
dec cursor_count
: bit cursor_flag
2017-10-07 20:59:25 +00:00
bmi done
2017-10-14 19:51:25 +00:00
jsr draw_cursor
2017-10-07 20:59:25 +00:00
done: plp
2017-09-17 18:18:47 +00:00
rts
2017-10-07 20:59:25 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; ObscureCursor
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc ObscureCursorImpl
2017-09-17 18:18:47 +00:00
php
sei
2017-10-14 19:51:25 +00:00
jsr restore_cursor_background
2017-09-17 18:18:47 +00:00
lda #$80
2017-10-14 19:51:25 +00:00
sta cursor_flag
2017-09-17 18:18:47 +00:00
plp
rts
2017-10-14 19:56:59 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; HideCursor
2017-10-03 03:05:07 +00:00
.proc HideCursorImpl
2017-10-03 03:05:07 +00:00
php
2017-09-17 18:18:47 +00:00
sei
2017-10-14 19:51:25 +00:00
jsr restore_cursor_background
dec cursor_count
2017-09-17 18:18:47 +00:00
plp
.endproc
mrts: rts
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
cursor_throttle:
.byte 0
.proc move_cursor
bit use_interrupts
bpl :+
2018-03-24 02:43:22 +00:00
lda kbd_mouse_state
bne :+
dec cursor_throttle
lda cursor_throttle
bpl mrts
lda #2
sta cursor_throttle
: ldx #2
: lda mouse_x,x
2017-10-01 23:17:04 +00:00
cmp set_pos_params,x
bne mouse_moved
2017-09-17 18:18:47 +00:00
dex
bpl :-
bmi no_move
mouse_moved:
jsr restore_cursor_background
ldx #2
2017-10-14 19:51:25 +00:00
stx cursor_flag
: lda mouse_x,x
2017-10-01 23:17:04 +00:00
sta set_pos_params,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-10-14 19:51:25 +00:00
jsr update_cursor
no_move:
bit no_mouse_flag
bmi :+
2018-03-24 04:27:58 +00:00
jsr read_mouse_pos
: bit no_mouse_flag
bpl :+
lda #0
sta mouse_status
: lda kbd_mouse_state
2017-10-07 22:07:12 +00:00
beq rts4
jsr handle_keyboard_mouse
.endproc
2017-10-07 22:07:12 +00:00
rts4: rts
2017-09-17 18:18:47 +00:00
2018-03-24 04:27:58 +00:00
;;; ============================================================
.proc read_mouse_pos
ldy #READMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
bit mouse_hooked_flag
2018-03-24 04:27:58 +00:00
bmi do_scale_x
2017-10-07 22:07:12 +00:00
ldx mouse_firmware_hi
lda MOUSE_X_LO,x
sta mouse_x
lda MOUSE_X_HI,x
sta mouse_x+1
lda MOUSE_Y_LO,x
sta mouse_y
2018-03-24 04:27:58 +00:00
;; Scale X
do_scale_x:
ldy mouse_scale_x
beq do_scale_y
: lda mouse_x
2017-09-17 18:18:47 +00:00
asl a
sta mouse_x
lda mouse_x+1
2017-09-17 18:18:47 +00:00
rol a
sta mouse_x+1
2017-09-17 18:18:47 +00:00
dey
2018-03-24 04:27:58 +00:00
bne :-
;; Scale Y
do_scale_y:
ldy mouse_scale_y
beq done_scaling
lda mouse_y
2018-03-24 04:27:58 +00:00
: asl a
2017-09-17 18:18:47 +00:00
dey
2018-03-24 04:27:58 +00:00
bne :-
sta mouse_y
2018-03-24 04:27:58 +00:00
done_scaling:
bit mouse_hooked_flag
bmi done
lda MOUSE_STATUS,x
sta mouse_status
2018-03-24 04:27:58 +00:00
done: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetCursorAddr
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc GetCursorAddrImpl
ldax active_cursor
jmp store_xa_at_params
2017-10-14 19:51:25 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-09-17 18:18:47 +00:00
2017-10-07 22:07:12 +00:00
;; Call mouse firmware, operation in Y, param in A
.proc call_mouse
proc_ptr := $88
2017-10-07 22:07:12 +00:00
bit no_mouse_flag
bmi rts4
bit mouse_hooked_flag
bmi hooked
2017-09-17 18:18:47 +00:00
pha
2017-10-07 22:07:12 +00:00
ldx mouse_firmware_hi
stx proc_ptr+1
2017-09-30 02:14:47 +00:00
lda #$00
sta proc_ptr
lda (proc_ptr),y
sta proc_ptr
2017-09-17 18:18:47 +00:00
pla
2017-10-07 22:07:12 +00:00
ldy mouse_operand
jmp (proc_ptr)
2017-09-17 18:18:47 +00:00
hooked: jmp (mouse_hook)
.endproc
2017-09-17 18:18:47 +00:00
;;; Init parameters
machid: .byte 0
subid: .byte 0
op_sys: .byte $00
slot_num:
.byte $00
use_interrupts:
.byte $00
always_handle_irq:
.byte $00
savebehind_size:
.res 2
savebehind_usage:
.res 2
2017-10-06 16:09:43 +00:00
2018-02-18 19:33:21 +00:00
desktop_initialized_flag:
2017-10-06 16:09:43 +00:00
.byte 0
save_p_reg:
.byte $00
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; StartDeskTop
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 12 bytes of params, copied to $82
.proc StartDeskTopImpl
PARAM_BLOCK params, $82
machine: .res 1
subid: .res 1
op_sys: .res 1
slot_num: .res 1
use_irq: .res 1
sysfontptr: .res 2
savearea: .res 2
savesize: .res 2
END_PARAM_BLOCK
2017-10-03 03:46:01 +00:00
php
pla
sta save_p_reg
COPY_BYTES 5, params::machine, machid
2017-10-03 03:46:01 +00:00
lda #$7F
2018-01-29 16:25:56 +00:00
sta standard_port::textback
copy16 params::sysfontptr, standard_port::textfont
copy16 params::savearea, savebehind_buffer
copy16 params::savesize, savebehind_size
jsr set_irq_mode
jsr set_op_sys
2018-05-26 07:35:28 +00:00
ldy #MGTK::Font::height
lda (params::sysfontptr),y
2017-10-03 03:46:01 +00:00
tax
stx sysfont_height
2017-10-03 03:46:01 +00:00
dex
stx goaway_height ; goaway height = font height - 1
2017-10-03 03:46:01 +00:00
inx
inx
inx
stx fill_rect_params2_height ; menu bar height = font height + 2
2017-10-03 03:46:01 +00:00
inx
stx wintitle_height ; win title height = font height + 3
2018-02-28 02:38:18 +00:00
stx test_rect_bottom
2018-01-29 16:25:56 +00:00
stx test_rect_params2_top
2017-10-03 03:46:01 +00:00
stx fill_rect_params4_top
inx ; font height + 4: top of desktop area
2018-02-28 02:38:18 +00:00
stx set_port_top
stx winframe_top
stx desktop_port_y
2018-02-28 02:38:18 +00:00
stx fill_rect_top
2017-10-03 03:46:01 +00:00
dex
2017-12-16 05:36:09 +00:00
stx menu_item_y_table
2017-10-03 03:46:01 +00:00
clc
ldy #$00
: txa
2017-12-16 05:36:09 +00:00
adc menu_item_y_table,y
2017-10-03 03:46:01 +00:00
iny
2017-12-16 05:36:09 +00:00
sta menu_item_y_table,y
cpy #menu_item_y_table_end - menu_item_y_table-1
bcc :-
2018-03-24 04:27:58 +00:00
lda #1
sta mouse_scale_x
lda #0
sta mouse_scale_y
bit subid
bvs :+
lda #2 ; default scaling for IIc/IIc+
2018-03-24 04:27:58 +00:00
sta mouse_scale_x
lda #1
sta mouse_scale_y
:
ldx slot_num
2017-10-07 22:07:12 +00:00
jsr find_mouse
bit slot_num
bpl found_mouse
cpx #0
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::no_mouse
: lda slot_num
2017-10-03 03:46:01 +00:00
and #$7F
beq found_mouse
cpx slot_num
beq found_mouse
2018-03-02 02:25:42 +00:00
exit_call $91
2017-10-03 03:46:01 +00:00
found_mouse:
stx slot_num
2017-10-03 03:46:01 +00:00
lda #$80
2018-02-18 19:33:21 +00:00
sta desktop_initialized_flag
lda slot_num
bne no_mouse
bit use_interrupts
bpl no_mouse
lda #0
sta use_interrupts
no_mouse:
2018-04-02 15:00:43 +00:00
ldy #params::slot_num - params
lda slot_num
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-10-03 03:46:01 +00:00
iny
lda use_interrupts
2017-10-07 20:59:25 +00:00
sta (params_addr),y
bit use_interrupts
bpl no_irq
bit op_sys
bpl no_irq
MLI_CALL ALLOC_INTERRUPT, alloc_interrupt_params
no_irq: lda VERSION
2017-09-17 18:18:47 +00:00
pha
lda #F8VERSION ; F8 ROM IIe ID byte
sta VERSION
ldy #SETMOUSE
lda #1
bit use_interrupts
bpl :+
2017-09-17 18:18:47 +00:00
cli
ora #8
: jsr call_mouse
2017-09-17 18:18:47 +00:00
pla
sta VERSION
2018-01-29 08:57:55 +00:00
jsr InitGrafImpl
jsr set_pointer_cursor
2018-01-29 08:57:55 +00:00
jsr FlushEventsImpl
lda #0
sta current_window+1
reset_desktop:
jsr save_params_and_stack
jsr set_desktop_port
2017-10-15 05:09:00 +00:00
;; Fills the desktop background on startup (menu left black)
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, checkerboard_pattern
MGTK_CALL MGTK::PaintRect, fill_rect_params
jmp restore_params_active_port
.endproc
2017-09-17 18:18:47 +00:00
2018-02-26 04:28:23 +00:00
DEFINE_ALLOC_INTERRUPT_PARAMS alloc_interrupt_params, interrupt_handler
DEFINE_DEALLOC_INTERRUPT_PARAMS dealloc_interrupt_params
.proc set_irq_mode
lda #0
sta always_handle_irq
lda use_interrupts
beq irts
cmp #1
beq irq_on
cmp #3
bne irq_err
lda #$80
sta always_handle_irq
irq_on:
2017-09-17 18:18:47 +00:00
lda #$80
sta use_interrupts
irts: rts
2017-09-17 18:18:47 +00:00
irq_err:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::invalid_irq_setting
.endproc
2017-09-17 18:18:47 +00:00
.proc set_op_sys
lda op_sys
beq is_prodos
cmp #1
beq is_pascal
2017-09-17 18:18:47 +00:00
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::invalid_op_sys
is_prodos:
lda #$80
sta op_sys
is_pascal:
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; StopDeskTop
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc StopDeskTopImpl
ldy #SETMOUSE
lda #MOUSE_MODE_OFF
2017-10-07 22:07:12 +00:00
jsr call_mouse
ldy #SERVEMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
bit use_interrupts
2017-10-15 05:09:00 +00:00
bpl :+
bit op_sys
2017-10-15 05:09:00 +00:00
bpl :+
lda alloc_interrupt_params::int_num
sta dealloc_interrupt_params::int_num
2017-10-01 23:17:04 +00:00
MLI_CALL DEALLOC_INTERRUPT, dealloc_interrupt_params
:
lda save_p_reg
2017-09-17 18:18:47 +00:00
pha
plp
lda #0
2018-02-18 19:33:21 +00:00
sta desktop_initialized_flag
2017-09-17 18:18:47 +00:00
rts
2017-10-15 05:09:00 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-02-18 19:33:21 +00:00
;;; SetUserHook
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $82
.proc SetUserHookImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
hook_id: .res 1
routine_ptr: .res 2
END_PARAM_BLOCK
lda params::hook_id
cmp #1
bne :+
2018-04-28 23:22:33 +00:00
lda params::routine_ptr+1
bne clear_before_events_hook
sta before_events_hook+1
2018-04-28 23:22:33 +00:00
lda params::routine_ptr
sta before_events_hook
2017-09-17 18:18:47 +00:00
rts
: cmp #2
bne invalid_hook
2018-04-28 23:22:33 +00:00
lda params::routine_ptr+1
bne clear_after_events_hook
sta after_events_hook+1
2018-04-28 23:22:33 +00:00
lda params::routine_ptr
sta after_events_hook
2017-09-17 18:18:47 +00:00
rts
clear_before_events_hook:
lda #0
sta before_events_hook
sta before_events_hook+1
2017-09-17 18:18:47 +00:00
rts
clear_after_events_hook:
lda #0
sta after_events_hook
sta after_events_hook+1
2017-09-17 18:18:47 +00:00
rts
invalid_hook:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::invalid_hook
.endproc
2017-09-17 18:18:47 +00:00
.proc call_before_events_hook
lda before_events_hook+1
beq :+
jsr save_params_and_stack
jsr before_events_hook_jmp
2017-09-17 18:18:47 +00:00
php
jsr restore_params_active_port
2017-09-17 18:18:47 +00:00
plp
: rts
before_events_hook_jmp:
jmp (before_events_hook)
.endproc
2017-09-17 18:18:47 +00:00
before_events_hook:
.res 2
2017-09-30 02:14:47 +00:00
.proc call_after_events_hook
lda after_events_hook+1
beq :+
jsr save_params_and_stack
jsr after_events_hook_jmp
2017-09-17 18:18:47 +00:00
php
jsr restore_params_active_port
2017-09-17 18:18:47 +00:00
plp
: rts
2017-09-17 18:18:47 +00:00
after_events_hook_jmp:
jmp (after_events_hook)
.endproc
after_events_hook:
.res 2
params_addr_save:
.res 2
stack_ptr_save:
.res 1
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc hide_cursor_save_params
jsr HideCursorImpl
;; Fall-through
2018-04-02 15:00:43 +00:00
.endproc
.proc save_params_and_stack
copy16 params_addr, params_addr_save
2017-10-06 04:18:28 +00:00
lda stack_ptr_stash
sta stack_ptr_save
2017-10-06 04:18:28 +00:00
lsr preserve_zp_flag
2017-09-30 02:14:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc show_cursor_and_restore
jsr ShowCursorImpl
;; Fall-through
2018-04-02 15:00:43 +00:00
.endproc
.proc restore_params_active_port
asl preserve_zp_flag
copy16 params_addr_save, params_addr
ldax active_port
;; Fall-through
.endproc
.proc set_and_prepare_port
stax $82
lda stack_ptr_save
2017-10-06 04:18:28 +00:00
sta stack_ptr_stash
2018-05-26 01:39:43 +00:00
ldy #.sizeof(MGTK::GrafPort)-1
: lda ($82),y
2018-01-29 16:25:56 +00:00
sta current_grafport,y
2017-09-17 18:18:47 +00:00
dey
bpl :-
2018-01-29 16:25:56 +00:00
jmp prepare_port
.endproc
2017-09-17 18:18:47 +00:00
2017-09-30 02:14:47 +00:00
.proc set_standard_port
ldax standard_port_addr
bne set_and_prepare_port ; always
.endproc
standard_port_addr:
.addr standard_port
.proc set_desktop_port
jsr set_standard_port
MGTK_CALL MGTK::SetPortBits, desktop_port_bits
2017-09-17 18:18:47 +00:00
rts
desktop_port_bits:
.word 0 ; viewloc x
port_y:
.word 13 ; viewloc y = font height + 4
.word $2000 ; mapbits
.byte $80 ; mapwidth
.res 1 ; reserved
.endproc
desktop_port_y := set_desktop_port::port_y
2017-10-01 23:17:04 +00:00
.proc fill_rect_params
left: .word 0
top: .word 0
2018-03-02 02:25:42 +00:00
right: .word screen_width-1
bottom: .word screen_height-1
.endproc
2018-02-28 02:38:18 +00:00
fill_rect_top := fill_rect_params::top
2017-09-30 02:14:47 +00:00
.byte $00,$00,$00,$00,$00,$00,$00,$00
2017-10-01 23:17:04 +00:00
checkerboard_pattern:
.byte %01010101
.byte %10101010
.byte %01010101
.byte %10101010
.byte %01010101
.byte %10101010
.byte %01010101
.byte %10101010
.byte $00
2017-10-01 23:17:04 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-02-18 19:33:21 +00:00
;;; AttachDriver
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $82
2018-02-18 19:33:21 +00:00
.proc AttachDriverImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
hook: .res 2
mouse_state: .res 2
END_PARAM_BLOCK
2018-02-18 19:33:21 +00:00
bit desktop_initialized_flag
bmi fail
2018-04-28 23:22:33 +00:00
copy16 params::hook, mouse_hook
ldax mouse_state_addr
ldy #2
2018-02-28 02:38:18 +00:00
jmp store_xa_at_y
2017-09-17 18:18:47 +00:00
2018-11-18 04:34:17 +00:00
fail: exit_call MGTK::Error::desktop_already_initialized
2017-09-17 18:18:47 +00:00
mouse_state_addr:
.addr mouse_state
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; PeekEvent
2017-10-04 15:31:53 +00:00
.proc PeekEventImpl
2017-10-03 02:48:21 +00:00
clc
bcc GetEventImpl_peek_entry
.endproc
2017-10-03 03:05:07 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetEvent
2017-10-03 03:05:07 +00:00
.proc GetEventImpl
2017-10-03 02:48:21 +00:00
sec
peek_entry:
php
bit use_interrupts
bpl :+
2017-09-17 18:18:47 +00:00
sei
bmi no_check
: jsr CheckEventsImpl
no_check:
jsr next_event
bcs no_event
2017-09-17 18:18:47 +00:00
plp
php
bcc :+ ; skip advancing tail mark if in peek mode
sta eventbuf_tail
: tax
2017-10-06 16:09:43 +00:00
ldy #0 ; Store 5 bytes at params
: lda eventbuf,x
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
inx
iny
2017-10-06 16:09:43 +00:00
cpy #4
bne :-
lda #0
2017-10-07 20:59:25 +00:00
sta (params_addr),y
beq ret
no_event:
jsr return_move_event
ret: plp
bit use_interrupts
bpl :+
2017-09-17 18:18:47 +00:00
cli
: rts
.endproc
GetEventImpl_peek_entry := GetEventImpl::peek_entry
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 5 bytes of params, copied to $82
.proc PostEventImpl
PARAM_BLOCK params, $82
kind: .byte 0
xcoord: .word 0 ; also used for key/modifiers/window id
ycoord: .word 0
END_PARAM_BLOCK
2017-09-17 18:18:47 +00:00
php
sei
lda params::kind
bmi event_ok
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::update
bcs bad_event
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::key_down
beq event_ok
ldx params::xcoord
ldy params::xcoord+1
lda params::ycoord
2018-03-24 02:43:22 +00:00
jsr set_mouse_pos
event_ok:
jsr put_event
bcs no_room
2017-09-17 18:18:47 +00:00
tax
ldy #0
: lda (params_addr),y
sta eventbuf,x
2017-09-17 18:18:47 +00:00
inx
iny
cpy #MGTK::short_event_size
bne :-
2017-09-17 18:18:47 +00:00
plp
rts
bad_event:
2018-11-18 04:34:17 +00:00
lda #MGTK::Error::invalid_event
bmi error_return
no_room:
2018-11-18 04:34:17 +00:00
lda #MGTK::Error::event_queue_full
error_return:
plp
2018-01-29 08:57:55 +00:00
jmp exit_with_a
.endproc
;; Return a no_event (if mouse up) or drag event (if mouse down)
;; and report the current mouse position.
.proc return_move_event
2018-11-18 04:34:17 +00:00
lda #MGTK::EventKind::no_event
2017-09-17 18:18:47 +00:00
bit mouse_status
bpl :+
2018-11-18 04:34:17 +00:00
lda #MGTK::EventKind::drag
: ldy #0
sta (params_addr),y ; Store 5 bytes at params
2017-09-17 18:18:47 +00:00
iny
: lda set_pos_params-1,y
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
iny
cpy #MGTK::event_size
bne :-
2017-09-30 02:14:47 +00:00
rts
.endproc
2017-09-30 02:14:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; CheckEvents
2017-10-07 03:59:09 +00:00
.proc input
state: .byte 0
key := *
kmods := * + 1
xpos := *
ypos := * + 2
modifiers := * + 3
.res 4, 0
.endproc
2018-01-29 08:57:55 +00:00
.proc CheckEventsImpl
bit use_interrupts
bpl irq_entry
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::irq_in_use
2017-09-17 18:18:47 +00:00
irq_entry:
sec ; called from interrupt handler
jsr call_before_events_hook
bcc end
lda BUTN1 ; Look at buttons (apple keys), compute modifiers
2017-09-30 02:14:47 +00:00
asl a
lda BUTN0
2017-09-17 18:18:47 +00:00
and #$80
rol a
rol a
sta input::modifiers
jsr activate_keyboard_mouse ; check if keyboard mouse should be started
jsr move_cursor
lda mouse_status ; bit 7 = is down, bit 6 = was down, still down
2017-09-17 18:18:47 +00:00
asl a
eor mouse_status
bmi :+ ; minus = (is down & !was down)
bit mouse_status
bmi end ; minus = is down
2017-10-16 03:28:50 +00:00
bit check_kbd_flag
bpl :+
2018-03-24 02:43:22 +00:00
lda kbd_mouse_state
bne :+
lda KBD
bpl end ; no key
and #CHAR_MASK
sta input::key
bit KBDSTRB ; clear strobe
lda input::modifiers
sta input::kmods
2018-11-18 04:34:17 +00:00
lda #MGTK::EventKind::key_down
sta input::state
bne put_key_event ; always
: bcc up
lda input::modifiers
beq :+
2018-11-18 04:34:17 +00:00
lda #MGTK::EventKind::apple_key
bne set_state
2018-11-18 04:34:17 +00:00
: lda #MGTK::EventKind::button_down
bne set_state
2018-11-18 04:34:17 +00:00
up: lda #MGTK::EventKind::button_up
set_state:
sta input::state
COPY_BYTES 3, set_pos_params, input::key
put_key_event:
jsr put_event
2017-09-17 18:18:47 +00:00
tax
ldy #0
: lda input,y
sta eventbuf,x
2017-09-17 18:18:47 +00:00
inx
iny
cpy #MGTK::short_event_size
bne :-
2017-09-17 18:18:47 +00:00
end: jmp call_after_events_hook
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
;;; Interrupt Handler
int_stash_zp:
.res 9, 0
int_stash_rdpage2:
2017-10-01 23:17:04 +00:00
.byte 0
int_stash_rd80store:
2017-10-01 23:17:04 +00:00
.byte 0
.proc interrupt_handler
cld ; required for interrupt handlers
2018-01-29 08:57:55 +00:00
body: ; returned by GetIntHandler
2017-10-16 03:20:54 +00:00
lda RDPAGE2 ; record softswitch state
sta int_stash_rdpage2
lda RD80STORE
sta int_stash_rd80store
lda LOWSCR
sta SET80COL
COPY_BYTES 9, $82, int_stash_zp ; preserve 9 bytes of ZP
ldy #SERVEMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
bcs :+
jsr CheckEventsImpl::irq_entry
2017-09-17 18:18:47 +00:00
clc
: bit always_handle_irq
bpl :+
clc ; carry clear if interrupt handled
: COPY_BYTES 9, int_stash_zp, $82 ; restore ZP
lda LOWSCR ; restore soft switches
sta CLR80COL
lda int_stash_rdpage2
bpl :+
lda HISCR
: lda int_stash_rd80store
bpl :+
sta SET80COL
: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetIntHandler
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc GetIntHandlerImpl
ldax int_handler_addr
jmp store_xa_at_params
2017-09-17 18:18:47 +00:00
int_handler_addr:
.addr interrupt_handler::body
2017-10-16 03:20:54 +00:00
.endproc
2017-10-06 00:04:39 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; FlushEvents
2017-10-15 02:45:51 +00:00
;;; This is called during init by the DAs, just before
;;; entering the input loop.
eventbuf_tail: .byte 0
eventbuf_head: .byte 0
eventbuf_size := 33 ; max # of events in queue
eventbuf:
.scope eventbuf
kind := *
key := *+1
modifiers := *+2
window_id := *+1
.endscope
.res eventbuf_size*MGTK::short_event_size
2017-10-03 02:48:21 +00:00
2018-01-29 08:57:55 +00:00
.proc FlushEventsImpl
php
2017-09-17 18:18:47 +00:00
sei
lda #0
sta eventbuf_tail
sta eventbuf_head
2017-09-17 18:18:47 +00:00
plp
rts
.endproc
2018-01-29 08:57:55 +00:00
;; called during PostEvent and a few other places
.proc put_event
lda eventbuf_head
cmp #(eventbuf_size-1)*MGTK::short_event_size
bne :+ ; if head is not at end, advance
lda #0 ; otherwise reset to 0
bcs compare
: clc
adc #MGTK::short_event_size
compare:
cmp eventbuf_tail ; did head catch up with tail?
beq rts_with_carry_set
sta eventbuf_head ; nope, maybe next time
2017-09-17 18:18:47 +00:00
clc
rts
.endproc
2017-09-17 18:18:47 +00:00
rts_with_carry_set:
sec
2017-09-17 18:18:47 +00:00
rts
2018-01-29 08:57:55 +00:00
;; called during GetEvent
.proc next_event
lda eventbuf_tail ; equal?
cmp eventbuf_head
beq rts_with_carry_set
2017-10-06 00:04:39 +00:00
cmp #$80
bne :+
2017-10-06 00:04:39 +00:00
lda #0
bcs ret ; always
: clc
adc #MGTK::short_event_size
ret: clc
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetKeyEvent
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
2017-10-16 03:28:50 +00:00
check_kbd_flag: .byte $80
2018-01-29 08:57:55 +00:00
.proc SetKeyEventImpl
2018-04-29 20:21:52 +00:00
PARAM_BLOCK params, $82
handle_keys: .res 1
END_PARAM_BLOCK
2017-10-16 03:28:50 +00:00
asl check_kbd_flag
2018-04-29 20:21:52 +00:00
ror params::handle_keys
2017-10-16 03:28:50 +00:00
ror check_kbd_flag
2017-09-17 18:18:47 +00:00
rts
2017-10-16 03:28:50 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-16 03:28:50 +00:00
2018-04-02 15:00:43 +00:00
;;; Menu drawing metrics
offset_checkmark: .byte 2
offset_text: .byte 9
offset_shortcut: .byte 16
shortcut_x_adj: .byte 9
non_shortcut_x_adj: .byte 30
sysfont_height: .byte 0
2017-09-17 18:18:47 +00:00
2017-10-15 02:45:51 +00:00
active_menu:
.addr 0
2018-01-29 16:25:56 +00:00
.proc test_rect_params
left: .word $ffff
top: .word $ffff
right: .word $230
bottom: .word $C
.endproc
2018-02-28 02:38:18 +00:00
test_rect_top := test_rect_params::top
test_rect_bottom := test_rect_params::bottom
.proc fill_rect_params2
left: .word 0
top: .word 0
width: .word 0
height: .word 11
.endproc
2017-10-03 03:46:01 +00:00
fill_rect_params2_height := fill_rect_params2::height
savebehind_buffer:
.word 0
2018-01-29 16:25:56 +00:00
.proc test_rect_params2
left: .word 0
top: .word 12
right: .word 0
bottom: .word 0
.endproc
2018-01-29 16:25:56 +00:00
test_rect_params2_top := test_rect_params2::top
.proc fill_rect_params4
left: .word 0
top: .word 12
right: .word 0
bottom: .word 0
.endproc
2017-10-03 03:46:01 +00:00
fill_rect_params4_top := fill_rect_params4::top
2017-12-16 05:36:09 +00:00
menu_item_y_table:
.repeat 15, i
.byte 12 + 12 * i
.endrepeat
menu_item_y_table_end:
2018-04-28 23:22:33 +00:00
menu_glyphs:
solid_apple_glyph:
.byte $1E
open_apple_glyph:
.byte $1F
checkmark_glyph:
.byte $1D
controlkey_glyph:
2018-04-02 15:00:43 +00:00
.byte $01
shortcut_text:
.byte 2 ; length
.byte $1E
.byte $FF
mark_text:
.byte 1 ; length
.byte $1D
test_rect_params_addr:
.addr test_rect_params
test_rect_params2_addr:
.addr test_rect_params2
mark_text_addr:
.addr mark_text
shortcut_text_addr:
.addr shortcut_text
menu_index := $A7
menu_count := $A8
menu_item_index := $A9
menu_item_count := $AA
menu_ptr := $AB
menu_item_ptr := $AD
PARAM_BLOCK curmenu, $AF
;; Public members
menu_id: .byte 0
disabled: .byte 0
title: .addr 0
menu_items: .addr 0
;; Reserved area in menu
x_penloc: .word 0
x_min: .word 0
x_max: .word 0
END_PARAM_BLOCK
PARAM_BLOCK curmenuinfo, $BB
;; Reserved area before first menu item
x_min: .word 0
x_max: .word 0
END_PARAM_BLOCK
PARAM_BLOCK curmenuitem, $BF
;; Public members
options: .byte 0
mark_char: .byte 0
shortcut1: .byte 0
shortcut2: .byte 0
name: .addr 0
END_PARAM_BLOCK
2017-10-16 03:38:58 +00:00
2018-04-02 15:00:43 +00:00
.proc get_menu_count
2018-03-26 03:18:43 +00:00
copy16 active_menu, $82
2017-10-15 02:45:51 +00:00
ldy #0
2017-10-07 20:59:25 +00:00
lda ($82),y
2018-04-02 15:00:43 +00:00
sta menu_count
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc get_menu
stx menu_index
lda #2
2017-09-17 18:18:47 +00:00
clc
2018-04-02 15:00:43 +00:00
: dex
bmi :+
adc #12
bne :-
: adc active_menu
sta menu_ptr
2017-10-15 02:45:51 +00:00
lda active_menu+1
2018-04-02 15:00:43 +00:00
adc #0
sta menu_ptr+1
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuBarItem)-1
2018-04-02 15:00:43 +00:00
: lda (menu_ptr),y
sta curmenu,y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuItem)-1
2018-04-02 15:00:43 +00:00
: lda (curmenu::menu_items),y
sta curmenuinfo-1,y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bne :-
lda (curmenu::menu_items),y
sta menu_item_count
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc put_menu
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuBarItem)-1
2018-04-02 15:00:43 +00:00
: lda curmenu,y
sta (menu_ptr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuItem)-1
2018-04-02 15:00:43 +00:00
: lda curmenuinfo-1,y
sta (curmenu::menu_items),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bne :-
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc get_menu_item
stx menu_item_index
2018-05-26 07:35:28 +00:00
lda #.sizeof(MGTK::MenuItem)
2017-09-17 18:18:47 +00:00
clc
2018-04-02 15:00:43 +00:00
: dex
bmi :+
2018-05-26 07:35:28 +00:00
adc #.sizeof(MGTK::MenuItem)
2018-04-02 15:00:43 +00:00
bne :-
:
adc curmenu::menu_items
sta menu_item_ptr
lda curmenu::menu_items+1
adc #0
sta menu_item_ptr+1
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuItem)-1
2018-04-02 15:00:43 +00:00
: lda (menu_item_ptr),y
sta curmenuitem,y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc put_menu_item
2018-05-26 07:35:28 +00:00
ldy #.sizeof(MGTK::MenuItem)-1
2018-04-02 15:00:43 +00:00
: lda curmenuitem,y
sta (menu_item_ptr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
;; Set penloc to X=AX, Y=Y
.proc set_penloc
sty current_penloc_y
ldy #0
2018-01-29 16:25:56 +00:00
sty current_penloc_y+1
set_x: stax current_penloc_x
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2017-10-15 02:45:51 +00:00
;; Set fill mode to A
2018-04-02 15:00:43 +00:00
.proc set_fill_mode
2018-01-29 16:25:56 +00:00
sta current_penmode
2018-01-29 08:57:55 +00:00
jmp SetPenModeImpl
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc do_measure_text
jsr prepare_text_params
jmp measure_text
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc draw_text
jsr prepare_text_params
2018-01-29 08:57:55 +00:00
jmp DrawTextImpl
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-01-29 08:57:55 +00:00
;; Prepare $A1,$A2 as params for TextWidth/DrawText call
;; ($A3 is length)
2018-04-02 15:00:43 +00:00
.proc prepare_text_params
temp_ptr := $82
stax temp_ptr
2017-09-17 18:18:47 +00:00
clc
adc #1
2018-04-02 15:00:43 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
: stax measure_text::data
ldy #0
2018-04-02 15:00:43 +00:00
lda (temp_ptr),y
sta measure_text::length
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
.proc get_and_return_event
PARAM_BLOCK event, $82
kind: .byte 0
mouse_pos:
mouse_x: .word 0
2018-04-04 04:26:13 +00:00
mouse_y: .word 0
2018-04-02 15:00:43 +00:00
END_PARAM_BLOCK
MGTK_CALL MGTK::GetEvent, event
return event
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetMenu
2017-10-07 03:59:09 +00:00
2018-04-02 15:00:43 +00:00
need_savebehind:
.res 2
2017-10-15 02:45:51 +00:00
2018-04-02 15:00:43 +00:00
.proc SetMenuImpl
temp := $82
max_width := $C5
lda #0
sta savebehind_usage
sta savebehind_usage+1
2018-03-26 03:18:43 +00:00
copy16 params_addr, active_menu
2017-10-15 02:45:51 +00:00
2018-04-02 15:00:43 +00:00
jsr get_menu_count ; into menu_count
jsr hide_cursor_save_params
jsr set_standard_port
2018-04-02 15:00:43 +00:00
ldax test_rect_params_addr
2017-10-15 02:45:51 +00:00
jsr fill_and_frame_rect
2018-04-02 15:00:43 +00:00
ldax #12
ldy sysfont_height
2017-09-17 18:18:47 +00:00
iny
jsr set_penloc
2018-04-02 15:00:43 +00:00
ldx #0
menuloop:
jsr get_menu
ldax current_penloc_x
2018-04-02 15:00:43 +00:00
stax curmenu::x_penloc
2017-09-30 02:14:47 +00:00
sec
2018-04-02 15:00:43 +00:00
sbc #8
bcs :+
2017-09-30 02:14:47 +00:00
dex
2018-04-02 15:00:43 +00:00
: stax curmenu::x_min
stax curmenuinfo::x_min
ldx #0
stx max_width
stx max_width+1
itemloop:
jsr get_menu_item
bit curmenuitem::options
bvs filler ; bit 6 - is filler
ldax curmenuitem::name
jsr do_measure_text
2018-04-02 15:00:43 +00:00
stax temp
lda curmenuitem::options
and #3 ; OA+SA
bne :+
lda curmenuitem::shortcut1
bne :+
lda shortcut_x_adj
bne has_shortcut
: lda non_shortcut_x_adj
has_shortcut:
clc
adc temp
sta temp
bcc :+
inc temp+1
:
sec
sbc max_width
lda temp+1
sbc max_width+1
bmi :+
copy16 temp, max_width ; calculate max width
:
filler: ldx menu_item_index
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx menu_item_count
bne itemloop
lda menu_item_count
2017-09-17 18:18:47 +00:00
tax
ldy sysfont_height
2017-09-17 18:18:47 +00:00
iny
iny
iny
2018-04-02 15:00:43 +00:00
jsr mult_x_y ; num items * (sysfont_height+3)
2017-09-17 18:18:47 +00:00
pha
2018-04-02 15:00:43 +00:00
copy16 max_width, fixed_div::dividend
copy16 #7, fixed_div::divisor
2018-04-02 15:00:43 +00:00
jsr fixed_div ; max width / 7
2018-04-02 15:00:43 +00:00
ldy fixed_div::quotient+2
2017-09-17 18:18:47 +00:00
iny
iny
pla
tax
2018-04-02 15:00:43 +00:00
jsr mult_x_y ; total height * ((max width / 7)+2)
sta need_savebehind
sty need_savebehind+1
2017-09-17 18:18:47 +00:00
sec
sbc savebehind_usage
2017-09-17 18:18:47 +00:00
tya
sbc savebehind_usage+1
2018-04-02 15:00:43 +00:00
bmi :+
copy16 need_savebehind, savebehind_usage ; calculate max savebehind data needed
: add16_8 curmenuinfo::x_min, max_width, curmenuinfo::x_max
2018-04-02 15:00:43 +00:00
jsr put_menu
2018-04-02 15:00:43 +00:00
ldax curmenu::title
jsr draw_text
2018-04-02 15:00:43 +00:00
jsr get_menu_and_menu_item
ldax current_penloc_x
2017-09-17 18:18:47 +00:00
clc
2018-04-02 15:00:43 +00:00
adc #8
bcc :+
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
: stax curmenu::x_max
jsr put_menu
ldax #12
2017-10-08 15:42:27 +00:00
jsr adjust_xpos
2018-04-02 15:00:43 +00:00
ldx menu_index
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx menu_count
beq :+
jmp menuloop
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
: lda #0
sta sel_menu_index
sta sel_menu_item_index
2018-04-02 15:00:43 +00:00
jsr show_cursor_and_restore
2017-09-17 18:18:47 +00:00
sec
lda savebehind_size
sbc savebehind_usage
lda savebehind_size+1
sbc savebehind_usage+1
2018-04-02 15:00:43 +00:00
bpl :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::insufficient_savebehind_area
2018-04-02 15:00:43 +00:00
: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc get_menu_and_menu_item
ldx menu_index
jsr get_menu
ldx menu_item_index
jmp get_menu_item
.endproc
2017-09-17 18:18:47 +00:00
2017-10-15 02:45:51 +00:00
;; Fills rect (params at X,A) then inverts border
.proc fill_and_frame_rect
stax fill_params
stax draw_params
2018-04-02 15:00:43 +00:00
lda #MGTK::pencopy
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::PaintRect, 0, fill_params
2018-04-02 15:00:43 +00:00
lda #MGTK::notpencopy
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::FrameRect, 0, draw_params
2017-09-17 18:18:47 +00:00
rts
2017-10-15 02:45:51 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc find_menu_by_id_or_fail
jsr find_menu_by_id
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::menu_not_found
2018-04-02 15:00:43 +00:00
: rts
.endproc
find_mode := $C6
find_mode_by_id := $00 ; find menu/menu item by id
find_menu_id := $C7
find_menu_item_id := $C8
find_mode_by_coord := $80 ; find menu by x-coord/menu item by y-coord
; coordinate is in set_pos_params
find_mode_by_shortcut := $C0 ; find menu and menu item by shortcut key
find_shortcut := $C9
find_options := $CA
.proc find_menu_by_id
lda #find_mode_by_id
find_menu:
sta find_mode
2017-09-17 18:18:47 +00:00
2017-10-15 02:45:51 +00:00
jsr get_menu_count
2018-04-02 15:00:43 +00:00
ldx #0
loop: jsr get_menu
bit find_mode
bvs find_menu_item_mode
bmi :+
lda curmenu::menu_id ; search by menu id
cmp find_menu_id
bne next
beq found
: ldax set_pos_params::xcoord ; search by x coordinate bounds
cpx curmenu::x_min+1
bcc next
bne :+
cmp curmenu::x_min
bcc next
: cpx curmenu::x_max+1
bcc found
bne next
cmp curmenu::x_max
bcc found
bcs next
find_menu_item_mode:
jsr find_menu_item
bne found
next: ldx menu_index
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx menu_count
bne loop
return #0
found: return curmenu::menu_id
.endproc
find_menu := find_menu_by_id::find_menu
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc find_menu_item
ldx #0
loop: jsr get_menu_item
ldx menu_item_index
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
bit find_mode
bvs find_by_shortcut
bmi :+
cpx find_menu_item_id
bne next
beq found
: lda menu_item_y_table,x
cmp set_pos_params::ycoord
2018-04-02 15:00:43 +00:00
bcs found
bcc next
find_by_shortcut:
lda find_shortcut
and #CHAR_MASK
2018-04-02 15:00:43 +00:00
cmp curmenuitem::shortcut1
beq :+
cmp curmenuitem::shortcut2
bne next
: cmp #$20 ; is control char
bcc found
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
2018-04-02 15:00:43 +00:00
bne next
lda curmenuitem::options
and find_options
bne found
next: cpx menu_item_count
bne loop
ldx #0
found: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; HiliteMenu
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc HiliteMenuImpl
menu_param := $C7
lda menu_param
bne :+
lda cur_open_menu
sta menu_param
: jsr find_menu_by_id_or_fail
do_hilite:
jsr hide_cursor_save_params
jsr set_standard_port
2018-04-02 15:00:43 +00:00
jsr hilite_menu
jmp show_cursor_and_restore
.endproc
2017-09-17 18:18:47 +00:00
2017-10-14 19:51:25 +00:00
;; Highlight/Unhighlight top level menu item
2018-04-02 15:00:43 +00:00
.proc hilite_menu
ldx #1
loop: lda curmenu::x_min,x
sta fill_rect_params2::left,x
2018-04-02 15:00:43 +00:00
lda curmenu::x_max,x
sta fill_rect_params2::width,x
2018-04-02 15:00:43 +00:00
lda curmenuinfo::x_min,x
2018-01-29 16:25:56 +00:00
sta test_rect_params2::left,x
sta fill_rect_params4::left,x
2018-04-02 15:00:43 +00:00
lda curmenuinfo::x_max,x
2018-01-29 16:25:56 +00:00
sta test_rect_params2::right,x
sta fill_rect_params4::right,x
2018-04-02 15:00:43 +00:00
2017-09-17 18:18:47 +00:00
dex
2017-10-14 19:51:25 +00:00
bpl loop
2018-04-02 15:00:43 +00:00
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::PaintRect, fill_rect_params2
2017-09-17 18:18:47 +00:00
rts
2017-10-14 19:51:25 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; MenuKey
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc MenuKeyImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
menu_item: .byte 0
which_key: .byte 0
key_mods: .byte 0
END_PARAM_BLOCK
lda params::which_key
2018-04-29 20:21:52 +00:00
cmp #CHAR_ESCAPE
2018-04-02 15:00:43 +00:00
bne :+
lda params::key_mods
bne :+
2018-01-29 08:57:55 +00:00
jsr KeyboardMouse
jmp MenuSelectImpl
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
: lda #find_mode_by_shortcut
jsr find_menu
beq not_found
lda curmenu::disabled
bmi not_found
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
2018-04-02 15:00:43 +00:00
bne not_found
lda curmenu::menu_id
sta cur_open_menu
bne found
not_found:
lda #0
2017-09-17 18:18:47 +00:00
tax
2018-04-02 15:00:43 +00:00
found: ldy #0
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
iny
txa
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2018-04-02 15:00:43 +00:00
bne HiliteMenuImpl::do_hilite
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc find_menu_and_menu_item
jsr find_menu_by_id_or_fail
jsr find_menu_item
cpx #0
.endproc
rrts: rts
.proc find_menu_item_or_fail
jsr find_menu_and_menu_item
bne rrts
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::menu_item_not_found
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; DisableItem
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc DisableItemImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
menu_item: .byte 0
disable: .byte 0
END_PARAM_BLOCK
jsr find_menu_item_or_fail
asl curmenuitem::options
ror params::disable
ror curmenuitem::options
jmp put_menu_item
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; CheckItem
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc CheckItemImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
menu_item: .byte 0
check: .byte 0
END_PARAM_BLOCK
jsr find_menu_item_or_fail
lda params::check
beq :+
2018-11-18 04:34:17 +00:00
lda #MGTK::MenuOpt::item_is_checked
2018-04-02 15:00:43 +00:00
ora curmenuitem::options
bne set_options ; always
2018-11-18 04:34:17 +00:00
: lda #$FF^MGTK::MenuOpt::item_is_checked
2018-04-02 15:00:43 +00:00
and curmenuitem::options
set_options:
sta curmenuitem::options
jmp put_menu_item
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; DisableMenu
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc DisableMenuImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
disable: .byte 0
END_PARAM_BLOCK
jsr find_menu_by_id_or_fail
asl curmenu::disabled
ror params::disable
ror curmenu::disabled
ldx menu_index
jmp put_menu
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; MenuSelect
2017-10-07 03:59:09 +00:00
2018-04-02 15:00:43 +00:00
cur_open_menu:
.byte 0
cur_hilited_menu_item:
.byte 0
was_in_menu_flag:
.byte 0
2018-04-02 15:00:43 +00:00
.proc MenuSelectImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
menu_item: .byte 0
END_PARAM_BLOCK
2017-10-15 02:45:51 +00:00
jsr kbd_mouse_init_tracking
2018-04-02 15:00:43 +00:00
2017-10-15 02:45:51 +00:00
jsr get_menu_count
jsr save_params_and_stack
jsr set_standard_port
2018-03-24 02:43:22 +00:00
bit kbd_mouse_state
2018-04-02 15:00:43 +00:00
bpl :+
jsr kbd_menu_select
2018-04-02 15:00:43 +00:00
jmp in_menu
: lda #0
sta cur_open_menu
sta cur_hilited_menu_item
sta was_in_menu_flag
2018-04-02 15:00:43 +00:00
jsr get_and_return_event
event_loop:
bit movement_cancel
2018-04-02 15:00:43 +00:00
bpl :+
jmp kbd_menu_return
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
: MGTK_CALL MGTK::MoveTo, get_and_return_event::event::mouse_pos
MGTK_CALL MGTK::InRect, test_rect_params ; test in menu bar
bne in_menu_bar
lda cur_open_menu
beq in_menu
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
MGTK_CALL MGTK::InRect, test_rect_params2 ; test in menu
bne in_menu_item
jsr unhilite_cur_menu_item
in_menu:jsr get_and_return_event
cmp #MGTK::EventKind::button_down
2018-04-02 15:00:43 +00:00
beq :+
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::button_up
2018-04-02 15:00:43 +00:00
bne event_loop
bit was_in_menu_flag
bmi :+
lda cur_open_menu
bne event_loop
2018-04-02 15:00:43 +00:00
: lda cur_hilited_menu_item
bne :+
jsr hide_menu
jmp restore
: jsr HideCursorImpl
jsr set_standard_port
2018-04-02 15:00:43 +00:00
jsr restore_menu_savebehind
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
restore:jsr restore_params_active_port
lda #0
ldx cur_hilited_menu_item
beq :+
lda cur_open_menu
ldy menu_index ; ???
sty sel_menu_index
stx sel_menu_item_index
: jmp store_xa_at_params
in_menu_bar:
jsr unhilite_cur_menu_item
lda #find_mode_by_coord
jsr find_menu
cmp cur_open_menu
beq in_menu
2017-09-17 18:18:47 +00:00
pha
2018-04-02 15:00:43 +00:00
jsr hide_menu
2017-09-17 18:18:47 +00:00
pla
2018-04-02 15:00:43 +00:00
sta cur_open_menu
jsr draw_menu
jmp in_menu
in_menu_item:
lda #find_mode_by_coord
sta was_in_menu_flag
2018-04-02 15:00:43 +00:00
sta find_mode
jsr find_menu_item
cpx cur_hilited_menu_item
beq in_menu
lda curmenu::disabled
ora curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
2018-04-02 15:00:43 +00:00
beq :+
ldx #0
: txa
2017-09-17 18:18:47 +00:00
pha
2018-04-02 15:00:43 +00:00
jsr hilite_menu_item
2017-09-17 18:18:47 +00:00
pla
2018-04-02 15:00:43 +00:00
sta cur_hilited_menu_item
jsr hilite_menu_item
jmp in_menu
.endproc
savebehind_left_bytes := $82
savebehind_bottom := $83
savebehind_buf_addr := $8E
savebehind_vid_addr := $84
savebehind_mapwidth := $90
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc set_up_savebehind
lda curmenuinfo::x_min+1
2017-09-17 18:18:47 +00:00
lsr a
2018-04-02 15:00:43 +00:00
lda curmenuinfo::x_min
2017-09-17 18:18:47 +00:00
ror a
tax
lda div7_table,x
2018-04-02 15:00:43 +00:00
sta savebehind_left_bytes
lda curmenuinfo::x_max+1
2017-09-17 18:18:47 +00:00
lsr a
2018-04-02 15:00:43 +00:00
lda curmenuinfo::x_max
2017-09-17 18:18:47 +00:00
ror a
tax
lda div7_table,x
2017-09-17 18:18:47 +00:00
sec
2018-04-02 15:00:43 +00:00
sbc savebehind_left_bytes
sta savebehind_mapwidth
copy16 savebehind_buffer, savebehind_buf_addr
ldy menu_item_count
2017-12-16 05:36:09 +00:00
ldx menu_item_y_table,y ; ???
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
stx savebehind_bottom
stx fill_rect_params4::bottom
2018-01-29 16:25:56 +00:00
stx test_rect_params2::bottom
2018-04-02 15:00:43 +00:00
ldx sysfont_height
2017-09-17 18:18:47 +00:00
inx
inx
inx
stx fill_rect_params4::top
2018-01-29 16:25:56 +00:00
stx test_rect_params2::top
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc savebehind_get_vidaddr
lda hires_table_lo,x
2017-09-17 18:18:47 +00:00
clc
2018-04-02 15:00:43 +00:00
adc savebehind_left_bytes
sta savebehind_vid_addr
2017-09-30 22:32:38 +00:00
lda hires_table_hi,x
2017-09-17 18:18:47 +00:00
ora #$20
2018-04-02 15:00:43 +00:00
sta savebehind_vid_addr+1
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc savebehind_next_line
lda savebehind_buf_addr
2017-09-17 18:18:47 +00:00
sec
2018-04-02 15:00:43 +00:00
adc savebehind_mapwidth
sta savebehind_buf_addr
bcc :+
inc savebehind_buf_addr+1
: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc restore_menu_savebehind
jsr set_up_savebehind
loop: jsr savebehind_get_vidaddr
sta HISCR
2018-04-02 15:00:43 +00:00
ldy savebehind_mapwidth
: lda (savebehind_buf_addr),y
sta (savebehind_vid_addr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
jsr savebehind_next_line
sta LOWSCR
2018-04-02 15:00:43 +00:00
ldy savebehind_mapwidth
: lda (savebehind_buf_addr),y
sta (savebehind_vid_addr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
jsr savebehind_next_line
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx savebehind_bottom
bcc loop
beq loop
2018-01-29 08:57:55 +00:00
jmp ShowCursorImpl
2018-04-02 15:00:43 +00:00
.endproc
dmrts: rts
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc hide_menu
clc
bcc draw_menu_draw_or_hide
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc draw_menu
sec
draw_or_hide:
lda cur_open_menu
beq dmrts
2017-09-17 18:18:47 +00:00
php
2018-04-02 15:00:43 +00:00
sta find_menu_id
jsr find_menu_by_id
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
2018-04-02 15:00:43 +00:00
jsr hilite_menu
2017-09-17 18:18:47 +00:00
plp
2018-04-02 15:00:43 +00:00
bcc restore_menu_savebehind
jsr set_up_savebehind
saveloop:
jsr savebehind_get_vidaddr
sta HISCR
2018-04-02 15:00:43 +00:00
ldy savebehind_mapwidth
: lda (savebehind_vid_addr),y
sta (savebehind_buf_addr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
jsr savebehind_next_line
sta LOWSCR
2018-04-02 15:00:43 +00:00
ldy savebehind_mapwidth
: lda (savebehind_vid_addr),y
sta (savebehind_buf_addr),y
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
bpl :-
jsr savebehind_next_line
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx savebehind_bottom
bcc saveloop
beq saveloop
jsr set_standard_port
2018-04-02 15:00:43 +00:00
ldax test_rect_params2_addr
2017-10-15 02:45:51 +00:00
jsr fill_and_frame_rect
2018-02-26 00:06:17 +00:00
inc16 fill_rect_params4::left
lda fill_rect_params4::right
2018-04-02 15:00:43 +00:00
bne :+
dec fill_rect_params4::right+1
2018-04-02 15:00:43 +00:00
: dec fill_rect_params4::right
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
jsr get_menu_and_menu_item
ldx #0
loop: jsr get_menu_item
bit curmenuitem::options
bvc :+
jmp next
2018-04-02 15:00:43 +00:00
: lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::item_is_checked
2018-04-02 15:00:43 +00:00
beq no_mark
lda offset_checkmark
jsr moveto_menuitem
lda checkmark_glyph
2018-04-02 15:00:43 +00:00
sta mark_text+1
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::item_has_mark
2018-04-02 15:00:43 +00:00
beq :+
lda curmenuitem::mark_char
sta mark_text+1
: ldax mark_text_addr
jsr draw_text
2018-04-02 15:00:43 +00:00
jsr get_menu_and_menu_item
no_mark:
lda offset_text
jsr moveto_menuitem
ldax curmenuitem::name
jsr draw_text
2018-04-02 15:00:43 +00:00
jsr get_menu_and_menu_item
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::open_apple | MGTK::MenuOpt::solid_apple
2018-04-02 15:00:43 +00:00
bne oa_sa
lda curmenuitem::shortcut1
beq no_shortcut
lda controlkey_glyph
2018-04-02 15:00:43 +00:00
sta shortcut_text+1
jmp no_shortcut
2017-09-17 18:18:47 +00:00
2018-11-18 04:34:17 +00:00
oa_sa: cmp #MGTK::MenuOpt::open_apple
2018-04-02 15:00:43 +00:00
bne :+
lda open_apple_glyph
2018-04-02 15:00:43 +00:00
sta shortcut_text+1
jmp shortcut
: lda solid_apple_glyph
sta shortcut_text+1
shortcut:
lda curmenuitem::shortcut1
sta shortcut_text+2
lda offset_shortcut
jsr moveto_fromright
ldax shortcut_text_addr
jsr draw_text
2018-04-02 15:00:43 +00:00
jsr get_menu_and_menu_item
no_shortcut:
bit curmenu::disabled
bmi :+
bit curmenuitem::options
bpl next
: jsr dim_menuitem
jmp next ; useless jmp ???
next: ldx menu_item_index
2017-09-17 18:18:47 +00:00
inx
2018-04-02 15:00:43 +00:00
cpx menu_item_count
beq :+
jmp loop
: jmp ShowCursorImpl
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc moveto_menuitem
ldx menu_item_index
2017-12-16 05:36:09 +00:00
ldy menu_item_y_table+1,x ; ???
2017-09-17 18:18:47 +00:00
dey
2018-04-02 15:00:43 +00:00
ldx curmenuinfo::x_min+1
2017-09-17 18:18:47 +00:00
clc
2018-04-02 15:00:43 +00:00
adc curmenuinfo::x_min
bcc :+
2017-09-17 18:18:47 +00:00
inx
: jmp set_penloc
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc dim_menuitem
ldx menu_item_index
2017-12-16 05:36:09 +00:00
lda menu_item_y_table,x
sta fill_rect_params3_top
inc fill_rect_params3_top
2017-12-16 05:36:09 +00:00
lda menu_item_y_table+1,x
sta fill_rect_params3_bottom
2018-04-02 15:00:43 +00:00
add16lc curmenuinfo::x_min, #5, fill_rect_params3_left
sub16lc curmenuinfo::x_max, #5, fill_rect_params3_right
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, light_speckle_pattern
2018-04-02 15:00:43 +00:00
lda #MGTK::penOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-04-02 15:00:43 +00:00
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::PaintRect, fill_rect_params3
2018-01-29 16:25:56 +00:00
MGTK_CALL MGTK::SetPattern, standard_port::penpattern
2018-04-02 15:00:43 +00:00
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
draw_menu_draw_or_hide := draw_menu::draw_or_hide
2017-09-17 18:18:47 +00:00
2017-10-01 23:17:04 +00:00
light_speckle_pattern:
.byte %10001000
.byte %01010101
.byte %10001000
.byte %01010101
.byte %10001000
.byte %01010101
.byte %10001000
.byte %01010101
.proc fill_rect_params3
left: .word 0
top: .word 0
right: .word 0
bottom: .word 0
.endproc
fill_rect_params3_left := fill_rect_params3::left
fill_rect_params3_top := fill_rect_params3::top
fill_rect_params3_right := fill_rect_params3::right
fill_rect_params3_bottom := fill_rect_params3::bottom
2018-04-02 15:00:43 +00:00
;; Move to the given distance from the right side of the menu.
.proc moveto_fromright
sta $82
ldax curmenuinfo::x_max
2017-09-17 18:18:47 +00:00
sec
2017-10-07 20:59:25 +00:00
sbc $82
2018-04-02 15:00:43 +00:00
bcs :+
2017-09-17 18:18:47 +00:00
dex
2018-04-02 15:00:43 +00:00
: jmp set_penloc::set_x
.endproc
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc unhilite_cur_menu_item
jsr hilite_menu_item
lda #0
sta cur_hilited_menu_item
.endproc
hmrts: rts
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
.proc hilite_menu_item
ldx cur_hilited_menu_item
beq hmrts
ldy menu_item_y_table-1,x
2017-09-17 18:18:47 +00:00
iny
sty fill_rect_params4::top
2017-12-16 05:36:09 +00:00
ldy menu_item_y_table,x
sty fill_rect_params4::bottom
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
2018-04-02 15:00:43 +00:00
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::PaintRect, fill_rect_params4
2018-01-29 08:57:55 +00:00
jmp ShowCursorImpl
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; InitMenu
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $82
2018-01-29 08:57:55 +00:00
.proc InitMenuImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
solid_char: .res 1
open_char: .res 1
check_char: .res 1
control_char: .res 1
END_PARAM_BLOCK
2017-10-16 03:38:58 +00:00
COPY_BYTES 4, params, menu_glyphs
2017-10-16 03:38:58 +00:00
2018-03-26 03:18:43 +00:00
copy16 standard_port::textfont, params
2017-10-16 03:38:58 +00:00
ldy #0
lda (params),y
bmi :+ ; branch if double-width font
2017-10-06 00:04:39 +00:00
2018-04-02 15:00:43 +00:00
lda #2
sta offset_checkmark
lda #9
sta offset_text
lda #16
sta offset_shortcut
lda #9
sta shortcut_x_adj
lda #30
sta non_shortcut_x_adj
2017-10-06 00:04:39 +00:00
bne end
2018-04-02 15:00:43 +00:00
: lda #2
sta offset_checkmark
lda #16
sta offset_text
lda #30
sta offset_shortcut
lda #16
sta shortcut_x_adj
lda #51
sta non_shortcut_x_adj
2017-10-06 00:04:39 +00:00
end: rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetMark
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 4 bytes of params, copied to $C7
2018-04-02 15:00:43 +00:00
.proc SetMarkImpl
PARAM_BLOCK params, $C7
menu_id: .byte 0
menu_item: .byte 0
set_char: .byte 0
mark_char: .byte 0
END_PARAM_BLOCK
jsr find_menu_item_or_fail
lda params::set_char
beq :+
2018-11-18 04:34:17 +00:00
lda #MGTK::MenuOpt::item_has_mark
2018-04-02 15:00:43 +00:00
ora curmenuitem::options
sta curmenuitem::options
lda params::mark_char
sta curmenuitem::mark_char
jmp put_menu_item
2018-11-18 04:34:17 +00:00
: lda #$FF^MGTK::MenuOpt::item_has_mark
2018-04-02 15:00:43 +00:00
and curmenuitem::options
sta curmenuitem::options
jmp put_menu_item
.endproc
2017-09-17 18:18:47 +00:00
icon_offset_pos := 0
icon_offset_width := 4
icon_offset_height := 5
icon_offset_bits := 6
2017-10-06 00:04:39 +00:00
.proc up_scroll_params
xcoord: .res 2
ycoord: .res 2
.byte 19,10
2017-10-06 00:04:39 +00:00
.addr up_scroll_bitmap
.endproc
.proc down_scroll_params
xcoord: .res 2
ycoord: .res 2
.byte 19,10
2017-10-06 00:04:39 +00:00
.addr down_scroll_bitmap
.endproc
2017-10-06 00:04:39 +00:00
.proc left_scroll_params
xcoord: .res 2
ycoord: .res 2
.byte 20,9
2017-10-06 00:04:39 +00:00
.addr left_scroll_bitmap
.endproc
.proc right_scroll_params
xcoord: .res 2
ycoord: .res 2
.byte 18,9
2017-10-06 00:04:39 +00:00
.addr right_scroll_bitmap
.endproc
.proc resize_box_params
xcoord: .res 2
ycoord: .res 2
.byte 20,10
2017-10-06 00:04:39 +00:00
.addr resize_box_bitmap
.endproc
;; Up Scroll
2017-10-06 00:04:39 +00:00
up_scroll_bitmap:
.byte px(%0000000),px(%0000000),px(%0000000)
.byte px(%0000000),px(%0001100),px(%0000000)
.byte px(%0000000),px(%0110011),px(%0000000)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0000110),px(%0000000),px(%0011000)
.byte px(%0011111),px(%1000000),px(%1111110)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0000001),px(%1111111),px(%1100000)
.byte px(%0000000),px(%0000000),px(%0000000)
.byte px(%0111111),px(%1111111),px(%1111111)
;; Down Scroll
2017-10-06 00:04:39 +00:00
down_scroll_bitmap:
.byte px(%0111111),px(%1111111),px(%1111111)
.byte px(%0000000),px(%0000000),px(%0000000)
.byte px(%0000001),px(%1111111),px(%1100000)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0011111),px(%1000000),px(%1111110)
.byte px(%0000110),px(%0000000),px(%0011000)
.byte px(%0000001),px(%1000000),px(%1100000)
.byte px(%0000000),px(%0110011),px(%0000000)
.byte px(%0000000),px(%0001100),px(%0000000)
.byte px(%0000000),px(%0000000),px(%0000000)
;; Left Scroll
2017-10-06 00:04:39 +00:00
left_scroll_bitmap:
.byte px(%0000000),px(%0000000),px(%0000000)
.byte px(%0000000),px(%0001100),px(%0000001)
.byte px(%0000000),px(%0111100),px(%0000001)
.byte px(%0000001),px(%1001111),px(%1111001)
.byte px(%0000110),px(%0000000),px(%0011001)
.byte px(%0011000),px(%0000000),px(%0011001)
.byte px(%0000110),px(%0000000),px(%0011001)
.byte px(%0000001),px(%1001111),px(%1111001)
.byte px(%0000000),px(%0111100),px(%0000001)
.byte px(%0000000),px(%0001100),px(%0000001)
;; Right Scroll
2017-10-06 00:04:39 +00:00
right_scroll_bitmap:
.byte px(%0000000),px(%0000000),px(%0000000)
.byte px(%1000000),px(%0011000),px(%0000000)
.byte px(%1000000),px(%0011110),px(%0000000)
.byte px(%1001111),px(%1111001),px(%1000000)
.byte px(%1001100),px(%0000000),px(%0110000)
.byte px(%1001100),px(%0000000),px(%0001100)
.byte px(%1001100),px(%0000000),px(%0110000)
.byte px(%1001111),px(%1111001),px(%1000000)
.byte px(%1000000),px(%0011110),px(%0000000)
.byte px(%1000000),px(%0011000),px(%0000000)
.byte 0 ; unreferenced ???
;; Resize Box
2017-10-06 00:04:39 +00:00
resize_box_bitmap:
.byte px(%1111111),px(%1111111),px(%1111111)
.byte px(%1000000),px(%0000000),px(%0000001)
.byte px(%1001111),px(%1111110),px(%0000001)
.byte px(%1001100),px(%0000111),px(%1111001)
.byte px(%1001100),px(%0000110),px(%0011001)
.byte px(%1001100),px(%0000110),px(%0011001)
.byte px(%1001111),px(%1111110),px(%0011001)
.byte px(%1000011),px(%0000000),px(%0011001)
.byte px(%1000011),px(%1111111),px(%1111001)
.byte px(%1000000),px(%0000000),px(%0000001)
.byte px(%1111111),px(%1111111),px(%1111111)
2018-02-28 02:38:18 +00:00
up_scroll_addr:
2017-10-06 00:04:39 +00:00
.addr up_scroll_params
2018-02-28 02:38:18 +00:00
down_scroll_addr:
2017-10-06 00:04:39 +00:00
.addr down_scroll_params
2018-02-28 02:38:18 +00:00
left_scroll_addr:
2017-10-06 00:04:39 +00:00
.addr left_scroll_params
2018-02-28 02:38:18 +00:00
right_scroll_addr:
2017-10-06 00:04:39 +00:00
.addr right_scroll_params
2018-02-28 02:38:18 +00:00
resize_box_addr:
2017-10-06 00:04:39 +00:00
.addr resize_box_params
current_window:
.word 0
sel_window_id:
.byte 0
found_window:
.word 0
target_window_id:
.byte 0
;; The root window is not a real window, but a structure whose
;; nextwinfo field lines up with current_window.
root_window_addr:
2018-05-26 01:49:36 +00:00
.addr current_window - MGTK::Winfo::nextwinfo
which_control := $8C
which_control_horiz := $00
which_control_vert := $80
previous_window := $A7
window := $A9
;; First 12 bytes of winfo only
PARAM_BLOCK current_winfo, $AB
id: .byte 0
options: .byte 0
title: .addr 0
hscroll: .byte 0
vscroll: .byte 0
hthumbmax: .byte 0
hthumbpos: .byte 0
vthumbmax: .byte 0
vthumbpos: .byte 0
status: .byte 0
reserved: .byte 0
END_PARAM_BLOCK
;; First 16 bytes of win's grafport only
PARAM_BLOCK current_winport, $B7
.proc viewloc
xcoord: .word 0
ycoord: .word 0
.endproc
mapbits: .addr 0
mapwidth: .byte 0
.byte 0
.proc maprect
x1: .word 0
y1: .word 0
x2: .word 0
y2: .word 0
.endproc
END_PARAM_BLOCK
PARAM_BLOCK winrect, $C7
x1: .word 0
y1: .word 0
x2: .word 0
y2: .word 0
END_PARAM_BLOCK
2017-10-06 00:04:39 +00:00
2017-10-15 04:15:35 +00:00
;; Start window enumeration at top ???
.proc top_window
copy16 root_window_addr, previous_window
ldax current_window
bne set_found_window
2017-10-15 04:15:35 +00:00
end: rts
.endproc
2017-09-17 18:18:47 +00:00
2017-10-15 04:15:35 +00:00
;; Look up next window in chain. $A9/$AA will point at
;; window params block (also returned in X,A).
2017-10-15 04:15:35 +00:00
.proc next_window
copy16 window, previous_window
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::nextwinfo+1
lda (window),y
2017-10-15 04:15:35 +00:00
beq top_window::end ; if high byte is 0, end of chain
2017-09-17 18:18:47 +00:00
tax
dey
lda (window),y
set_found_window:
stax found_window
;; Fall-through
.endproc
;; Load/refresh the ZP window data areas at $AB and $B7.
.proc get_window
ldax found_window
get_from_ax:
stax window
ldy #11 ; copy first 12 bytes of window defintion to
: lda (window),y ; to $AB
sta current_winfo,y
2017-09-17 18:18:47 +00:00
dey
bpl :-
; copy first 16 bytes of grafport to $B7
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::port + MGTK::GrafPort::pattern-1
: lda (window),y
2018-05-26 01:49:36 +00:00
sta current_winport - MGTK::Winfo::port,y
2017-09-17 18:18:47 +00:00
dey
2018-05-26 01:49:36 +00:00
cpy #MGTK::Winfo::port-1
bne :-
return_window:
ldax window
2017-09-30 02:14:47 +00:00
rts
2017-10-15 04:15:35 +00:00
.endproc
set_found_window := next_window::set_found_window
2017-09-17 18:18:47 +00:00
2017-10-15 04:15:35 +00:00
;; Look up window state by id (in $82); $A9/$AA will point at
2018-03-24 04:35:53 +00:00
;; winfo (also X,A).
2017-10-15 04:15:35 +00:00
.proc window_by_id
jsr top_window
2017-10-12 04:33:23 +00:00
beq end
loop: lda current_winfo::id
2017-10-07 20:59:25 +00:00
cmp $82
beq get_window::return_window
2017-10-15 04:15:35 +00:00
jsr next_window
2017-10-12 04:33:23 +00:00
bne loop
end: rts
.endproc
2017-09-17 18:18:47 +00:00
2017-10-15 04:15:35 +00:00
;; Look up window state by id (in $82); $A9/$AA will point at
2018-03-24 04:35:53 +00:00
;; winfo (also X,A).
2018-01-29 05:18:00 +00:00
;; This will exit the MGTK call directly (restoring stack, etc)
2017-10-12 04:33:23 +00:00
;; if the window is not found.
2017-10-15 04:15:35 +00:00
.proc window_by_id_or_exit
jsr window_by_id
2017-10-12 04:33:23 +00:00
beq nope
2017-09-30 02:14:47 +00:00
rts
2018-11-18 04:34:17 +00:00
nope: exit_call MGTK::Error::window_not_found
2017-10-12 04:33:23 +00:00
.endproc
2017-09-17 18:18:47 +00:00
frame_winrect:
MGTK_CALL MGTK::FrameRect, winrect
2017-09-17 18:18:47 +00:00
rts
in_winrect:
MGTK_CALL MGTK::InRect, winrect
2017-09-17 18:18:47 +00:00
rts
;; Retrieve the rectangle of the current window and put it in winrect.
;;
;; The rectangle is defined by placing the top-left corner at the viewloc
;; of the window and setting the width and height matching the width
;; and height of the maprect of the window's port.
;;
.proc get_winrect
COPY_BLOCK current_winport::viewloc, winrect ; copy viewloc to left/top of winrect
ldx #2
: lda current_winport::maprect::x2,x ; x2/y2
2017-09-17 18:18:47 +00:00
sec
sbc current_winport::maprect::x1,x ; x1/y1
2017-09-17 18:18:47 +00:00
tay
lda current_winport::maprect::x2+1,x
sbc current_winport::maprect::x1+1,x
2017-09-17 18:18:47 +00:00
pha
2017-09-17 18:18:47 +00:00
tya
clc
adc winrect::x1,x ; x1/y1
sta winrect::x2,x ; x2/y2
2017-09-17 18:18:47 +00:00
pla
adc winrect::x1+1,x
sta winrect::x2+1,x
2017-09-17 18:18:47 +00:00
dex
dex
bpl :-
;; Fall-through
.endproc
return_winrect:
ldax #winrect
2017-09-17 18:18:47 +00:00
rts
;; Return the window's rect including framing: title bar and scroll
;; bars.
.proc get_winframerect
jsr get_winrect
lda winrect
bne :+
dec winrect+1
: dec winrect
bit current_winfo::vscroll
bmi vert_scroll
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
bne vert_scroll
2017-09-17 18:18:47 +00:00
lda #$01
bne :+
vert_scroll:
lda #$15
: clc
adc winrect::x2
sta winrect::x2
bcc :+
inc winrect::x2+1
: lda #1
bit current_winfo::hscroll
bpl :+
2017-09-17 18:18:47 +00:00
lda #$0B
: clc
adc winrect::y2
sta winrect::y2
bcc :+
inc winrect::y2+1
:
2018-11-18 04:34:17 +00:00
lda #MGTK::Option::dialog_box
and current_winfo::options
bne :+
lda winframe_top
: sta $82
lda winrect::y1
2017-09-17 18:18:47 +00:00
sec
2017-10-07 20:59:25 +00:00
sbc $82
sta winrect::y1
bcs return_winrect
dec winrect::y1+1
bcc return_winrect
.endproc
.proc get_win_vertscrollrect
jsr get_winframerect
ldax winrect::x2
2017-09-17 18:18:47 +00:00
sec
sbc #$14
bcs :+
2017-09-17 18:18:47 +00:00
dex
: stax winrect::x1
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
bne return_winrect
lda winrect::y1
2017-09-17 18:18:47 +00:00
clc
adc wintitle_height
sta winrect::y1
bcc return_winrect
inc winrect::y1+1
bcs return_winrect
.endproc
.proc get_win_horizscrollrect
jsr get_winframerect
get_rect:
ldax winrect::y2
2017-09-17 18:18:47 +00:00
sec
sbc #$0A
bcs :+
2017-09-17 18:18:47 +00:00
dex
: stax winrect::y1
jmp return_winrect
.endproc
.proc get_win_growboxrect
jsr get_win_vertscrollrect
jmp get_win_horizscrollrect::get_rect
.endproc
2017-09-17 18:18:47 +00:00
.proc get_wintitlebar_rect
jsr get_winframerect
2017-09-17 18:18:47 +00:00
lda winrect::y1
2017-09-17 18:18:47 +00:00
clc
adc wintitle_height
sta winrect::y2
lda winrect::y1+1
adc #0
sta winrect::y2+1
jmp return_winrect
.endproc
.proc get_wingoaway_rect
jsr get_wintitlebar_rect
2017-09-17 18:18:47 +00:00
ldax winrect::x1
2017-09-17 18:18:47 +00:00
clc
adc #12
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax winrect::x1
2017-09-17 18:18:47 +00:00
clc
adc #14
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax winrect::x2
ldax winrect::y1
2017-09-17 18:18:47 +00:00
clc
adc #2
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax winrect::y1
2017-09-17 18:18:47 +00:00
clc
adc goaway_height
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax winrect::y2
2017-09-17 18:18:47 +00:00
jmp return_winrect
.endproc
.proc draw_window
jsr get_winframerect
2017-10-15 02:45:51 +00:00
jsr fill_and_frame_rect
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
bne no_titlebar
jsr get_wintitlebar_rect
2017-10-15 02:45:51 +00:00
jsr fill_and_frame_rect
jsr center_title_text
ldax current_winfo::title
jsr draw_text
2017-09-17 18:18:47 +00:00
no_titlebar:
jsr get_window
bit current_winfo::vscroll
bpl no_vert_scroll
jsr get_win_vertscrollrect
jsr frame_winrect
no_vert_scroll:
bit current_winfo::hscroll
bpl :+
jsr get_win_horizscrollrect
jsr frame_winrect
: lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
beq :+
jsr get_win_growboxrect
jsr frame_winrect
jsr get_win_vertscrollrect
jsr frame_winrect
: jsr get_window
lda current_winfo::id
cmp sel_window_id
bne :+
jsr set_desktop_port
jmp draw_winframe
: rts
.endproc
2017-09-17 18:18:47 +00:00
2017-10-01 05:54:52 +00:00
;; Drawing title bar, maybe?
draw_erase_mode:
.byte 1
2017-10-01 23:17:04 +00:00
stripes_pattern:
stripes_pattern_alt := *+1
2017-10-06 00:04:39 +00:00
.byte %11111111
.byte %00000000
.byte %11111111
.byte %00000000
.byte %11111111
.byte %00000000
.byte %11111111
.byte %00000000
.byte %11111111
.proc set_stripes_pattern
jsr get_wingoaway_rect
lda winrect::y1
and #1
beq :+
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, stripes_pattern
2017-09-17 18:18:47 +00:00
rts
: MGTK_CALL MGTK::SetPattern, stripes_pattern_alt
2017-09-17 18:18:47 +00:00
rts
.endproc
.proc erase_winframe
lda #MGTK::penOR
ldx #0
beq :+
.endproc
2017-09-17 18:18:47 +00:00
.proc draw_winframe
lda #MGTK::penBIC
ldx #1
: stx draw_erase_mode
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::go_away_box
beq no_goaway
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
bne no_goaway
jsr get_wingoaway_rect
jsr frame_winrect
jsr set_stripes_pattern
ldax winrect::x1
2017-09-17 18:18:47 +00:00
sec
sbc #9
bcs :+
2017-09-17 18:18:47 +00:00
dex
: stax left
2017-09-17 18:18:47 +00:00
clc
adc #6
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax right
copy16 winrect::y1, top
copy16 winrect::y2, bottom
2018-01-29 08:57:55 +00:00
jsr PaintRectImpl ; draws title bar stripes to left of close box
no_goaway:
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
bne no_titlebar
jsr get_wintitlebar_rect
jsr center_title_text
2018-03-30 14:58:10 +00:00
jsr penloc_to_bounds
jsr set_stripes_pattern
ldax winrect::x2
2017-09-17 18:18:47 +00:00
clc
adc #3
bcc :+
2017-09-17 18:18:47 +00:00
inx
: tay
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::go_away_box
bne has_goaway
2017-09-17 18:18:47 +00:00
tya
sec
sbc #$1A
bcs :+
2017-09-17 18:18:47 +00:00
dex
: tay
has_goaway:
tya
ldy right
sty winrect::x2
ldy right+1
sty winrect::x2+1
ldy left
sty right
ldy left+1
sty right+1
stax left
lda right
2017-09-17 18:18:47 +00:00
sec
sbc #10
sta right
bcs :+
dec right+1
: jsr PaintRectImpl ; Draw title bar stripes between close box and title
add16 winrect::x2, #10, left
jsr get_wintitlebar_rect
sub16 winrect::x2, #3, right
2018-01-29 08:57:55 +00:00
jsr PaintRectImpl ; Draw title bar stripes to right of title
2018-01-29 16:25:56 +00:00
MGTK_CALL MGTK::SetPattern, standard_port::penpattern
no_titlebar:
jsr get_window
bit current_winfo::vscroll
bpl no_vscroll
jsr get_win_vertscrollrect
ldx #3
: lda winrect,x
2017-10-06 00:04:39 +00:00
sta up_scroll_params,x
sta down_scroll_params,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
inc up_scroll_params::ycoord
ldax winrect::y2
2017-09-17 18:18:47 +00:00
sec
sbc #$0A
bcs :+
2017-09-17 18:18:47 +00:00
dex
:
pha
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
bne :+
bit current_winfo::hscroll
bpl no_hscroll
: pla
2017-09-17 18:18:47 +00:00
sec
sbc #$0B
bcs :+
2017-09-17 18:18:47 +00:00
dex
: pha
no_hscroll:
pla
stax down_scroll_params::ycoord
2018-02-28 02:38:18 +00:00
ldax down_scroll_addr
jsr draw_icon
2018-02-28 02:38:18 +00:00
ldax up_scroll_addr
jsr draw_icon
no_vscroll:
bit current_winfo::hscroll
bpl no_hscrollbar
jsr get_win_horizscrollrect
ldx #3
: lda winrect,x
2017-10-06 00:04:39 +00:00
sta left_scroll_params,x
sta right_scroll_params,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
ldax winrect::x2
2017-09-17 18:18:47 +00:00
sec
sbc #$14
bcs :+
2017-09-17 18:18:47 +00:00
dex
:
pha
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
bne :+
bit current_winfo::vscroll
bpl no_vscroll2
: pla
2017-09-17 18:18:47 +00:00
sec
2017-09-30 02:14:47 +00:00
sbc #$15
bcs :+
2017-09-30 02:14:47 +00:00
dex
: pha
no_vscroll2:
pla
stax right_scroll_params
2018-02-28 02:38:18 +00:00
ldax right_scroll_addr
jsr draw_icon
2018-02-28 02:38:18 +00:00
ldax left_scroll_addr
jsr draw_icon
no_hscrollbar:
lda #MGTK::pencopy
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
lda current_winfo::vscroll
2017-09-30 02:14:47 +00:00
and #$01
beq :+
lda #which_control_vert
sta which_control
lda draw_erase_mode
jsr draw_or_erase_scrollbar
jsr get_window
: lda current_winfo::hscroll
2017-09-17 18:18:47 +00:00
and #$01
beq :+
lda #which_control_horiz
sta which_control
lda draw_erase_mode
jsr draw_or_erase_scrollbar
jsr get_window
: lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
beq ret
jsr get_win_growboxrect
lda draw_erase_mode
bne draw_resize
ldax #winrect
2017-10-15 02:45:51 +00:00
jsr fill_and_frame_rect
jmp ret
2017-09-17 18:18:47 +00:00
;; Draw resize box
draw_resize:
ldx #3
: lda winrect,x
2017-10-06 00:04:39 +00:00
sta resize_box_params,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
lda #MGTK::notpencopy
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-02-28 02:38:18 +00:00
ldax resize_box_addr
jsr draw_icon
ret: rts
.endproc
2017-09-17 18:18:47 +00:00
.proc center_title_text
ldax current_winfo::title
jsr do_measure_text
stax $82
lda winrect::x1
2017-09-17 18:18:47 +00:00
clc
adc winrect::x2
2017-09-17 18:18:47 +00:00
tay
lda winrect::x1+1
adc winrect::x2+1
2017-09-17 18:18:47 +00:00
tax
2017-09-17 18:18:47 +00:00
tya
sec
2017-10-07 20:59:25 +00:00
sbc $82
2017-09-17 18:18:47 +00:00
tay
2017-09-17 18:18:47 +00:00
txa
2017-10-07 20:59:25 +00:00
sbc $83
2017-09-17 18:18:47 +00:00
cmp #$80
ror a
2018-01-29 16:25:56 +00:00
sta current_penloc_x+1
2017-09-17 18:18:47 +00:00
tya
ror a
2018-01-29 16:25:56 +00:00
sta current_penloc_x
ldax winrect::y2
2017-09-17 18:18:47 +00:00
sec
sbc #2
bcs :+
2017-09-17 18:18:47 +00:00
dex
: stax current_penloc_y
ldax $82
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2018-01-29 16:25:56 +00:00
;;; 4 bytes of params, copied to current_penloc
2017-10-07 20:59:25 +00:00
.proc FindWindowImpl
PARAM_BLOCK params, $EA
mousex: .word 0
mousey: .word 0
which_area: .byte 0
window_id: .byte 0
END_PARAM_BLOCK
jsr save_params_and_stack
MGTK_CALL MGTK::InRect, test_rect_params ; check if in menubar
beq not_menubar
2018-11-18 04:34:17 +00:00
lda #MGTK::Area::menubar
return_no_window:
ldx #0
return_result:
pha
txa
2017-09-17 18:18:47 +00:00
pha
jsr restore_params_active_port
2017-09-17 18:18:47 +00:00
pla
tax
pla
ldy #params::which_area - params
2018-02-28 02:38:18 +00:00
jmp store_xa_at_y
2017-09-17 18:18:47 +00:00
not_menubar:
lda #0 ; first window we see is the selected one
sta not_selected
2017-10-15 04:15:35 +00:00
jsr top_window
beq no_windows
loop: jsr get_winframerect
jsr in_winrect
bne in_window
2017-10-15 04:15:35 +00:00
jsr next_window
stx not_selected ; set to non-zero for subsequent windows
bne loop
no_windows:
2018-11-18 04:34:17 +00:00
lda #MGTK::Area::desktop
beq return_no_window
in_window:
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
bne in_content
jsr get_wintitlebar_rect
jsr in_winrect
beq in_content
lda not_selected
bne :+
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::go_away_box
beq :+
jsr get_wingoaway_rect
jsr in_winrect
beq :+
2018-11-18 04:34:17 +00:00
lda #MGTK::Area::close_box
bne return_window
2018-11-18 04:34:17 +00:00
: lda #MGTK::Area::dragbar
bne return_window
in_content:
lda not_selected
bne :+
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
beq :+
jsr get_win_growboxrect
jsr in_winrect
beq :+
2018-11-18 04:34:17 +00:00
lda #MGTK::Area::grow_box
return_window:
ldx current_winfo::id
bne return_result
2018-11-18 04:34:17 +00:00
: lda #MGTK::Area::content
bne return_window
not_selected:
.byte 0
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
;;; OpenWindow
2017-10-03 03:05:07 +00:00
;;; params points to a winfo structure
.proc OpenWindowImpl
win_id := $82
copy16 params_addr, window
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::window_id
lda (window),y
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::window_id_required
2017-09-17 18:18:47 +00:00
: sta win_id
2017-10-15 04:15:35 +00:00
jsr window_by_id
beq :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::window_already_exists
2017-09-17 18:18:47 +00:00
: copy16 params_addr, window
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::status
lda (window),y
2017-09-17 18:18:47 +00:00
ora #$80
sta (window),y
bmi do_select_win
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SelectWindow
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
.proc SelectWindowImpl
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
cmp current_window
bne :+
cpx current_window+1
bne :+
2017-09-17 18:18:47 +00:00
rts
: jsr link_window
do_select_win:
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::nextwinfo
lda current_window
sta (window),y
2017-09-17 18:18:47 +00:00
iny
lda current_window+1
sta (window),y
lda window
2017-09-17 18:18:47 +00:00
pha
lda window+1
2017-09-17 18:18:47 +00:00
pha
2018-04-02 15:00:43 +00:00
jsr hide_cursor_save_params
jsr set_desktop_port
2017-10-15 04:15:35 +00:00
jsr top_window
beq :+
jsr erase_winframe
: pla
sta current_window+1
2017-09-17 18:18:47 +00:00
pla
sta current_window
2017-10-15 04:15:35 +00:00
jsr top_window
lda current_winfo::id
sta sel_window_id
jsr draw_window
2018-04-02 15:00:43 +00:00
jmp show_cursor_and_restore
.endproc
do_select_win := SelectWindowImpl::do_select_win
2017-09-17 18:18:47 +00:00
.proc link_window
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::nextwinfo
lda (window),y
sta (previous_window),y
2017-09-17 18:18:47 +00:00
iny
lda (window),y
sta (previous_window),y
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetWinPtr
2017-10-07 03:59:09 +00:00
2018-04-28 23:22:33 +00:00
;;; 1 byte of params, copied to $82
2017-10-07 20:59:25 +00:00
2018-01-29 08:57:55 +00:00
.proc GetWinPtrImpl
2017-10-15 04:15:35 +00:00
ptr := $A9
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
ldax ptr
2017-10-15 04:15:35 +00:00
ldy #1
2018-02-28 02:38:18 +00:00
jmp store_xa_at_y
2017-10-15 04:15:35 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; BeginUpdate
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
previous_port:
.res 2
update_port:
2018-05-26 01:39:43 +00:00
.res .sizeof(MGTK::GrafPort)
2017-10-03 02:48:21 +00:00
2018-01-29 08:57:55 +00:00
.proc BeginUpdateImpl
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
lda current_winfo::id
cmp target_window_id
2017-12-16 05:36:09 +00:00
bne :+
inc matched_target
2017-12-16 05:36:09 +00:00
2018-04-02 15:00:43 +00:00
: jsr hide_cursor_save_params
jsr set_desktop_port
lda matched_target
2017-12-16 05:36:09 +00:00
bne :+
2018-01-29 16:25:56 +00:00
MGTK_CALL MGTK::SetPortBits, set_port_params
: jsr draw_window
jsr set_desktop_port
lda matched_target
2017-12-16 05:36:09 +00:00
bne :+
2018-01-29 16:25:56 +00:00
MGTK_CALL MGTK::SetPortBits, set_port_params
: jsr get_window
copy16 active_port, previous_port
jsr prepare_winport
2017-09-17 18:18:47 +00:00
php
ldax update_port_addr
2018-01-29 16:25:56 +00:00
jsr assign_and_prepare_port
2017-10-06 04:18:28 +00:00
asl preserve_zp_flag
2017-09-17 18:18:47 +00:00
plp
2017-12-16 05:36:09 +00:00
bcc :+
2017-09-17 18:18:47 +00:00
rts
2018-01-29 08:57:55 +00:00
: jsr EndUpdateImpl
2017-12-16 05:36:09 +00:00
;; fall through
2017-10-15 04:15:35 +00:00
.endproc
2017-09-17 18:18:47 +00:00
err_obscured:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::window_obscured
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; EndUpdate
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
update_port_addr:
.addr update_port
2017-10-07 03:59:09 +00:00
.proc EndUpdateImpl
2018-01-29 08:57:55 +00:00
jsr ShowCursorImpl
ldax previous_port
stax active_port
jmp set_and_prepare_port
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; GetWinPort
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $82
.proc GetWinPortImpl
PARAM_BLOCK params, $82
win_id: .byte 0
win_port: .addr 0
END_PARAM_BLOCK
2018-01-29 16:25:56 +00:00
jsr apply_port_to_active_port
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
copy16 params::win_port, params_addr
COPY_STRUCT MGTK::Rect, fill_rect_params, current_maprect_x1
jsr prepare_winport
bcc err_obscured
2018-05-26 01:39:43 +00:00
ldy #.sizeof(MGTK::GrafPort)-1
: lda current_grafport,y
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
dey
bpl :-
2018-01-29 16:25:56 +00:00
jmp apply_active_port_to_port
.endproc
2017-09-17 18:18:47 +00:00
.proc prepare_winport
jsr get_winrect
ldx #7
: lda #0
sta clipped_left,x
lda winrect,x
sta left,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
jsr clip_rect
bcs :+
2017-09-17 18:18:47 +00:00
rts
;; Load window's grafport into current_grafport.
2018-05-26 01:49:36 +00:00
: ldy #MGTK::Winfo::port
: lda (window),y
2018-05-26 01:49:36 +00:00
sta current_grafport - MGTK::Winfo::port,y
2017-09-17 18:18:47 +00:00
iny
2018-05-26 01:49:36 +00:00
cpy #MGTK::Winfo::port + .sizeof(MGTK::GrafPort)
bne :-
2018-03-26 03:18:43 +00:00
ldx #2
: lda left,x
sta current_viewloc_x,x
lda left+1,x
sta current_viewloc_x+1,x
lda right,x
sec
sbc left,x
sta $82,x
lda right+1,x
sbc left+1,x
sta $83,x
lda current_maprect_x1,x
sec
sbc clipped_left,x
sta current_maprect_x1,x
lda current_maprect_x1+1,x
sbc clipped_left+1,x
sta current_maprect_x1+1,x
lda current_maprect_x1,x
clc
adc $82,x
sta current_maprect_x2,x
lda current_maprect_x1+1,x
adc $83,x
sta current_maprect_x2+1,x
2018-03-26 03:18:43 +00:00
2017-09-17 18:18:47 +00:00
dex
dex
bpl :-
2017-09-17 18:18:47 +00:00
sec
rts
.endproc
2017-10-04 15:31:53 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetWinPort
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $82
2018-01-29 16:25:56 +00:00
;; This updates win grafport from params ???
2017-10-15 04:15:35 +00:00
;; The math is weird; $82 is the window id so
;; how does ($82),y do anything useful - is
;; this buggy ???
;; It seems like it's trying to update a fraction
2018-01-29 16:25:56 +00:00
;; of the drawing port (from |pattern| to |font|)
2017-10-15 04:15:35 +00:00
2018-01-29 08:57:55 +00:00
.proc SetWinPortImpl
ptr := window
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
lda ptr
2017-09-17 18:18:47 +00:00
clc
2018-05-26 01:49:36 +00:00
adc #MGTK::Winfo::port
2017-10-15 04:15:35 +00:00
sta ptr
bcc :+
inc ptr+1
2018-05-26 01:39:43 +00:00
: ldy #.sizeof(MGTK::GrafPort)-1
2017-10-15 04:15:35 +00:00
loop: lda ($82),y
sta (ptr),y
2017-09-17 18:18:47 +00:00
dey
cpy #$10
2017-10-15 04:15:35 +00:00
bcs loop
2017-09-17 18:18:47 +00:00
rts
2017-10-15 04:15:35 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; FrontWindow
2017-10-04 15:31:53 +00:00
2018-01-29 08:57:55 +00:00
.proc FrontWindowImpl
2017-10-15 04:15:35 +00:00
jsr top_window
beq nope
lda current_winfo::id
2017-10-15 04:15:35 +00:00
bne :+
2017-10-15 04:15:35 +00:00
nope: lda #0
: ldy #0
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
rts
2017-10-15 04:15:35 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; TrackGoAway
2017-10-03 03:05:07 +00:00
2017-10-09 04:02:57 +00:00
in_close_box: .byte 0
2017-10-07 22:07:12 +00:00
2018-01-29 08:57:55 +00:00
.proc TrackGoAwayImpl
2017-10-15 04:15:35 +00:00
jsr top_window
2017-10-09 04:02:57 +00:00
beq end
jsr get_wingoaway_rect
jsr save_params_and_stack
jsr set_desktop_port
2017-09-17 18:18:47 +00:00
lda #$80
2017-10-09 04:02:57 +00:00
toggle: sta in_close_box
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
MGTK_CALL MGTK::PaintRect, winrect
2018-01-29 08:57:55 +00:00
jsr ShowCursorImpl
2018-04-02 15:00:43 +00:00
loop: jsr get_and_return_event
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::button_up
beq :+
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::MoveTo, set_pos_params
jsr in_winrect
2017-10-09 04:02:57 +00:00
eor in_close_box
bpl loop
lda in_close_box
2017-09-17 18:18:47 +00:00
eor #$80
2017-10-09 04:02:57 +00:00
jmp toggle
2017-09-17 18:18:47 +00:00
: jsr restore_params_active_port
ldy #0
2017-10-09 04:02:57 +00:00
lda in_close_box
beq end
lda #1
2017-10-09 04:02:57 +00:00
end: sta (params_addr),y
2017-09-17 18:18:47 +00:00
rts
2017-10-09 04:02:57 +00:00
.endproc
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-09-17 18:18:47 +00:00
2017-09-30 02:14:47 +00:00
.byte $00
.proc drag_initialpos
xcoord: .res 2
ycoord: .res 2
.endproc
.proc drag_curpos
xcoord: .res 2
ycoord: .res 2
.endproc
.proc drag_delta
xdelta: .res 2
ydelta: .res 2
.endproc
2017-12-16 05:36:09 +00:00
;; High bit set if window is being resized, clear if moved.
drag_resize_flag:
.byte 0
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 5 bytes of params, copied to $82
2018-01-29 08:57:55 +00:00
GrowWindowImpl:
2017-09-17 18:18:47 +00:00
lda #$80
bmi DragWindowImpl_drag_or_grow
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 5 bytes of params, copied to $82
.proc DragWindowImpl
PARAM_BLOCK params, $82
window_id: .byte 0
dragx: .word 0
dragy: .word 0
moved: .byte 0
END_PARAM_BLOCK
lda #0
drag_or_grow:
sta drag_resize_flag
jsr kbd_mouse_init_tracking
ldx #3
: lda params::dragx,x
sta drag_initialpos,x
sta drag_curpos,x
lda #0
sta drag_delta,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
2018-03-24 02:43:22 +00:00
bit kbd_mouse_state
bpl :+
jsr kbd_win_drag_or_grow
: jsr hide_cursor_save_params
jsr winframe_to_set_port
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, checkerboard_pattern
loop: jsr get_window
jsr update_win_for_drag
jsr get_winframerect
jsr frame_winrect
2018-01-29 08:57:55 +00:00
jsr ShowCursorImpl
no_change:
jsr get_and_return_event
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::button_up
bne dragging
jsr frame_winrect
bit movement_cancel
bmi cancelled
ldx #3
: lda drag_delta,x
bne changed
2017-09-17 18:18:47 +00:00
dex
bpl :-
cancelled:
jsr show_cursor_and_restore
lda #0
return_moved:
ldy #params::moved - params
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
rts
changed:
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::port
: lda current_winport - MGTK::Winfo::port,y
sta (window),y
2017-09-17 18:18:47 +00:00
iny
2018-05-26 01:49:36 +00:00
cpy #MGTK::Winfo::port + 16
bne :-
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
lda current_winfo::id
jsr erase_window
2018-04-02 15:00:43 +00:00
jsr hide_cursor_save_params
bit movement_cancel
bvc :+
jsr set_input
: jsr show_cursor_and_restore
2017-09-17 18:18:47 +00:00
lda #$80
jmp return_moved
dragging:
jsr check_if_changed
beq no_change
2017-09-17 18:18:47 +00:00
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
jsr frame_winrect
jmp loop
.endproc
.proc update_win_for_drag
win_width := $82
PARAM_BLOCK content, $C7
minwidth: .word 0
minheight: .word 0
maxwidth: .word 0
maxheight: .word 0
END_PARAM_BLOCK
2017-09-17 18:18:47 +00:00
;; Copy mincontwidth..maxcontheight from the window to content
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::port-1
: lda (window),y
2018-05-26 01:49:36 +00:00
sta content - MGTK::Winfo::mincontwidth,y
2017-09-17 18:18:47 +00:00
dey
2018-05-26 01:49:36 +00:00
cpy #MGTK::Winfo::mincontwidth-1
bne :-
ldx #0
stx force_tracking_change
2017-12-16 05:36:09 +00:00
bit drag_resize_flag
bmi grow
: add16 current_winport::viewloc::xcoord,x, drag_delta,x, current_winport::viewloc::xcoord,x
2017-09-17 18:18:47 +00:00
inx
inx
cpx #4
bne :-
2017-09-17 18:18:47 +00:00
lda #$12
cmp current_winport::viewloc::ycoord
bcc :+
sta current_winport::viewloc::ycoord
: rts
2017-09-17 18:18:47 +00:00
grow: lda #0
sta grew_flag
loop: add16lc current_winport::maprect::x2,x, drag_delta,x, current_winport::maprect::x2,x
sub16lc current_winport::maprect::x2,x, current_winport::maprect::x1,x, win_width
2017-09-17 18:18:47 +00:00
sec
lda win_width
sbc content::minwidth,x
lda win_width+1
sbc content::minwidth+1,x
bpl :+
add16lc content::minwidth,x, current_winport::maprect::x1,x, current_winport::maprect::x2,x
jsr set_grew_flag
jmp next
2017-09-17 18:18:47 +00:00
: sec
lda content::maxwidth,x
sbc win_width
lda content::maxwidth+1,x
sbc win_width+1
bpl next
add16lc content::maxwidth,x, current_winport::maprect::x1,x, current_winport::maprect::x2,x
jsr set_grew_flag
next: inx
2017-09-17 18:18:47 +00:00
inx
cpx #4
bne loop
jmp finish_grow
.endproc
2017-09-17 18:18:47 +00:00
;; Return with Z=1 if the drag position was not changed, or Z=0
;; if the drag position was changed or force_tracking_change is set.
.proc check_if_changed
ldx #2
ldy #0
loop: lda get_and_return_event::event::mouse_pos+1,x
cmp drag_curpos+1,x
bne :+
2017-09-17 18:18:47 +00:00
iny
:
lda get_and_return_event::event::mouse_pos,x
cmp drag_curpos,x
bne :+
2017-09-17 18:18:47 +00:00
iny
: sta drag_curpos,x
2017-09-17 18:18:47 +00:00
sec
sbc drag_initialpos,x
sta drag_delta,x
lda get_and_return_event::event::mouse_pos+1,x
sta drag_curpos+1,x
sbc drag_initialpos+1,x
sta drag_delta+1,x
2017-09-17 18:18:47 +00:00
dex
dex
bpl loop
cpy #4
bne :+
lda force_tracking_change
: rts
.endproc
DragWindowImpl_drag_or_grow := DragWindowImpl::drag_or_grow
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; CloseWindow
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
2018-01-29 08:57:55 +00:00
.proc CloseWindowImpl
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
2018-04-02 15:00:43 +00:00
jsr hide_cursor_save_params
jsr winframe_to_set_port
jsr link_window
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::status
lda (window),y
2017-09-17 18:18:47 +00:00
and #$7F
sta (window),y
2017-10-15 04:15:35 +00:00
jsr top_window
lda current_winfo::id
sta sel_window_id
lda #0
jmp erase_window
2017-10-15 04:15:35 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; CloseAll
2017-10-04 15:31:53 +00:00
.proc CloseAllImpl
2018-01-29 08:57:55 +00:00
jsr top_window
beq :+
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::status
lda (window),y
2017-09-17 18:18:47 +00:00
and #$7F
sta (window),y
jsr link_window
2018-01-29 08:57:55 +00:00
jmp CloseAllImpl
: jmp StartDeskTopImpl::reset_desktop
.endproc
2017-09-17 18:18:47 +00:00
.proc winframe_to_set_port
jsr set_desktop_port
jsr get_winframerect
2017-09-17 18:18:47 +00:00
COPY_BLOCK winrect, left
jsr clip_rect
ldx #3
: lda left,x
2018-02-28 02:38:18 +00:00
sta set_port_maprect,x
2018-01-29 16:25:56 +00:00
sta set_port_params,x
lda right,x
2018-02-28 02:38:18 +00:00
sta set_port_size,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-09-17 18:18:47 +00:00
rts
.endproc
matched_target:
.byte 0
2017-09-17 18:18:47 +00:00
2017-10-09 04:02:57 +00:00
;; Erases window after destruction
.proc erase_window
sta target_window_id
lda #0
sta matched_target
2018-01-29 16:25:56 +00:00
MGTK_CALL MGTK::SetPortBits, set_port_params
lda #MGTK::pencopy
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, checkerboard_pattern
2018-02-28 02:38:18 +00:00
MGTK_CALL MGTK::PaintRect, set_port_maprect
2018-04-02 15:00:43 +00:00
jsr show_cursor_and_restore
2017-10-15 04:15:35 +00:00
jsr top_window
beq ret
2017-09-17 18:18:47 +00:00
php
sei
2018-01-29 08:57:55 +00:00
jsr FlushEventsImpl
: jsr next_window
bne :-
loop: jsr put_event
bcs plp_ret
2017-09-17 18:18:47 +00:00
tax
2018-11-18 04:34:17 +00:00
lda #MGTK::EventKind::update
sta eventbuf::kind,x
lda current_winfo::id
sta eventbuf::window_id,x
lda current_winfo::id
cmp sel_window_id
beq plp_ret
2017-10-07 20:59:25 +00:00
sta $82
2017-10-15 04:15:35 +00:00
jsr window_by_id
2017-09-17 18:18:47 +00:00
ldax previous_window
jsr get_window::get_from_ax
jmp loop
plp_ret:
plp
ret: rts
.endproc
2017-09-17 18:18:47 +00:00
goaway_height: .word 8 ; font height - 1
wintitle_height:.word 12 ; font height + 3
winframe_top: .word 13 ; font height + 4
2018-01-29 16:25:56 +00:00
.proc set_port_params
left: .word 0
top: .word $D
mapbits: .addr MGTK::screen_mapbits
mapwidth: .word MGTK::screen_mapwidth
hoffset: .word 0
voffset: .word 0
width: .word 0
height: .word 0
.endproc
2018-02-28 02:38:18 +00:00
set_port_top := set_port_params::top
set_port_size := set_port_params::width
set_port_maprect := set_port_params::hoffset ; Re-used since h/voff are 0
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; WindowToScreen
2017-10-07 03:59:09 +00:00
2017-10-15 04:15:35 +00:00
;; $83/$84 += $B7/$B8
;; $85/$86 += $B9/$BA
2018-01-29 08:57:55 +00:00
.proc WindowToScreenImpl
PARAM_BLOCK params, $82
window_id: .byte 0
windowx: .word 0
windowy: .word 0
screenx: .word 0 ; out
screeny: .word 0 ; out
END_PARAM_BLOCK
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
2017-10-15 04:15:35 +00:00
ldx #2
loop: add16 params::windowx,x, current_winport::viewloc,x, params::windowx,x
2017-09-17 18:18:47 +00:00
dex
dex
2017-10-15 04:15:35 +00:00
bpl loop
bmi copy_map_results ; always
2017-10-15 04:15:35 +00:00
.endproc
2017-10-03 03:05:07 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; ScreenToWindow
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 5 bytes of params, copied to $82
2018-04-04 04:26:13 +00:00
.proc ScreenToWindowImpl
PARAM_BLOCK params, $82
window_id: .byte 0
screenx: .word 0
screeny: .word 0
windowx: .word 0 ; out
windowy: .word 0 ; out
END_PARAM_BLOCK
2017-10-15 04:15:35 +00:00
jsr window_by_id_or_exit
ldx #2
: sub16 params::screenx,x, current_winport::viewloc,x, params::screenx,x
2017-09-17 18:18:47 +00:00
dex
dex
bpl :-
2018-04-04 04:26:13 +00:00
;; fall through
.endproc
.proc copy_map_results
ldy #ScreenToWindowImpl::params::windowx - ScreenToWindowImpl::params
: lda ScreenToWindowImpl::params + (ScreenToWindowImpl::params::screenx - ScreenToWindowImpl::params::windowx),y
2017-10-07 20:59:25 +00:00
sta (params_addr),y
2017-09-17 18:18:47 +00:00
iny
cpy #ScreenToWindowImpl::params::size ; results are 2 words (x, y) at params_addr+5
bne :-
2017-09-17 18:18:47 +00:00
rts
2018-04-04 04:26:13 +00:00
.endproc
;;; ============================================================
2017-09-17 18:18:47 +00:00
;; Used to draw scrollbar arrows and resize box
.proc draw_icon
icon_ptr := $82
stax icon_ptr
ldy #3
: lda #0
sta PaintBitsImpl::dbi_left,y
lda (icon_ptr),y
sta left,y
2017-09-17 18:18:47 +00:00
dey
bpl :-
2017-09-17 18:18:47 +00:00
iny
sty $91 ; zero
ldy #icon_offset_width
lda (icon_ptr),y
2017-09-17 18:18:47 +00:00
tax
lda div7_table+7,x
sta src_mapwidth
2017-09-17 18:18:47 +00:00
txa
ldx left+1
2017-09-17 18:18:47 +00:00
clc
adc left
bcc :+
2017-09-17 18:18:47 +00:00
inx
: stax right
2017-09-17 18:18:47 +00:00
iny
lda (icon_ptr),y ; height
ldx top+1
2017-09-17 18:18:47 +00:00
clc
adc top
bcc :+
2017-09-30 02:14:47 +00:00
inx
: stax bottom
2017-09-17 18:18:47 +00:00
iny
lda (icon_ptr),y
sta bits_addr
2017-09-17 18:18:47 +00:00
iny
lda (icon_ptr),y
sta bits_addr+1
jmp BitBltImpl
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; ActivateCtl
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $8C
.proc ActivateCtlImpl
PARAM_BLOCK params, $8C
which_ctl: .byte 0
activate: .byte 0
END_PARAM_BLOCK
2017-09-17 18:18:47 +00:00
lda which_control
2018-11-18 04:34:17 +00:00
cmp #MGTK::Ctl::vertical_scroll_bar
bne :+
lda #which_control_vert
sta which_control
bne activate
2018-11-18 04:34:17 +00:00
: cmp #MGTK::Ctl::horizontal_scroll_bar
bne ret
lda #which_control_horiz
sta which_control
beq activate
ret: rts
activate:
jsr hide_cursor_save_params
2017-10-15 04:15:35 +00:00
jsr top_window
bit which_control
bpl :+
lda current_winfo::vscroll
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::vscroll
bne toggle
: lda current_winfo::hscroll
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::hscroll
toggle: eor params::activate
and #1
eor (window),y
sta (window),y
lda params::activate
jsr draw_or_erase_scrollbar
2018-04-02 15:00:43 +00:00
jmp show_cursor_and_restore
.endproc
2017-09-17 18:18:47 +00:00
.proc draw_or_erase_scrollbar
bne do_draw
jsr get_scrollbar_scroll_area
jsr set_standard_port
MGTK_CALL MGTK::PaintRect, winrect
2017-09-17 18:18:47 +00:00
rts
do_draw:
bit which_control
bmi vert_scrollbar
bit current_winfo::hscroll
bmi has_scroll
ret: rts
vert_scrollbar:
bit current_winfo::vscroll
bpl ret
has_scroll:
jsr set_standard_port
jsr get_scrollbar_scroll_area
MGTK_CALL MGTK::SetPattern, light_speckles_pattern
MGTK_CALL MGTK::PaintRect, winrect
MGTK_CALL MGTK::SetPattern, standard_port::penpattern
bit which_control
bmi vert_thumb
bit current_winfo::hscroll
bvs has_thumb
ret2: rts
2017-09-17 18:18:47 +00:00
vert_thumb:
bit current_winfo::vscroll
bvc ret2
has_thumb:
jsr get_thumb_rect
2017-10-15 02:45:51 +00:00
jmp fill_and_frame_rect
.endproc
2017-09-17 18:18:47 +00:00
2017-10-01 23:17:04 +00:00
light_speckles_pattern:
.byte %11011101
.byte %01110111
.byte %11011101
.byte %01110111
.byte %11011101
.byte %01110111
.byte %11011101
.byte %01110111
2017-09-30 02:14:47 +00:00
.byte $00,$00
2017-10-07 20:59:25 +00:00
.proc get_scrollbar_scroll_area
bit which_control
bpl horiz
jsr get_win_vertscrollrect
lda winrect::y1
2017-09-17 18:18:47 +00:00
clc
adc #$0C
sta winrect::y1
bcc :+
inc winrect::y1+1
:
lda winrect::y2
2017-09-17 18:18:47 +00:00
sec
sbc #$0B
sta winrect::y2
bcs :+
dec winrect::y2+1
:
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
bne :+
bit current_winfo::hscroll
bpl v_noscroll
: lda winrect::y2
2017-09-17 18:18:47 +00:00
sec
sbc #$0B
sta winrect::y2
bcs :+
dec winrect::y2+1
:
v_noscroll:
inc16 winrect::x1
lda winrect::x2
bne :+
dec winrect::x2+1
: dec winrect::x2
jmp return_winrect_jmp
horiz: jsr get_win_horizscrollrect
lda winrect::x1
2017-09-17 18:18:47 +00:00
clc
adc #$15
sta winrect::x1
bcc :+
inc winrect::x1+1
:
lda winrect::x2
2017-09-17 18:18:47 +00:00
sec
sbc #$15
sta winrect::x2
bcs :+
dec winrect::x2+1
:
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
bne :+
bit current_winfo::vscroll
bpl h_novscroll
: lda winrect::x2
2017-09-17 18:18:47 +00:00
sec
sbc #$15
sta winrect::x2
bcs h_novscroll
dec winrect::x2+1
h_novscroll:
inc16 winrect::y1
lda winrect::y2
bne :+
dec winrect::y2+1
: dec winrect::y2
return_winrect_jmp:
jmp return_winrect
.endproc
thumb_max := $A3
thumb_pos := $A1
xthumb_width := 20
ythumb_height := 12
.proc get_thumb_rect
thumb_coord := $82
jsr get_scrollbar_scroll_area
jsr get_thumb_vals
jsr fixed_div
lda fixed_div_quotient+2 ; 8.0 integral part
2017-09-17 18:18:47 +00:00
pha
jsr calc_ctl_bounds
jsr set_up_thumb_division
2017-09-17 18:18:47 +00:00
pla
tax
lda thumb_max
ldy thumb_max+1
cpx #1 ; 100%
beq :+
ldx fixed_div_quotient+1 ; 0.8 fractional part
jsr get_thumb_coord
: sta thumb_coord
sty thumb_coord+1
ldx #0 ; x-coords
lda #xthumb_width
bit which_control
bpl :+
ldx #2 ; y-coords
lda #ythumb_height
: pha
add16 winrect,x, thumb_coord, winrect,x
2017-09-17 18:18:47 +00:00
pla
clc
adc winrect::x1,x
sta winrect::x2,x
lda winrect::x1+1,x
adc #0
sta winrect::x2+1,x
jmp return_winrect
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; FindControl
2017-10-03 03:05:07 +00:00
2018-01-29 16:25:56 +00:00
;;; 4 bytes of params, copied to current_penloc
2017-10-07 20:59:25 +00:00
.proc FindControlImpl
jsr save_params_and_stack
2017-10-15 04:15:35 +00:00
jsr top_window
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::no_active_window
2017-09-17 18:18:47 +00:00
: bit current_winfo::vscroll
bpl no_vscroll
jsr get_win_vertscrollrect
jsr in_winrect
beq no_vscroll
ldx #0
lda current_winfo::vscroll
2017-09-17 18:18:47 +00:00
and #$01
beq vscrollbar
lda #which_control_vert
sta which_control
jsr get_scrollbar_scroll_area
jsr in_winrect
beq in_arrows
bit current_winfo::vscroll
bcs return_dead_zone ; never ???
jsr get_thumb_rect
jsr in_winrect
beq no_thumb
2018-11-18 04:34:17 +00:00
ldx #MGTK::Part::thumb
bne vscrollbar
in_arrows:
2018-11-18 04:34:17 +00:00
lda #MGTK::Part::up_arrow
bne :+
no_thumb:
2018-11-18 04:34:17 +00:00
lda #MGTK::Part::page_up
: pha
jsr get_thumb_rect
2017-09-17 18:18:47 +00:00
pla
tax
2018-01-29 16:25:56 +00:00
lda current_penloc_y
cmp winrect::y1
bcc :+
inx ; part_down_arrow / part_page_down
:
vscrollbar:
2018-11-18 04:34:17 +00:00
lda #MGTK::Ctl::vertical_scroll_bar
bne return_result
no_vscroll:
bit current_winfo::hscroll
bpl no_hscroll
jsr get_win_horizscrollrect
jsr in_winrect
beq no_hscroll
ldx #0
lda current_winfo::hscroll
2017-09-17 18:18:47 +00:00
and #$01
beq hscrollbar
lda #which_control_horiz
sta which_control
jsr get_scrollbar_scroll_area
jsr in_winrect
beq in_harrows
bit current_winfo::hscroll
bvc return_dead_zone
jsr get_thumb_rect
jsr in_winrect
beq no_hthumb
2018-11-18 04:34:17 +00:00
ldx #MGTK::Part::thumb
bne hscrollbar
in_harrows:
2018-11-18 04:34:17 +00:00
lda #MGTK::Part::left_arrow
bne :+
no_hthumb:
2018-11-18 04:34:17 +00:00
lda #MGTK::Part::page_left
: pha
jsr get_thumb_rect
2017-09-17 18:18:47 +00:00
pla
tax
2018-01-29 16:25:56 +00:00
lda current_penloc_x+1
cmp winrect::x1+1
bcc hscrollbar
bne :+
2018-01-29 16:25:56 +00:00
lda current_penloc_x
cmp winrect::x1
bcc hscrollbar
: inx
hscrollbar:
2018-11-18 04:34:17 +00:00
lda #MGTK::Ctl::horizontal_scroll_bar
bne return_result
no_hscroll:
jsr get_winrect
jsr in_winrect
beq return_dead_zone
2018-11-18 04:34:17 +00:00
lda #MGTK::Ctl::not_a_control
beq return_result
return_dead_zone:
2018-11-18 04:34:17 +00:00
lda #MGTK::Ctl::dead_zone
return_result:
jmp FindWindowImpl::return_result
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; SetCtlMax
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $82
.proc SetCtlMaxImpl
PARAM_BLOCK params, $82
which_ctl: .byte 0
ctlmax: .byte 0
END_PARAM_BLOCK
lda params::which_ctl
2018-11-18 04:34:17 +00:00
cmp #MGTK::Ctl::vertical_scroll_bar
bne :+
2017-09-17 18:18:47 +00:00
lda #$80
sta params::which_ctl
bne got_ctl ; always
2018-11-18 04:34:17 +00:00
: cmp #MGTK::Ctl::horizontal_scroll_bar
bne :+
2017-09-17 18:18:47 +00:00
lda #$00
sta params::which_ctl
beq got_ctl ; always
2018-11-18 04:34:17 +00:00
: exit_call MGTK::Error::control_not_found
got_ctl:
jsr top_window
bne :+
2017-09-17 18:18:47 +00:00
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::no_active_window
2017-09-17 18:18:47 +00:00
2018-05-26 01:49:36 +00:00
: ldy #MGTK::Winfo::hthumbmax
bit params::which_ctl
bpl :+
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::vthumbmax
: lda params::ctlmax
sta (window),y
sta current_winfo,y
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; TrackThumb
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 5 bytes of params, copied to $82
.proc TrackThumbImpl
PARAM_BLOCK params, $82
which_ctl: .byte 0
mouse_pos:
mousex: .word 0
mousey: .word 0
thumbpos: .byte 0
thumbmoved: .byte 0
END_PARAM_BLOCK
thumb_dim := $82
lda params::which_ctl
2018-11-18 04:34:17 +00:00
cmp #MGTK::Ctl::vertical_scroll_bar
bne :+
lda #which_control_vert
sta params::which_ctl
bne got_ctl ; always
2018-11-18 04:34:17 +00:00
: cmp #MGTK::Ctl::horizontal_scroll_bar
bne :+
lda #which_control_horiz
sta params::which_ctl
beq got_ctl ; always
2018-11-18 04:34:17 +00:00
: exit_call MGTK::Error::control_not_found
got_ctl:lda params::which_ctl
sta which_control
ldx #3
: lda params::mouse_pos,x
sta drag_initialpos,x
sta drag_curpos,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
2017-10-15 04:15:35 +00:00
jsr top_window
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::no_active_window
2017-09-17 18:18:47 +00:00
: jsr get_thumb_rect
jsr save_params_and_stack
jsr set_desktop_port
lda #MGTK::penXOR
2017-10-15 02:45:51 +00:00
jsr set_fill_mode
2018-01-29 05:18:00 +00:00
MGTK_CALL MGTK::SetPattern, light_speckles_pattern
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
drag_loop:
jsr frame_winrect
2018-01-29 08:57:55 +00:00
jsr ShowCursorImpl
no_change:
jsr get_and_return_event
2018-11-18 04:34:17 +00:00
cmp #MGTK::EventKind::button_up
beq drag_done
jsr check_if_changed
beq no_change
2018-01-29 08:57:55 +00:00
jsr HideCursorImpl
jsr frame_winrect
2017-10-15 04:15:35 +00:00
jsr top_window
jsr get_thumb_rect
ldx #0
lda #xthumb_width
bit which_control
bpl :+
ldx #2
lda #ythumb_height
: sta thumb_dim
lda winrect,x
2017-09-17 18:18:47 +00:00
clc
adc drag_delta,x
2017-09-17 18:18:47 +00:00
tay
lda winrect+1,x
adc drag_delta+1,x
cmp ctl_bound1+1
bcc :+
bne in_bound1
cpy ctl_bound1
bcs in_bound1
: lda ctl_bound1+1
ldy ctl_bound1
in_bound1:
cmp ctl_bound2+1
bcc in_bound2
bne :+
cpy ctl_bound2
bcc in_bound2
: lda ctl_bound2+1
ldy ctl_bound2
in_bound2:
sta winrect+1,x
2017-09-17 18:18:47 +00:00
tya
sta winrect,x
2017-09-17 18:18:47 +00:00
clc
adc thumb_dim
sta winrect::x2,x
lda winrect+1,x
adc #0
sta winrect::x2+1,x
jmp drag_loop
2017-09-17 18:18:47 +00:00
drag_done:
jsr HideCursorImpl
jsr frame_winrect
2018-04-02 15:00:43 +00:00
jsr show_cursor_and_restore
jsr set_up_thumb_division
jsr fixed_div
ldx fixed_div::quotient+2 ; 8.0 integral part
jsr get_thumb_vals
lda fixed_div::divisor
ldy #0
cpx #1
bcs :+
ldx fixed_div_quotient+1 ; 0.8 fractional part
jsr get_thumb_coord
: ldx #1
cmp fixed_div_quotient+2
bne :+
2017-09-17 18:18:47 +00:00
dex
: ldy #params::thumbpos - params
2018-02-28 02:38:18 +00:00
jmp store_xa_at_y
.endproc
2017-09-17 18:18:47 +00:00
;; Calculates the thumb coordinates given the maximum position
;; and current fraction.
;;
;; Inputs:
;; A,Y = maximum position of thumb in 16.0 format
;; X = fraction in fixed 0.8 format
;;
;; Outputs:
;; A,Y = current position of thumb in 16.0 format
;; (= maximum position * fraction)
;;
.proc get_thumb_coord
increment := $82
accum := $84
sta increment ; fixed 8.8 = max position/256
sty increment+1
lda #$80 ; fixed 8.8 = 1/2
sta accum
2017-09-17 18:18:47 +00:00
ldy #$00
sty accum+1
txa ; fixed 8.0 = fraction*256
beq ret
loop: add16 increment, accum, accum ; returning with A=high byte of accum
bcc :+
2017-09-17 18:18:47 +00:00
iny
: dex ; (accum low),A,Y is in fixed 16.8
bne loop ; return A,Y
ret: rts
.endproc
2017-09-17 18:18:47 +00:00
2017-10-06 01:36:20 +00:00
ctl_bound2:
.res 2
ctl_bound1:
.res 2
;; Set fixed_div::divisor and fixed_div::dividend up for the
;; proportion calculation for the control in which_control.
.proc set_up_thumb_division
sub16 ctl_bound2, ctl_bound1, fixed_div::divisor
ldx #0
bit which_control
bpl :+
ldx #2
: sub16 winrect,x, ctl_bound1, fixed_div::dividend
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
;; Set thumb_max and thumb_pos according to the control indicated
;; in which_control.
.proc get_thumb_vals
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::hthumbmax
bit which_control
bpl is_horiz
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::vthumbmax
is_horiz:
lda (window),y
sta thumb_max
2017-09-17 18:18:47 +00:00
iny
lda (window),y
sta thumb_pos
lda #0
sta thumb_pos+1
sta thumb_max+1
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc calc_ctl_bounds
offset := $82
ldx #0
lda #xthumb_width
bit which_control
bpl :+
ldx #2
lda #ythumb_height
:
sta offset
lda winrect::x1,x
ldy winrect::x1+1,x
sta ctl_bound1
sty ctl_bound1+1
lda winrect::x2,x
ldy winrect::x2+1,x
2017-09-17 18:18:47 +00:00
sec
sbc offset
bcs :+
2017-09-17 18:18:47 +00:00
dey
: sta ctl_bound2
sty ctl_bound2+1
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; UpdateThumb
2017-10-03 03:05:07 +00:00
2017-10-07 20:59:25 +00:00
;;; 3 bytes of params, copied to $8C
2018-03-02 02:25:42 +00:00
.proc UpdateThumbImpl
PARAM_BLOCK params, $8C
which_ctl: .byte 0
thumbpos: .byte 0
END_PARAM_BLOCK
lda which_control
2018-11-18 04:34:17 +00:00
cmp #MGTK::Ctl::vertical_scroll_bar
2018-03-02 02:25:42 +00:00
bne :+
lda #which_control_vert
sta which_control
2018-03-02 02:25:42 +00:00
bne check_win
2018-11-18 04:34:17 +00:00
: cmp #MGTK::Ctl::horizontal_scroll_bar
2018-03-02 02:25:42 +00:00
bne bad_ctl
lda #which_control_horiz
sta which_control
2018-03-02 02:25:42 +00:00
beq check_win
2017-09-17 18:18:47 +00:00
2018-03-02 02:25:42 +00:00
bad_ctl:
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::control_not_found
2018-03-02 02:25:42 +00:00
check_win:
jsr top_window
bne :+
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::no_active_window
2017-09-17 18:18:47 +00:00
2018-05-26 01:49:36 +00:00
: ldy #MGTK::Winfo::hthumbpos
bit which_control
2018-03-02 02:25:42 +00:00
bpl :+
2018-05-26 01:49:36 +00:00
ldy #MGTK::Winfo::vthumbpos
: lda params::thumbpos
sta (window),y
2018-04-02 15:00:43 +00:00
jsr hide_cursor_save_params
jsr set_standard_port
jsr draw_or_erase_scrollbar
2018-04-02 15:00:43 +00:00
jmp show_cursor_and_restore
2018-03-02 02:25:42 +00:00
.endproc
2017-10-03 02:48:21 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; KeyboardMouse
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 1 byte of params, copied to $82
.proc KeyboardMouse
2018-01-29 08:57:55 +00:00
lda #$80
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
2018-01-29 08:57:55 +00:00
jmp FlushEventsImpl
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-04 15:31:53 +00:00
;;; $4E SetMenuSelection
2017-10-07 03:59:09 +00:00
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $82
.proc SetMenuSelectionImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
menu_index: .res 1
menu_item_index: .res 1
END_PARAM_BLOCK
2018-03-24 02:43:22 +00:00
2018-04-28 23:22:33 +00:00
lda params::menu_index
2018-04-02 15:00:43 +00:00
sta sel_menu_index
2018-03-24 02:43:22 +00:00
2018-04-28 23:22:33 +00:00
lda params::menu_item_index
2018-04-02 15:00:43 +00:00
sta sel_menu_item_index
2018-03-24 02:43:22 +00:00
2017-09-17 18:18:47 +00:00
rts
2018-03-24 02:43:22 +00:00
.endproc
;;; ============================================================
;; Set to $80 by KeyboardMouse call; also set to $04,
;; $01 elsewhere.
kbd_mouse_state:
.byte 0
kbd_mouse_state_menu := 1
kbd_mouse_state_mousekeys := 4
2018-03-24 02:43:22 +00:00
kbd_mouse_x: .word 0
kbd_mouse_y: .word 0
2017-09-17 18:18:47 +00:00
kbd_menu_select_flag:
.byte 0
2018-03-24 02:43:22 +00:00
;; Currently selected menu/menu item. Note that menu is index,
;; not ID from menu definition.
2018-04-02 15:00:43 +00:00
sel_menu_index:
2018-03-24 02:43:22 +00:00
.byte 0
2018-04-02 15:00:43 +00:00
sel_menu_item_index:
2018-03-24 02:43:22 +00:00
.byte 0
2018-03-24 04:27:58 +00:00
saved_mouse_pos:
saved_mouse_x: .word 0
saved_mouse_y: .byte 0
2018-03-24 02:43:22 +00:00
kbd_menu: .byte $00
kbd_menu_item: .byte $00
movement_cancel: .byte $00
kbd_mouse_status: .byte $00
2018-03-24 02:43:22 +00:00
.proc kbd_mouse_save_zp
COPY_BYTES $80, $80, kbd_mouse_zp_stash
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_mouse_restore_zp
COPY_BYTES $80, kbd_mouse_zp_stash,$80
2017-09-17 18:18:47 +00:00
rts
.endproc
kbd_mouse_zp_stash:
.res 128
2017-09-17 18:18:47 +00:00
2017-10-05 03:41:08 +00:00
2018-03-24 02:43:22 +00:00
;;; ============================================================
;;; X = xlo, Y = xhi, A = y
.proc set_mouse_pos
bit mouse_hooked_flag
bmi no_firmware
2017-10-07 22:07:12 +00:00
bit no_mouse_flag
2018-03-24 02:43:22 +00:00
bmi no_firmware
2017-09-17 18:18:47 +00:00
pha
txa
sec
jsr scale_mouse_coord
2017-10-07 22:07:12 +00:00
ldx mouse_firmware_hi
sta MOUSE_X_LO,x
2017-09-17 18:18:47 +00:00
tya
sta MOUSE_X_HI,x
2017-09-17 18:18:47 +00:00
pla
ldy #$00
clc
jsr scale_mouse_coord
2017-10-07 22:07:12 +00:00
ldx mouse_firmware_hi
sta MOUSE_Y_LO,x
2017-09-17 18:18:47 +00:00
tya
sta MOUSE_Y_HI,x
ldy #POSMOUSE
2017-10-07 22:07:12 +00:00
jmp call_mouse
2017-09-17 18:18:47 +00:00
2018-03-24 02:43:22 +00:00
no_firmware:
stx mouse_x
sty mouse_x+1
sta mouse_y
bit mouse_hooked_flag
2018-03-24 02:43:22 +00:00
bpl not_hooked
ldy #POSMOUSE
2017-10-07 22:07:12 +00:00
jmp call_mouse
2017-09-17 18:18:47 +00:00
2018-03-24 02:43:22 +00:00
not_hooked:
rts
.endproc
;;; ============================================================
2017-09-17 18:18:47 +00:00
2018-03-24 04:27:58 +00:00
.proc restore_mouse_pos
ldx saved_mouse_x
ldy saved_mouse_x+1
lda saved_mouse_y
2018-03-24 02:43:22 +00:00
jmp set_mouse_pos
2018-03-24 04:27:58 +00:00
.endproc
2017-09-17 18:18:47 +00:00
2018-03-24 04:27:58 +00:00
.proc set_mouse_pos_from_kbd_mouse
2018-03-24 02:43:22 +00:00
ldx kbd_mouse_x
ldy kbd_mouse_x+1
lda kbd_mouse_y
jmp set_mouse_pos
2018-03-24 04:27:58 +00:00
.endproc
2017-09-17 18:18:47 +00:00
.proc scale_mouse_coord
bcc scale_y
2018-03-24 04:27:58 +00:00
ldx mouse_scale_x
bne :+
ret: rts
2017-09-17 18:18:47 +00:00
scale_y:
ldx mouse_scale_y
beq ret
: pha
2017-09-17 18:18:47 +00:00
tya
lsr a
tay
pla
ror a
dex
bne :-
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_mouse_to_mouse
COPY_BYTES 3, kbd_mouse_x, mouse_x
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc position_kbd_mouse
jsr kbd_mouse_to_mouse
2018-03-24 02:43:22 +00:00
jmp set_mouse_pos_from_kbd_mouse
.endproc
2017-09-17 18:18:47 +00:00
2018-03-24 04:27:58 +00:00
.proc save_mouse_pos
jsr read_mouse_pos
COPY_BYTES 3, mouse_x, saved_mouse_pos
2017-09-17 18:18:47 +00:00
rts
2018-03-24 04:27:58 +00:00
.endproc
2017-09-17 18:18:47 +00:00
.proc restore_cursor
jsr stash_addr
copy16 kbd_mouse_cursor_stash, params_addr
2018-01-29 08:57:55 +00:00
jsr SetCursorImpl
2018-02-28 02:38:18 +00:00
jsr restore_addr
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
2017-09-17 18:18:47 +00:00
lda #$40
sta mouse_status
2018-03-24 04:27:58 +00:00
jmp restore_mouse_pos
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_mouse_init_tracking
lda #0
sta movement_cancel
sta force_tracking_change
2017-09-17 18:18:47 +00:00
rts
2018-04-02 15:00:43 +00:00
.endproc
2017-09-17 18:18:47 +00:00
;; Look at buttons (apple keys), compute modifiers in A
;; (bit 0 = button 0 / open apple, bit 1 = button 1 / solid apple)
.proc compute_modifiers
lda BUTN1
2017-09-17 18:18:47 +00:00
asl a
lda BUTN0
2017-09-17 18:18:47 +00:00
and #$80
rol a
rol a
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc get_key
jsr compute_modifiers
2018-02-28 02:38:18 +00:00
sta set_input_modifiers
no_modifiers:
clc
lda KBD
bpl :+
stx KBDSTRB
and #CHAR_MASK
2017-09-17 18:18:47 +00:00
sec
: rts
.endproc
2017-09-17 18:18:47 +00:00
.proc handle_keyboard_mouse
lda kbd_mouse_state
bne :+
2017-09-17 18:18:47 +00:00
rts
: cmp #kbd_mouse_state_mousekeys
beq kbd_mouse_mousekeys
jsr kbd_mouse_sync_cursor
2018-03-24 02:43:22 +00:00
lda kbd_mouse_state
cmp #kbd_mouse_state_menu
bne :+
jmp kbd_mouse_do_menu
2017-09-17 18:18:47 +00:00
: jmp kbd_mouse_do_window
.endproc
2017-09-17 18:18:47 +00:00
.proc stash_cursor
jsr stash_addr
copy16 active_cursor, kbd_mouse_cursor_stash
copy16 pointer_cursor_addr, params_addr
2018-01-29 08:57:55 +00:00
jsr SetCursorImpl
2018-02-28 02:38:18 +00:00
jmp restore_addr
.endproc
2017-09-17 18:18:47 +00:00
kbd_mouse_cursor_stash:
.res 2
2017-10-07 20:59:25 +00:00
2018-02-28 02:38:18 +00:00
stash_addr:
2018-03-26 03:18:43 +00:00
copy16 params_addr, stashed_addr
2017-09-17 18:18:47 +00:00
rts
2018-02-28 02:38:18 +00:00
restore_addr:
2018-03-26 03:18:43 +00:00
copy16 stashed_addr, params_addr
2017-09-17 18:18:47 +00:00
rts
2018-02-28 02:38:18 +00:00
stashed_addr: .addr 0
2017-10-07 20:59:25 +00:00
.proc kbd_mouse_mousekeys
jsr compute_modifiers ; C=_ A=____ __SO
ror a ; C=O A=____ ___S
ror a ; C=S A=O___ ____
ror kbd_mouse_status ; shift solid apple into bit 7 of kbd_mouse_status
lda kbd_mouse_status ; becomes mouse button
sta mouse_status
lda #0
sta input::modifiers
2017-09-30 02:14:47 +00:00
jsr get_key::no_modifiers
bcc :+
jmp mousekeys_input
: jmp position_kbd_mouse
.endproc
2017-09-17 18:18:47 +00:00
.proc activate_keyboard_mouse
pha ; save modifiers
2018-03-24 02:43:22 +00:00
lda kbd_mouse_state
bne in_kbd_mouse ; branch away if keyboard mouse is active
2017-09-17 18:18:47 +00:00
pla
cmp #3 ; open apple+solid apple
bne ret
bit mouse_status
bmi ret ; branch away if button is down
lda #4
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
ldx #10
beeploop:
lda SPKR ; Beep
ldy #0
: dey
bne :-
2017-09-17 18:18:47 +00:00
dex
bpl beeploop
waitloop:
jsr compute_modifiers
cmp #3
beq waitloop ; wait for user to release OA+SA
sta input::modifiers
lda #0
sta kbd_mouse_status ; reset mouse button status
COPY_BYTES 3, set_pos_params, kbd_mouse_x
ret: rts
2017-09-17 18:18:47 +00:00
in_kbd_mouse:
cmp #kbd_mouse_state_mousekeys
bne pla_ret
2017-09-17 18:18:47 +00:00
pla
and #1 ; modifiers
bne :+
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
: rts
2017-09-17 18:18:47 +00:00
pla_ret:
pla
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_mouse_sync_cursor
bit mouse_status
bpl :+
2018-03-24 02:43:22 +00:00
lda #0
sta kbd_mouse_state
jmp set_mouse_pos_from_kbd_mouse
2017-09-17 18:18:47 +00:00
: lda mouse_status
2017-09-17 18:18:47 +00:00
pha
lda #$C0
sta mouse_status
2017-09-17 18:18:47 +00:00
pla
and #$20
beq kbd_mouse_to_mouse_jmp
COPY_BYTES 3, mouse_x, kbd_mouse_x
stx kbd_menu_select_flag ; =$ff
2017-09-17 18:18:47 +00:00
rts
kbd_mouse_to_mouse_jmp:
jmp kbd_mouse_to_mouse
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_menu_select
php
2017-09-17 18:18:47 +00:00
sei
2018-03-24 04:27:58 +00:00
jsr save_mouse_pos
lda #kbd_mouse_state_menu
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
jsr position_menu_item
2017-09-17 18:18:47 +00:00
lda #$80
sta mouse_status
jsr stash_cursor
2018-04-02 15:00:43 +00:00
ldx sel_menu_index
jsr get_menu
lda curmenu::menu_id
2018-04-02 15:00:43 +00:00
sta cur_open_menu
jsr draw_menu
2018-04-02 15:00:43 +00:00
lda sel_menu_item_index
sta cur_hilited_menu_item
jsr hilite_menu_item
2017-09-17 18:18:47 +00:00
plp
rts
position_menu_item:
ldx sel_menu_index
2018-04-02 15:00:43 +00:00
jsr get_menu
2018-03-24 02:43:22 +00:00
add16lc curmenu::x_min, #5, kbd_mouse_x
2018-03-24 02:43:22 +00:00
2018-04-02 15:00:43 +00:00
ldy sel_menu_item_index
2017-12-16 05:36:09 +00:00
lda menu_item_y_table,y
2018-03-24 02:43:22 +00:00
sta kbd_mouse_y
2017-09-17 18:18:47 +00:00
lda #$C0
sta mouse_status
jmp position_kbd_mouse
.endproc
.proc kbd_menu_select_item
bit kbd_menu_select_flag
bpl :+
2017-09-17 18:18:47 +00:00
2018-04-02 15:00:43 +00:00
lda cur_hilited_menu_item
sta sel_menu_item_index
ldx cur_open_menu
2017-09-17 18:18:47 +00:00
dex
2018-04-02 15:00:43 +00:00
stx sel_menu_index
2017-09-17 18:18:47 +00:00
lda #0
sta kbd_menu_select_flag
: rts
.endproc
.proc kbd_mouse_do_menu
jsr kbd_mouse_save_zp
jsr :+
jmp kbd_mouse_restore_zp
2017-09-17 18:18:47 +00:00
: jsr get_key
2017-10-09 04:02:57 +00:00
bcs handle_menu_key
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-10-09 04:02:57 +00:00
;; Keyboard navigation of menu
.proc handle_menu_key
pha
jsr kbd_menu_select_item
2017-09-17 18:18:47 +00:00
pla
2018-02-27 04:13:18 +00:00
cmp #CHAR_ESCAPE
2017-10-09 04:02:57 +00:00
bne try_return
2017-10-08 03:22:39 +00:00
lda #0
sta kbd_menu_item
sta kbd_menu
2017-09-17 18:18:47 +00:00
lda #$80
sta movement_cancel
2017-09-17 18:18:47 +00:00
rts
2017-10-09 04:02:57 +00:00
try_return:
2018-02-27 04:13:18 +00:00
cmp #CHAR_RETURN
2017-10-09 04:02:57 +00:00
bne try_up
jsr kbd_mouse_to_mouse
jmp restore_cursor
2017-09-17 18:18:47 +00:00
2017-10-09 04:02:57 +00:00
try_up:
2018-02-27 04:13:18 +00:00
cmp #CHAR_UP
2017-10-09 04:02:57 +00:00
bne try_down
uploop: dec sel_menu_item_index
bpl :+
2018-04-02 15:00:43 +00:00
ldx sel_menu_index
jsr get_menu
ldx menu_item_count
2018-04-02 15:00:43 +00:00
stx sel_menu_item_index
: ldx sel_menu_item_index
beq :+
2017-09-17 18:18:47 +00:00
dex
2018-04-02 15:00:43 +00:00
jsr get_menu_item
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
bne uploop
: jmp kbd_menu_select::position_menu_item
2017-09-17 18:18:47 +00:00
2017-10-09 04:02:57 +00:00
try_down:
2018-02-27 04:13:18 +00:00
cmp #CHAR_DOWN
2017-10-09 04:02:57 +00:00
bne try_right
downloop:
inc sel_menu_item_index
2018-04-02 15:00:43 +00:00
ldx sel_menu_index
jsr get_menu
lda sel_menu_item_index
cmp menu_item_count
bcc :+
beq :+
2017-10-08 03:22:39 +00:00
lda #0
2018-04-02 15:00:43 +00:00
sta sel_menu_item_index
: ldx sel_menu_item_index
beq :+
2017-09-17 18:18:47 +00:00
dex
2018-04-02 15:00:43 +00:00
jsr get_menu_item
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
bne downloop
: jmp kbd_menu_select::position_menu_item
2017-09-17 18:18:47 +00:00
2017-10-09 04:02:57 +00:00
try_right:
2018-02-27 04:13:18 +00:00
cmp #CHAR_RIGHT
2017-10-09 04:02:57 +00:00
bne try_left
2017-10-08 03:22:39 +00:00
lda #0
2018-04-02 15:00:43 +00:00
sta sel_menu_item_index
inc sel_menu_index
2018-04-02 15:00:43 +00:00
lda sel_menu_index
cmp menu_count
bcc :+
lda #0
2018-04-02 15:00:43 +00:00
sta sel_menu_index
: jmp kbd_menu_select::position_menu_item
2017-09-17 18:18:47 +00:00
2017-10-09 04:02:57 +00:00
try_left:
2018-02-27 04:13:18 +00:00
cmp #CHAR_LEFT
2017-10-09 04:02:57 +00:00
bne nope
2017-10-08 03:22:39 +00:00
lda #0
2018-04-02 15:00:43 +00:00
sta sel_menu_item_index
dec sel_menu_index
bmi :+
jmp kbd_menu_select::position_menu_item
2017-09-17 18:18:47 +00:00
: ldx menu_count
2017-09-17 18:18:47 +00:00
dex
2018-04-02 15:00:43 +00:00
stx sel_menu_index
jmp kbd_menu_select::position_menu_item
nope: jsr kbd_menu_by_shortcut
bcc :+
2017-09-17 18:18:47 +00:00
lda #$80
sta movement_cancel
: rts
2017-10-09 04:02:57 +00:00
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_menu_by_shortcut
sta find_shortcut
2018-02-28 02:38:18 +00:00
lda set_input_modifiers
and #3
sta find_options
2018-04-02 15:00:43 +00:00
lda cur_open_menu
2017-09-17 18:18:47 +00:00
pha
2018-04-02 15:00:43 +00:00
lda cur_hilited_menu_item
2017-09-17 18:18:47 +00:00
pha
lda #find_mode_by_shortcut
2018-04-02 15:00:43 +00:00
jsr find_menu
beq fail
stx kbd_menu_item
lda curmenu::disabled
bmi fail
lda curmenuitem::options
2018-11-18 04:34:17 +00:00
and #MGTK::MenuOpt::disable_flag | MGTK::MenuOpt::item_is_filler
bne fail
lda curmenu::menu_id
sta kbd_menu
2017-09-17 18:18:47 +00:00
sec
bcs :+
fail: clc
: pla
2018-04-02 15:00:43 +00:00
sta cur_hilited_menu_item
2017-09-17 18:18:47 +00:00
pla
2018-04-02 15:00:43 +00:00
sta cur_open_menu
sta find_menu_id
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_menu_return
php
2017-09-17 18:18:47 +00:00
sei
2018-04-02 15:00:43 +00:00
jsr hide_menu
jsr restore_cursor
lda kbd_menu
sta MenuSelectImpl::params::menu_id
2018-04-02 15:00:43 +00:00
sta cur_open_menu
lda kbd_menu_item
sta MenuSelectImpl::params::menu_item
2018-04-02 15:00:43 +00:00
sta cur_hilited_menu_item
jsr restore_params_active_port
lda kbd_menu
beq :+
2018-01-29 08:57:55 +00:00
jsr HiliteMenuImpl
lda kbd_menu
: sta cur_open_menu
ldx kbd_menu_item
2018-04-02 15:00:43 +00:00
stx cur_hilited_menu_item
2017-09-17 18:18:47 +00:00
plp
jmp store_xa_at_params
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_win_drag_or_grow
php
2017-09-17 18:18:47 +00:00
sei
2018-03-24 04:27:58 +00:00
jsr save_mouse_pos
2017-09-17 18:18:47 +00:00
lda #$80
sta mouse_status
jsr get_winframerect
2017-12-16 05:36:09 +00:00
bit drag_resize_flag
bpl do_drag
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::grow_box
beq no_grow
ldx #0
: sec
lda winrect::x2,x
sbc #4
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x,x
sta drag_initialpos,x
sta drag_curpos,x
lda winrect::x2+1,x
sbc #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x+1,x
sta drag_initialpos+1,x
sta drag_curpos+1,x
2017-09-17 18:18:47 +00:00
inx
inx
cpx #4
bcc :-
2017-09-17 18:18:47 +00:00
sec
2018-03-02 02:25:42 +00:00
lda #<(screen_width-1)
sbc drag_initialpos::xcoord
2018-03-02 02:25:42 +00:00
lda #>(screen_width-1)
sbc drag_initialpos::xcoord+1
bmi no_grow
2017-09-17 18:18:47 +00:00
sec
2018-03-02 02:25:42 +00:00
lda #<(screen_height-1)
sbc drag_initialpos::ycoord
2018-03-02 02:25:42 +00:00
lda #>(screen_height-1)
sbc drag_initialpos::ycoord+1
bmi no_grow
jsr position_kbd_mouse
jsr stash_cursor
2017-09-17 18:18:47 +00:00
plp
rts
no_grow:
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
2018-11-18 04:34:17 +00:00
lda #MGTK::Error::window_not_resizable
2017-09-17 18:18:47 +00:00
plp
2018-01-29 08:57:55 +00:00
jmp exit_with_a
2017-09-17 18:18:47 +00:00
do_drag:
lda current_winfo::options
2018-11-18 04:34:17 +00:00
and #MGTK::Option::dialog_box
beq no_dialog
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_state
2018-11-18 04:34:17 +00:00
exit_call MGTK::Error::window_not_draggable
2017-09-17 18:18:47 +00:00
no_dialog:
ldx #0
dragloop:
clc
lda winrect::x1,x
cpx #2
beq is_y
2017-09-17 18:18:47 +00:00
adc #$23
jmp :+
2017-09-17 18:18:47 +00:00
is_y: adc #5
: sta kbd_mouse_x,x
sta drag_initialpos,x
sta drag_curpos,x
lda winrect::x1+1,x
adc #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x+1,x
sta drag_initialpos+1,x
sta drag_curpos+1,x
2017-09-17 18:18:47 +00:00
inx
inx
cpx #4
bcc dragloop
2018-03-24 02:43:22 +00:00
bit kbd_mouse_x+1
bpl xpositive
ldx #1
lda #0
: sta kbd_mouse_x,x
sta drag_initialpos,x
sta drag_curpos,x
2017-09-17 18:18:47 +00:00
dex
bpl :-
xpositive:
jsr position_kbd_mouse
jsr stash_cursor
2017-09-17 18:18:47 +00:00
plp
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc kbd_mouse_add_to_y
php
2017-09-17 18:18:47 +00:00
clc
2018-03-24 02:43:22 +00:00
adc kbd_mouse_y
sta kbd_mouse_y
2017-09-17 18:18:47 +00:00
plp
bpl yclamp
cmp #<screen_height
bcc :+
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_y
: jmp position_kbd_mouse
2017-09-17 18:18:47 +00:00
yclamp: cmp #<screen_height
bcc :-
lda #<(screen_height-1)
2018-03-24 02:43:22 +00:00
sta kbd_mouse_y
bne :- ; always
.endproc
.proc kbd_mouse_do_window
jsr kbd_mouse_save_zp
jsr :+
jmp kbd_mouse_restore_zp
2017-09-17 18:18:47 +00:00
: jsr get_key
bcs :+
2017-09-17 18:18:47 +00:00
rts
: cmp #CHAR_ESCAPE
bne :+
2017-09-17 18:18:47 +00:00
lda #$80
sta movement_cancel
jmp restore_cursor
2017-09-17 18:18:47 +00:00
: cmp #CHAR_RETURN
bne :+
jmp restore_cursor
2017-09-17 18:18:47 +00:00
: pha
2018-02-28 02:38:18 +00:00
lda set_input_modifiers
beq :+
2017-09-17 18:18:47 +00:00
ora #$80
2018-02-28 02:38:18 +00:00
sta set_input_modifiers
: pla
2017-09-17 18:18:47 +00:00
ldx #$C0
stx mouse_status
;; Fall-through
.endproc
.proc mousekeys_input
cmp #CHAR_UP
bne not_up
lda #256-8
2018-02-28 02:38:18 +00:00
bit set_input_modifiers
bpl :+
lda #256-48
: jmp kbd_mouse_add_to_y
not_up:
cmp #CHAR_DOWN
bne not_down
2017-09-17 18:18:47 +00:00
lda #8
2018-02-28 02:38:18 +00:00
bit set_input_modifiers
bpl :+
lda #48
: jmp kbd_mouse_add_to_y
not_down:
cmp #CHAR_RIGHT
bne not_right
jsr kbd_mouse_check_xmax
bcc out_of_bounds
2017-09-17 18:18:47 +00:00
clc
lda #8
2018-02-28 02:38:18 +00:00
bit set_input_modifiers
bpl :+
lda #64
: adc kbd_mouse_x
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x
lda kbd_mouse_x+1
adc #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x+1
2017-09-17 18:18:47 +00:00
sec
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x
sbc #<(screen_width-1)
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x+1
sbc #>(screen_width-1)
bmi out_of_bounds
lda #>(screen_width-1)
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x+1
lda #<(screen_width-1)
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x
out_of_bounds:
jmp position_kbd_mouse
not_right:
cmp #CHAR_LEFT
bne not_left
jsr kbd_mouse_check_xmin
bcc out_of_boundsl
2017-09-17 18:18:47 +00:00
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x
2018-02-28 02:38:18 +00:00
bit set_input_modifiers
bpl :+
sbc #64
jmp move_left
2017-09-17 18:18:47 +00:00
: sbc #8
move_left:
sta kbd_mouse_x
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x+1
sbc #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x+1
bpl out_of_boundsl
lda #0
2018-03-24 02:43:22 +00:00
sta kbd_mouse_x
sta kbd_mouse_x+1
out_of_boundsl:
jmp position_kbd_mouse
not_left:
sta set_input_key
2017-09-17 18:18:47 +00:00
COPY_STRUCT MGTK::GrafPort, $A7, $0600
2018-02-28 02:38:18 +00:00
lda set_input_key
jsr kbd_menu_by_shortcut
2017-09-17 18:18:47 +00:00
php
COPY_STRUCT MGTK::GrafPort, $0600, $A7
2017-09-17 18:18:47 +00:00
plp
bcc :+
2017-09-17 18:18:47 +00:00
lda #$40
sta movement_cancel
jmp restore_cursor
: rts
.endproc
2017-09-17 18:18:47 +00:00
.proc set_input
MGTK_CALL MGTK::PostEvent, set_input_params
2017-09-17 18:18:47 +00:00
rts
.endproc
2017-09-17 18:18:47 +00:00
.proc set_input_params ; 1 byte shorter than normal, since KEY
2018-11-18 04:34:17 +00:00
state: .byte MGTK::EventKind::key_down
key: .byte 0
modifiers:
.byte 0
.endproc
2018-02-28 02:38:18 +00:00
set_input_key := set_input_params::key
set_input_modifiers := set_input_params::modifiers
;; Set to true to force the return value of check_if_changed to true
;; during a tracking operation.
force_tracking_change:
.byte 0
.proc kbd_mouse_check_xmin
lda kbd_mouse_state
cmp #kbd_mouse_state_mousekeys
beq ret_ok
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x
bne ret_ok
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x+1
bne ret_ok
2017-12-16 05:36:09 +00:00
bit drag_resize_flag
bpl :+
ret_ok: sec
2017-09-17 18:18:47 +00:00
rts
: jsr get_winframerect
lda winrect::x2+1
bne min_ok
lda #9
2017-10-06 01:36:20 +00:00
bit set_input_params::modifiers
bpl :+
lda #65
: cmp winrect::x2
bcc min_ok
2017-09-17 18:18:47 +00:00
clc
rts
min_ok: inc force_tracking_change
2017-09-17 18:18:47 +00:00
clc
lda #8
2017-10-06 01:36:20 +00:00
bit set_input_params::modifiers
bpl :+
lda #64
: adc drag_initialpos
sta drag_initialpos
bcc :+
inc drag_initialpos+1
: clc
2017-09-17 18:18:47 +00:00
rts
.endproc
.proc kbd_mouse_check_xmax
lda kbd_mouse_state
cmp #kbd_mouse_state_mousekeys
beq :+
2017-09-17 18:18:47 +00:00
2017-12-16 05:36:09 +00:00
bit drag_resize_flag
bmi :+
2018-03-26 04:04:15 +00:00
lda kbd_mouse_x
sbc #<(screen_width-1)
2018-03-24 02:43:22 +00:00
lda kbd_mouse_x+1
2018-03-26 04:04:15 +00:00
sbc #>(screen_width-1)
beq is_max
2017-09-17 18:18:47 +00:00
sec
: sec
2017-09-17 18:18:47 +00:00
rts
is_max: jsr get_winframerect
2017-09-17 18:18:47 +00:00
sec
lda #<(screen_width-1)
sbc winrect::x1
2017-09-17 18:18:47 +00:00
tax
lda #>(screen_width-1)
sbc winrect::x1+1
beq :+
ldx #256-1
: bit set_input_modifiers
bpl :+
cpx #100
bcc clc_rts
bcs ge_100
: cpx #44
bcc clc_rts
bcs in_range
clc_rts:
clc
2017-09-17 18:18:47 +00:00
rts
ge_100: sec
lda drag_initialpos
sbc #64
jmp :+
2017-09-17 18:18:47 +00:00
in_range:
sec
lda drag_initialpos
sbc #8
: sta drag_initialpos
bcs :+
dec drag_initialpos+1
:
inc force_tracking_change
2017-09-17 18:18:47 +00:00
clc
rts
.endproc
2017-09-17 18:18:47 +00:00
grew_flag:
.byte 0
.proc set_grew_flag
lda #$80
sta grew_flag
grts: rts
.endproc
.proc finish_grow
bit kbd_mouse_state
bpl set_grew_flag::grts
bit grew_flag
bpl set_grew_flag::grts
jsr get_winframerect
2017-09-17 18:18:47 +00:00
php
sei
ldx #0
: sub16lc winrect::x2,x, #4, kbd_mouse_x,x
2017-09-17 18:18:47 +00:00
inx
inx
cpx #4
bcc :-
jsr position_kbd_mouse
2017-09-17 18:18:47 +00:00
plp
rts
.endproc
2017-09-17 18:18:47 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2018-01-29 08:57:55 +00:00
;;; ScaleMouse
2017-10-07 03:59:09 +00:00
;;; Sets up mouse clamping
2017-10-07 20:59:25 +00:00
;;; 2 bytes of params, copied to $82
;;; byte 1 controls x clamp, 2 controls y clamp
;;; clamp is to fractions of screen (0 = full, 1 = 1/2, 2 = 1/4, 3 = 1/8) (why???)
2017-10-07 20:59:25 +00:00
2018-01-29 08:57:55 +00:00
.proc ScaleMouseImpl
2018-04-28 23:22:33 +00:00
PARAM_BLOCK params, $82
x_exponent: .res 1
y_exponent: .res 1
END_PARAM_BLOCK
lda params::x_exponent
2018-03-24 04:27:58 +00:00
sta mouse_scale_x
2018-04-28 23:22:33 +00:00
lda params::y_exponent
2018-03-24 04:27:58 +00:00
sta mouse_scale_y
set_clamps:
bit no_mouse_flag ; called after INITMOUSE
bmi end
2018-03-24 04:27:58 +00:00
lda mouse_scale_x
2017-09-17 18:18:47 +00:00
asl a
tay
lda #0
sta mouse_x
sta mouse_x+1
bit mouse_hooked_flag
bmi :+
sta CLAMP_MIN_LO
sta CLAMP_MIN_HI
: lda clamp_x_table,y
sta mouse_y
bit mouse_hooked_flag
bmi :+
sta CLAMP_MAX_LO
: lda clamp_x_table+1,y
sta mouse_y+1
bit mouse_hooked_flag
bmi :+
sta CLAMP_MAX_HI
: lda #CLAMP_X
ldy #CLAMPMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
2018-03-24 04:27:58 +00:00
lda mouse_scale_y
2017-09-17 18:18:47 +00:00
asl a
tay
lda #0
sta mouse_x
sta mouse_x+1
bit mouse_hooked_flag
bmi :+
sta CLAMP_MIN_LO
sta CLAMP_MIN_HI
: lda clamp_y_table,y
sta mouse_y
bit mouse_hooked_flag
bmi :+
sta CLAMP_MAX_LO
: lda clamp_y_table+1,y
sta mouse_y+1
bit mouse_hooked_flag
bmi :+
sta CLAMP_MAX_HI
: lda #CLAMP_Y
ldy #CLAMPMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
end: rts
2017-09-17 18:18:47 +00:00
2018-03-02 02:25:42 +00:00
clamp_x_table: .word screen_width-1, screen_width/2-1, screen_width/4-1, screen_width/8-1
clamp_y_table: .word screen_height-1, screen_height/2-1, screen_height/4-1, screen_height/8-1
.endproc
2017-10-03 03:46:01 +00:00
2018-03-05 05:36:00 +00:00
;;; ============================================================
2017-10-07 22:07:12 +00:00
;;; Locate Mouse Slot
;; If X's high bit is set, only slot in low bits is tested.
;; Otherwise all slots are scanned.
.proc find_mouse
txa
2017-09-17 18:18:47 +00:00
and #$7F
2017-10-07 22:07:12 +00:00
beq scan
jsr check_mouse_in_a
sta no_mouse_flag
beq found
ldx #0
2017-09-17 18:18:47 +00:00
rts
2017-10-07 22:07:12 +00:00
;; Scan for mouse starting at slot 7
scan: ldx #7
loop: txa
jsr check_mouse_in_a
sta no_mouse_flag
beq found
2017-09-17 18:18:47 +00:00
dex
2017-10-07 22:07:12 +00:00
bpl loop
ldx #0 ; no mouse found
2017-09-17 18:18:47 +00:00
rts
found: ldy #INITMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
jsr ScaleMouseImpl::set_clamps
ldy #HOMEMOUSE
2017-10-07 22:07:12 +00:00
jsr call_mouse
lda mouse_firmware_hi
2017-09-17 18:18:47 +00:00
and #$0F
2017-10-07 22:07:12 +00:00
tax ; return with mouse slot in X
2017-09-17 18:18:47 +00:00
rts
2017-10-07 22:07:12 +00:00
;; Check for mouse in slot A
.proc check_mouse_in_a
ptr := $88
ora #>$C000
sta ptr+1
lda #<$0000
sta ptr
ldy #$0C ; $Cn0C = $20
lda (ptr),y
2017-09-17 18:18:47 +00:00
cmp #$20
2017-10-07 22:07:12 +00:00
bne nope
ldy #$FB ; $CnFB = $D6
lda (ptr),y
2017-09-17 18:18:47 +00:00
cmp #$D6
2017-10-07 22:07:12 +00:00
bne nope
lda ptr+1 ; yay, found it!
sta mouse_firmware_hi
2017-09-17 18:18:47 +00:00
asl a
asl a
asl a
asl a
2017-10-07 22:07:12 +00:00
sta mouse_operand
2018-03-22 02:29:14 +00:00
return #$00
2017-09-17 18:18:47 +00:00
2018-03-22 02:29:14 +00:00
nope: return #$80
2017-10-07 22:07:12 +00:00
.endproc
.endproc
no_mouse_flag: ; high bit set if no mouse present
.byte 0
mouse_firmware_hi: ; e.g. if mouse is in slot 4, this is $C4
.byte 0
mouse_operand: ; e.g. if mouse is in slot 4, this is $40
.byte 0
2018-01-29 05:18:00 +00:00
.endproc ; mgtk
;;; ============================================================
;; Room for future expansion
PAD_TO $8580