Files
a2d/mgtk.inc
2018-05-25 18:39:43 -07:00

814 lines
24 KiB
PHP

;;; ============================================================
;;; MouseGraphics ToolKit (w/ Graphics Primitives)
;;; ============================================================
.scope MGTK
MLI := $4000
;; MLI-style call (jsr MLI ; .byte call ; .addr params)
;; Call from AUX (RAMRDON/RAMWRTON)
;;; ============================================================
;;; Graphics Primitives
;;; ============================================================
;;; Point record:
;;;
;;; .word xcoord
;;; .word ycoord
;;; Rect record:
;;;
;;; .word x1
;;; .word y1
;;; .word x2
;;; .word y2
;;; MapInfo record:
;;;
;;; Point viewloc
;;; .addr mapbits screen_mapbits
;;; .byte mapwidth screen_mapwidth
;;; .byte reserved
;;; Rect maprect a.k.a. cliprect
;;; GrafPort record:
;;;
;;; MapInfo portmap
;;; .res 8 penpattern
;;; .byte colormask_and
;;; .byte colormask_or
;;; Point penloc
;;; .byte penwidth horizontal pen thickness
;;; .byte penheight vertical pen thickness
;;; .byte penmode
;;; .byte textback text background
;;; .addr textfont
;;; PolyList record:
;;; .byte count number of vertices in this polygon
;;; .byte last high bit set if there are more polygons
;;; Point vertex1
;;; Point vertex2
;;; ...
;;; Font record:
;;;
;;; .byte fonttype 0=regular, $80=double-width
;;; .byte lastchar char code of last character (usually $7F)
;;; .byte height pixels (1-16)
;;; .res N charwidth pixels, for each char
;;; .res N row0 bits
;;; .res N row0right bits (double-width only)
;;; ...
NoOp := $00 ; No-op
;;; (no parameters)
;;; --------------------------------------------------
;;; Initialization Commands
InitGraf := $01
;;; (no parameters)
SetSwitches := $02 ; Configure display switches
;;; .byte flags bit 0=hires, 1=page2, 2=mixed, 3=text
;;; --------------------------------------------------
;;; GrafPort Commands
InitPort := $03 ; Initialize GrafPort to standard values
;;; (input is address of GrafPort record)
SetPort := $04 ; Set current port as specified
;;; (input is address of GrafPort record)
GetPort := $05 ; Get pointer to current port
;;; .addr port (out)
SetPortBits := $06 ; Set just the mapinfo (viewloc, mapbits)
;;; (input is address of MapInfo record)
SetPenMode := $07 ; Set the current pen mode
;;; .byte mode pen*/notpen*
SetPattern := $08 ; Set the current pattern
;;; .res 8 pattern 8x8 pixel pattern for PaintRect calls
SetColorMasks := $09 ; Set the current color masks
;;; .byte and_mask
;;; .byte or_mask
SetPenSize := $0A ; Set the current pen size
;;; .byte penwidth horizontal pen thickness
;;; .byte penheight vertical pen thickness
SetFont := $0B ; Set the current font
;;; .addr textfont font definition
SetTextBG := $0C ; Set the current text background
;;; .byte backcolor 0=black, $7F=white
;;; --------------------------------------------------
;;; Drawing Commands
Move := $0D ; Set current pen location (relative)
;;; .word xdelta
;;; .word ydelta
MoveTo := $0E ; Set current pen location (absolute)
;;; Point pos
Line := $0F ; Draw line from current pen location (relative)
;;; .word xdelta
;;; .word ydelta
LineTo := $10 ; Draw line from current pen location (absolute)
;;; Point pos
PaintRect := $11 ; Fill rectangle with selected simple pattern/thickness
;;; Rect rect
FrameRect := $12 ; Draw rectangle with selected simple pattern/thickness
;;; Rect rect
InRect := $13 ; Is current position in bounds? A=$80 true, 0 false
;;; Rect rect
PaintBits := $14 ; Draw pattern
;;; (input is address of MapInfo record)
PaintPoly := $15
;;; (input is address of PolyList record)
FramePoly := $16 ; Draw multiple closed polygons
;;; (input is address of PolyList record)
InPoly := $17 ; Is current position in bounds? A=$80 true, 0 false
;;; (input is address of PolyList record)
;;; --------------------------------------------------
;;; Text Commands
TextWidth := $18 ; Measure the width of a string in pixels
;;; .addr data
;;; .byte length
;;; .word width (out) result in pixels
DrawText := $19 ; Drawn at penpos as left, baseline
;;; .addr data
;;; .byte length
;;; --------------------------------------------------
;;; Utility Commands
SetZP1 := $1A ; Configure lower half of ZP usage by API (speed vs. convenience)
SetZP2 := $1B ; Configure upper half ZP usage by API (speed vs. convenience)
;;; .byte preserve 0=stash/no auto restore; 1=restore now and onward
Version := $1C ; Get toolkit version
;;; .byte (out) major
;;; .byte (out) minor
;;; .byte (out) patch
;;; .byte (out) status
;;; .word (out) number
;;; ============================================================
;;; MouseGraphics ToolKit Calls
;;; ============================================================
;;; --------------------------------------------------
;;; Initialization Calls
StartDeskTop := $1D ; Inits state, registers interrupt handler, draws desktop
;;; .byte machine ROM FBB3 ($06 = IIe or later)
;;; .byte subid ROM FBC0 ($EA = IIe, $E0 = IIe enh/IIgs, $00 = IIc/IIc+)
;;; .byte op_sys 0=ProDOS, 1=Pascal
;;; .byte slot_num Mouse slot, 0 = search (will be filled in)
;;; .byte use_interrupts 0=passive, 1=interrupt
;;; .addr sysfontptr
;;; .addr savearea buffer for saving screen data (e.g. behind menus)
;;; .word savesize bytes
StopDeskTop := $1E ; Deallocates interrupt, hides cursor
;;; (no parameters)
SetUserHook := $1F
;;; .byte hook_id 0=before, 1=after event checking
;;; .addr routine_ptr 0=remove hook_id
AttachDriver := $20 ; Install pointer driver; A=0 on success, $95 if mouse disabled
;;; .addr hook Mouse hook routine to install
;;; .addr mouse_state (out) Address of mouse state (.word x, y; .byte status)
ScaleMouse := $21 ; Set mouse/screen scaling
;;; .byte x_exponent x-scale factor for mouse, 0...3
;;; .byte y_exponent y-scale factor for mouse, 0...3
KeyboardMouse := $22 ; Next operation will be performed by keyboard
;;; (no parameters)
GetIntHandler := $23 ; Get address of interrupt handler
;;; .addr handler (out) Address of interrupt handler (after cld)
;;; --------------------------------------------------
;;; Cursor Manager Calls
;;; Cursor record:
;;;
;;; .res 24 bitmap 2x12 byte bitmap (XOR'd after mask)
;;; .res 24 mask 2x12 byte mask (OR'd with screen)
;;; .byte hotx hotspot coords (pixels)
;;; .byte hoty
SetCursor := $24 ; Set cursor definition
;;; (input is address of Cursor record)
ShowCursor := $25 ; Return cursor to visibility
;;; (no parameters)
HideCursor := $26 ; Cursor hidden until ShowCursor call
;;; (no parameters)
ObscureCursor := $27 ; Cursor hidden until moved
;;; (no parameters)
GetCursorAddr := $28 ; Get cursor definition
;;; .addr definition (out) Address of cursor record
;;; --------------------------------------------------
;;; Event Manager Calls
;;; Event record:
;;;
;;; .byte kind event_kind_*
;;; if kind is event_kind_key_down:
;;; .byte key (ASCII code; high bit clear)
;;; .byte modifiers (0=none, 1=open-apple, 2=solid-apple, 3=both)
;;; if kind is event_kind_update:
;;; .byte window_id
;;; otherwise:
;;; .word xcoord
;;; .word ycoord
CheckEvents := $29 ; Process mouse/kbd if GetEvent will be delayed.
;;; (no parameters)
GetEvent := $2A
;;; (parameter is address of Event record)
FlushEvents := $2B
;;; (no parameters)
PeekEvent := $2C
;;; (parameter is address of Event record)
PostEvent := $2D ; Post event to queue
;;; (parameter is address of Event record)
SetKeyEvent := $2E ; If set, keypresses are ignored by Tool Kit
;;; .byte handle_keys high bit set = ignore keyboard, otherwise check
;;; --------------------------------------------------
;;; Menu Manager Calls
;;; Menu Bar record:
;;;
;;; .word count Number of menu bar items
;;; (array of...)
;;; .byte menu_id Menu identifier
;;; .byte disabled Flag
;;; .addr title Address of length-prefixed string
;;; .addr menu Address of Menu record
;;; .res 6 reserved Reserved
;;; ...
;;;
;;; Menu record:
;;;
;;; .byte count Number of items in menu
;;; .res 5 reserved Reserved
;;; (array of...)
;;; .byte options bit 0=OA, 1=SA, 2=mark, 5=check, 6=filler, 7=disabled
;;; .byte mark_char Custom mark character if mark option set
;;; .byte char1 ASCII code of shortcut #1 (e.g. uppercase B); or 0
;;; .byte char2 ASCII code of shortcut #2 (e.g. lowercase b, or same); or 0
;;; .addr name Address of length-prefixed string
;;; ...
InitMenu := $2F
;;; .byte solid_char char code to use for solid apple glyph
;;; .byte open_char char code to use for open apple glyph
;;; .byte check_char char code to use for checkmark glyph
;;; .byte control_char char code to use for control key glyph
SetMenu := $30 ; Configure (and draw) menu
;;; (input is address of Menu Bar record)
MenuSelect := $31 ; Enter modal loop for handling mouse-down on menu bar
;;; .byte menu_id (out) Top level menu identifier, or 0 if none
;;; .byte menu_item (out) Index (1-based) of item in menu, or 0 if none
MenuKey := $32 ; Find menu item corresponding to keypress
;;; .byte menu_id (out)
;;; .byte menu_item (out)
;;; .byte which_key
;;; .byte key_mods bit 0=OA, bit 1=SA
HiliteMenu := $33 ; Toggle highlight state of menu
;;; .byte menu_id
DisableMenu := $34
;;; .byte menu_id
;;; .byte disable 0=enable, 1=disable
DisableItem := $35
;;; .byte menu_id
;;; .byte menu_item
;;; .byte disable 0=enable, 1=disable
CheckItem := $36
;;; .byte menu_id
;;; .byte menu_item
;;; .byte check 0=unchecked, 1=checked
SetMark := $37
;;; .byte menu_id
;;; .byte menu_item
;;; .byte set_char 0=use checkmark, 1=use mark_char
;;; .byte mark_char char code to use for mark
;;; --------------------------------------------------
;;; Window Manager Calls
;;; WInfo record:
;;;
;;; .byte id
;;; .byte options option_*
;;; .addr title
;;; .byte hscroll scroll_option_*
;;; .byte vscroll scroll_option_*
;;; .byte hthumbmax
;;; .byte hthumbpos
;;; .byte vthumbmax
;;; .byte vthumbpos
;;; .byte status
;;; .byte reserved
;;; .word mincontwidth minimum content size (horizontal)
;;; .word mincontlength minimum content size (vertical)
;;; .word maxcontwidth maximum content size (horizontal)
;;; .word maxcontlength maximum content size (vertical)
;;; GrafPort windowport GrafPort record
;;; .addr nextwinfo address of next lower window in stack
OpenWindow := $38
;;; (input is address of WInfo record)
CloseWindow := $39
;;; .byte window_id
CloseAll := $3A
;;; (no parameters)
GetWinPtr := $3B ; Get pointer to window params by id; A=0 on success
;;; .byte window_id
;;; .addr window_ptr (out) winfo address
GetWinPort := $3C ; Get drawing state of window (possibly clipped)
;;; .byte window_id
;;; .addr port address of grafport to populate
SetWinPort := $3D ; Update port of window
;;; .byte window_id
;;; .addr port GrafPort to copy from
BeginUpdate := $3E ; Respond to update event for window
;;; .byte window_id
EndUpdate := $3F
;;; (no parameters)
FindWindow := $40
;;; .word mousex screen coordinates
;;; .word mousey
;;; .byte which_area (out) area_*
;;; .byte window_id (out) of window
FrontWindow := $41 ; Get id of top window
;;; .byte window_id (out) window, or 0 if none
SelectWindow := $42 ; Make window topmost
;;; .byte window_id
TrackGoAway := $43
;;; .byte clicked (out) 0 = cancelled, 1 = close
DragWindow := $44
;;; .byte window_id
;;; .word dragx mouse coords
;;; .word dragy
;;; .byte moved high bit set if moved, clear if not
GrowWindow := $45
;;; .byte window_id
;;; .word mousex
;;; .word mousey
;;; .byte itgrew (out) 0 = no change, 1 = moved
ScreenToWindow := $46 ; Map screen coords to content coords
;;; .byte window_id
;;; .word screenx
;;; .word screeny
;;; .word windowx (out)
;;; .word windowy (out)
WindowToScreen := $47 ; Map content coords to screen coords
;;; .byte window_id
;;; .word windowx
;;; .word windowy
;;; .word screenx (out)
;;; .word screeny (out)
;;; --------------------------------------------------
;;; Control Manager Calls
FindControl := $48
;;; .word mousex
;;; .word mousey
;;; .byte which_ctl ctl_*
;;; .byte which_part part_*
SetCtlMax := $49
;;; .byte which_ctl ctl_*_scroll_bar
;;; .byte ctlmax maximum value
TrackThumb := $4A
;;; .byte which_ctl ctl_*_scroll_bar
;;; .word mousex
;;; .word mousey
;;; .byte thumbpos (out) 0...255
;;; .byte thumbmoved (out) 0 = no change, 1 = moved
UpdateThumb := $4B
;;; .byte which_ctl ctl_*_scroll_bar
;;; .byte thumbpos new position 0...250
ActivateCtl := $4C ; Activate/deactivate scroll bar
;;; .byte which_ctl ctl_*_scroll_bar
;;; .byte activate 0=deactivate, 1=activate
;;; $4D ???
;;; (input length: 16 bytes)
;;; $4E ???
;;; (input length: 2 bytes)
;;; ============================================================
;;; Graphics Primitives Constants
;;; Used in GetWinPort / SetPortBits
screen_mapbits := $2000 ; Screen address
screen_mapwidth := $80 ; Stride in bytes
;;; Used in SetPenMode
pencopy := 0
penOR := 1
penXOR := 2
penBIC := 3
notpencopy := 4
notpenOR := 5
notpenXOR := 6
notpenBIC := 7
;;; Used in SetZP1
zp_overwrite := 0
zp_preserve := 1<<7
;;; Used in GrafPorts
colormask_and := $FF
colormask_or := $00
textbg_black := $00
textbg_white := $7F
;;; ============================================================
;;; MouseGraphics ToolKit Constants
;;; Used in GetEvent
event_kind_no_event := 0 ; No mouse or keypress
event_kind_button_down := 1 ; Mouse button was depressed
event_kind_button_up := 2 ; Mouse button was released
event_kind_key_down := 3 ; Key was pressed
event_kind_drag := 4 ; Mouse button still down
event_kind_apple_key := 5 ; Mouse button was depressed, modifier key down
event_kind_update := 6 ; Window update needed
event_modifier_open_apple := 1 << 0
event_modifier_solid_apple := 1 << 1
;;; Used in FindWindow
area_desktop := 0
area_menubar := 1
area_content := 2 ; Includes scroll bars
area_dragbar := 3
area_grow_box := 4
area_close_box := 5
;;; Used in FindControl, TrackThumb, UpdateThumb
ctl_not_a_control := 0
ctl_vertical_scroll_bar := 1
ctl_horizontal_scroll_bar := 2
ctl_dead_zone := 3
;;; Used in FindControl
part_up_arrow := 1
part_left_arrow := 1
part_down_arrow := 2
part_right_arrow := 2
part_page_up := 3
part_page_left := 3
part_page_down := 4
part_page_right := 4
part_thumb := 5
;;; Used in OpenWindow
option_dialog_box := 1 << 0
option_go_away_box := 1 << 1
option_grow_box := 1 << 2
scroll_option_none := 0
scroll_option_present := 1 << 7
scroll_option_thumb := 1 << 6
scroll_option_active := 1 << 0
scroll_option_normal := scroll_option_present | scroll_option_thumb | scroll_option_active
;;; Used in menu structs
menuopt_open_apple := 1 << 0
menuopt_solid_apple := 1 << 1
menuopt_item_has_mark := 1 << 2
menuopt_item_is_checked := 1 << 5
menuopt_item_is_filler := 1 << 6
menuopt_disable_flag := 1 << 7
disablemenu_enable := 0
disablemenu_disable := 1
disableitem_enable := 0
disableitem_disable := 1
checkitem_uncheck := 0
checkitem_check := 1
;;; Used in ActivateCtl
activatectl_deactivate := 0
activatectl_activate := 1
;;; Response from InRect/InPoly
inrect_inside := $80
inrect_outside := $00
inpoly_inside := $80
inpoly_outside := $00
;;; ============================================================
;;; Offsets
.struct Point
xcoord .word
ycoord .word
.endstruct
.struct Rect
x1 .word
y1 .word
x2 .word
y2 .word
.endstruct
.struct Pattern
bits .res 8
.endstruct
.struct MapInfo
viewloc .tag Point
mapbits .word
mapwidth .byte
reserved .byte
maprect .tag Rect
.endstruct
.struct GrafPort
viewloc .tag Point
mapbits .addr
mapwidth .byte
reserved .byte
maprect .tag Rect
pattern .tag Pattern
colormasks .byte 2
penloc .tag Point
penwidth .byte
penheight .byte
penmode .byte
textback .byte
textfont .addr
.endstruct
winfo_offset_window_id := 0
winfo_offset_options := 1
winfo_offset_title := 2
winfo_offset_hscroll := 4
winfo_offset_vscroll := 5
winfo_offset_hthumbmax := 6
winfo_offset_hthumbpos := 7
winfo_offset_vthumbmax := 8
winfo_offset_vthumbpos := 9
winfo_offset_status := 10
winfo_offset_mincontwidth := 12
winfo_offset_mincontheight := 14
winfo_offset_maxcontwidth := 16
winfo_offset_maxcontheight := 18
winfo_offset_port := 20
winfo_offset_nextwinfo := 56
winfo_size := 58
menu_size := 12
menu_item_size := 6
short_event_size := 4 ; events that don't have mouse coordinates
event_size := 5 ; any kind of event
cursor_height := 12
cursor_width := 2
cursor_offset_mask := cursor_width * cursor_height
cursor_offset_hotspot := 2 * cursor_width * cursor_height
cursor_size := cursor_offset_hotspot + 2
font_offset_fonttype := 0
font_offset_lastchar := 1
font_offset_height := 2
font_offset_charwidth := 3
;;; Errors
error_empty_object := $81
error_bad_object := $82
error_font_too_big := $83
error_invalid_op_sys := $90
error_no_mouse := $92
error_invalid_irq_setting := $93
error_invalid_hook := $94
error_desktop_already_initialized := $95
error_irq_in_use := $97
error_invalid_event := $98
error_event_queue_full := $99
error_menu_not_found := $9A
error_menu_item_not_found := $9B
error_insufficient_savebehind_area := $9C
error_window_already_exists := $9D
error_window_id_required := $9E
error_window_not_found := $9F
error_no_active_window := $A0
error_window_not_draggable := $A1
error_window_not_resizable := $A2
error_window_obscured := $A3
error_control_not_found := $A4
.endscope ; MGTK
;;; ============================================================
;;; Macros
;;; Call an MGTK entry point:
;;; MGTK_CALL n - params is $0000
;;; MGTK_CALL n, params_addr
;;; MGTK_CALL m, params_addr, label - params_addr is labeled for modifying
.macro MGTK_CALL op, addr, label
jsr MGTK::MLI
.byte op
.if .paramcount > 2
label := *
.endif
.if .paramcount > 1
.addr addr
.else
.addr 0
.endif
.endmacro
;;; ------------------------------------
;;; Rect definition. Option fifth param gives scope.
;;; DEFINE_RECT 0,0,20,30
;;; DEFINE_RECT 0,0,20,30,rect ; rect::x1, rect::y1, rect::x2, rect::y2
.macro DEFINE_RECT left, top, right, bottom, opt_scope
.if .paramcount > 4
.scope opt_scope
x1: .word left
y1: .word top
x2: .word right
y2: .word bottom
.endscope
.else
.word left
.word top
.word right
.word bottom
.endif
.endmacro
;;; Point definition. Option third param gives scope.
;;; DEFINE_POINT 10,20
;;; DEFINE_POINT 10,20,pt ; pt::xcoord, pt::ycoord
.macro DEFINE_POINT left, top, opt_scope
.if .paramcount > 2
.scope opt_scope
xcoord: .word left
ycoord: .word top
.endscope
.else
.word left
.word top
.endif
.endmacro
;;; String definition w/ inline data, for use with DrawText
;;; DEFINE_STRING "abc"
;;; DEFINE_STRING {"Ring a bell",$07,"!!!"} ; control characters
;;; Optional second param gives label to internal Pascal string
.macro DEFINE_STRING str, opt_label
.local data
.local end
.addr data ; textptr
.if .paramcount > 1
opt_label:
.endif
.byte end - data ; textlen
data: .byte str
end:
.endmacro
;;; Menus (common cases; other options are possible)
.macro DEFINE_MENU_BAR count
.byte count ; num menus
.byte 0 ; reserved
.endmacro
.macro DEFINE_MENU_BAR_ITEM id, label, menu
.byte id ; menu id
.byte 0 ; disable flag
.addr label ; title pointer
.addr menu ; pointer to menu
.res 6, 0 ; 6 reserved bytes
.endmacro
.macro DEFINE_MENU count
.byte count ; num items
.res 5, 0 ; 5 reserved bytes
.endmacro
.macro DEFINE_MENU_ITEM saddr, shortcut1, shortcut2
.if .paramcount > 1
.byte MGTK::menuopt_open_apple ; option byte
.byte 0 ; mark_char
.byte shortcut1 ; char1
.byte shortcut2 ; char2
.addr saddr ; item_str_pointer
.else
.byte 0 ; option byte
.byte 0 ; mark_char
.byte 0 ; char1
.byte 0 ; char2
.addr saddr ; item_str_pointer
.endif
.endmacro
.macro DEFINE_MENU_SEPARATOR
.byte MGTK::menuopt_item_is_filler ; option byte
.byte 0 ; mark_char
.byte 19 ; char1 - Ctrl+S for separator ???
.byte 0 ; char2
.addr 0 ; item_str_pointer
.endmacro
;;; ------------------------------------
;;; Define pattern for PaintBits - low 7 bits are reversed
;;; e.g. .byte px(%1000000)
;;; px() has high bit clear, PX() has high bit set
.define px(bits) (((bits&$40)>>6)|((bits&$20)>>4)|((bits&$10)>>2)|(bits&$8)|((bits&$4)<<2)|((bits&$2)<<4)|((bits&$1)<<6))
.define PX(bits) (((bits&$40)>>6)|((bits&$20)>>4)|((bits&$10)>>2)|(bits&$8)|((bits&$4)<<2)|((bits&$2)<<4)|((bits&$1)<<6)|$80)