-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathcommon.inc
419 lines (329 loc) · 14.3 KB
/
common.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
;;; ============================================================
;;; Definitions that apply to DeskTop and Selector
;;; ============================================================
;;; Uncomment to enable limited runtime error checking.
;;; DEBUG = 1
.include .concat("common/res/common.res.", kBuildLang)
;;; ============================================================
;;; Filenames
.define kFilenameLauncher "DeskTop.system"
.define kFilenameModulesDir "Modules"
.define kPathnameDeskTop .concat(kFilenameModulesDir, "/DeskTop")
.define kPathnameDiskCopy .concat(kFilenameModulesDir, "/Disk.Copy")
.define kPathnameSelector .concat(kFilenameModulesDir, "/Selector")
.define kFilenameLocalDir "Local"
.define kPathnameSelectorList .concat(kFilenameLocalDir, "/Selector.List")
.define kPathnameDeskTopConfig .concat(kFilenameLocalDir, "/DeskTop.config")
.define kPathnameDeskTopState .concat(kFilenameLocalDir, "/DeskTop.file")
.define kPathnameBellProc .concat(kFilenameLocalDir, "/Bell.proc")
.define kPathnameQuitSave .concat(kFilenameLocalDir, "/Quit.tmp")
.define kFilenameDADir "Apple.Menu"
.define kFilenameExtrasDir "Extras"
.define kFilenameRAMCardDir "DeskTop"
;;; ============================================================
;;; DeskTop Modules
MODULE_BOOTSTRAP := $2000
kModuleBootstrapSize = $400
;;; ============================================================
;;; For addresses/values that will be filled in at runtime.
SELF_MODIFIED = $1234 ; To avoid ZP addressing mode
SELF_MODIFIED_BYTE = $12
;;; ============================================================
kMaxPathLength = 64
kPathBufferSize = 65
kDirStackBufferSize = 64 ; max of 32 levels
kMaxFilenameLength = 15
;;; ============================================================
;;; Extended Events
;;; Generated by `GetNextEvent` in `lib/get_next_event.s`
kEventKindMouseMoved = $11
;;; ============================================================
;;; Metrics
kScreenWidth = 560
kScreenHeight = 192
;;; Prefer DEFAULT_FONT+MGTK::Font::height, but that's not always convenient.
kSystemFontHeight = 9
kSystemFontWidth = 7 ; proportional, but this is the maximum
kMenuBarHeight = kSystemFontHeight+4
;;; Standard button sizes; sometimes narrower
kButtonWidth = 100
kButtonHeight = kSystemFontHeight+2
kButtonTextHOffset = 5 ; from left edge of rect to text pos
kButtonTextVOffset = kSystemFontHeight+1 ; from top edge of rect to text pos
;;; Horizontal distance for label/control pairs
kLabelHOffset = 3
;;; Standard line edit (text input) control metrics
kTextBoxHeight = kSystemFontHeight+2
kTextBoxTextHOffset = 5 ; from left edge of rect to text pos
kTextBoxTextVOffset = kSystemFontHeight+1 ; from top edge of rect to text pos
;;; Standard list box control metrics
kListItemHeight = kSystemFontHeight+1
kListItemTextOffsetX = kTextBoxTextHOffset
kListItemTextOffsetY = kListItemHeight - 1
;;; File lists
kListViewIconWidth = 14
kListViewIconGap = 4
kListViewIconX = 4
kListViewNameX = kListViewIconX + kListViewIconWidth + kListViewIconGap
;;; Mouse threshold for double click detection.
kDoubleClickDeltaX = 5
kDoubleClickDeltaY = 4
;;; ============================================================
;;; Alert library options. See `lib/alert_dialog.s`
;;; Button options
;;; $C0 (%11xxxxxx) = Cancel + OK
;;; $81 (%10xxxxx1) = Cancel + Yes + No + All
;;; $80 (%10xx0000) = Cancel + Try Again
;;; $00 (%0xxxxxxx) = OK
;;; Note: Wrapper APIs that take A=id, X=options use X=0 to mean
;;; "use default options for that id", otherwise X & %00000001.
.enum AlertButtonOptions
OKCancel = $C0
YesNoAllCancel = $81
TryAgainCancel = $80
OK = $00
.endenum
.enum AlertOptions
Beep = %10000000 ; N = play beep sound
SaveBack = %01000000 ; V = save/restore background
.endenum
kAlertResultTryAgain = 0
kAlertResultCancel = 1
kAlertResultOK = 2
kAlertResultYes = 3
kAlertResultNo = 4
kAlertResultAll = 5
.struct AlertParams
text .addr
buttons .byte ; AlertButtonOptions
options .byte ; AlertOptions flags
.endstruct
;;; NOTE: See the Rename code in DeskTop for a use case for having
;;; TryAgain and OK differ. In that example, the error code determines
;;; the options (OK vs. Try Again / Cancel), and OK after a failure is
;;; the same as Cancel (give up), not Try Again.
;;; ============================================================
;;; Selector List file
;;; See `docs/Selector_List_Format.md` for file format.
kSelectorListNumPrimaryRunListEntries = 8
kSelectorListNumSecondaryRunListEntries = 16
kSelectorListNumEntries = kSelectorListNumPrimaryRunListEntries + kSelectorListNumSecondaryRunListEntries
kSelectorListNameLength = 16 ; includes leading size byte and trailing flags byte
kSelectorListPathLength = 64
kSelectorMaxNameLength = 14
kSelectorListNumPrimaryRunListOffset = 0
kSelectorListNumSecondaryRunListOffset = 1
kSelectorListEntriesOffset = 2
kSelectorListPathsOffset = kSelectorListEntriesOffset + kSelectorListNumEntries * kSelectorListNameLength
kSelectorEntryFlagsOffset = $F
kSelectorEntryCopyOnBoot = $00
kSelectorEntryCopyOnUse = $80
kSelectorEntryCopyNever = $C0
;;; This much is consistently reserved/written.
kSelectorListBufSize = $800
;;; If only the primary run list needs to be loaded, this is a sufficient buffer.
kSelectorListShortSize = $400
;;; ============================================================
;;; Link files
kLinkFileAuxType = $0001
kLinkFileSig1Offset = 0
kLinkFileSig2Offset = 1
kLinkFileSig1Value = $C2
kLinkFileSig2Value = $CD
kLinkFileVersionOffset = 2
kLinkFileCurrentVersion = $00
kLinkFilePathLengthOffset = 3
kLinkFileMaxSize = 68 ; signature + version + length + 64-byte path
;;; ============================================================
;;; Settings Config File
;;; See `docs/Desktop_Config_Format.md` for file format.
kDefaultDblClickSpeed = 1200
kDefaultCaretBlinkSpeed = 500
kDeskTopSettingsSize = $80
.struct DeskTopSettings
pattern .res 8
dblclick_speed .word
caret_blink_speed .word
clock_24hours .byte ; $00 = 12 hour, $80 = 24 hour
rgb_color .byte ; $00 = B&W, $80 = Color
mouse_tracking .byte ; 0 = normal, 1 = 2x speed
options .byte ; kOptionsXYZ options
intl_date_sep .byte ; date separator
intl_time_sep .byte ; time separator
intl_thou_sep .byte ; thousands separator
intl_deci_sep .byte ; decimal separator
intl_date_order .byte ; kDateOrderXYZ
reserved .res 106
;; Written on every startup, in settings for convenience
system_capabilities .byte ; kSysCapXYZ
.endstruct
.assert .sizeof(DeskTopSettings) = kDeskTopSettingsSize, error, .sprintf("Expected $%02X, was $%0X", kDeskTopSettingsSize, .sizeof(DeskTopSettings))
DeskTopSettings::kDateOrderMDY = 0
DeskTopSettings::kDateOrderDMY = 1
DeskTopSettings::kOptionsSkipRAMCard = %00000001 ; skip copy to RAMCard, if set
DeskTopSettings::kOptionsSkipSelector = %00000010 ; skip starting Selector, if set
DeskTopSettings::kOptionsShowShortcuts = %00000100 ; show button shortcuts, if set
DeskTopSettings::kOptionsSetCaseBits = %00001000 ; write GS/OS case bits, if set
DeskTopSettings::kOptionsShowInvisible = %00010000 ; show "invisible" files, if set
DeskTopSettings::kSysCapIsIIgs = %00000001
DeskTopSettings::kSysCapIsIIc = %00000010 ; also set for IIc Plus
DeskTopSettings::kSysCapIsIIcPlus = %00000100
DeskTopSettings::kSysCapIsIIeCard = %00001000
DeskTopSettings::kSysCapIsLaser128 = %00010000
DeskTopSettings::kSysCapMegaII = %00100000
DeskTopSettings::kSysCapLCMEve = %01000000
kDeskTopSettingsFileVersion = 3
kDeskTopSettingsFileSize = 1 + .sizeof(DeskTopSettings)
kDeskTopSettingsFileOffset = 1 ; offset into file of settings (first byte is version)
;;; ============================================================
;;; Alert Sounds. See `lib/bell.s`
kBellProcLength = 128
BELLPROC := $300
;;; ============================================================
;;; Date/Time. See `lib/datetime.s`
.struct ParsedDateTime
year .word
month .byte
day .byte
hour .byte
minute .byte
.endstruct
;;; ============================================================
;;; Offsets into launcher
kLauncherDateOffset = 3
;;; ============================================================
;;; Drive Special Cases
;;; Unit number used by Glen E. Bredon's RAM.DRV.SYSTEM
;;; RAM disk driver for RamWorks, appears in `DEVLST`.
kRamDrvSystemUnitNum = $3E
;;; Unit number used by John Brooks' RAMAUX.SYSTEM
;;; RAM disk driver for RamWorks, appears in `DEVLST`.
kRamAuxSystemUnitNum = $3F
;;; ADTPro's VDRIVE: https://adtpro.com/vdrive.html
;;; Driver address used by ADTPro's VEDRIVE in `DEVADR`.
kVEDRIVEDriverAddress = $D004
;;; Driver address used by ADTPro's VSDRIVE in `DEVADR`.
kVSDRIVEDriverAddress = $D000
;;; Driver signature byte/value for ADTPro's VSDRIVE
VSDRIVE_SIGNATURE_BYTE := $D003 ; in Main/LCBANK1
kVSDRIVESignatureValue = $63
;;; ============================================================
;;; QUIT Routine
;;; Modules (DeskTop, Selector) install a QUIT handler to restart
;;; themselves after launching external programs. These live in Main
;;; LCBANK2.
;;; The routine can extend from `SELECTOR` ($D100) up through
;;; `ENTRY_COPIED_FLAGS` (see below), but this seems a good limit
;;; to allow for future expansion.
kMaxQuitRoutineSize = $180
;;; ============================================================
;;; RAM Disk
;;; On startup, DeskTop will copy itself (including resources) and
;;; (optionally) selector entries to a RAM disk if available. Flags
;;; are set and the original/new prefixes to DeskTop are maintained.
;;; These are stored in the custom ProDOS QUIT routine area in Main
;;; LCBANK2.
;;; These can extend from `SELECTOR` + `kMaxQuitRoutineSize`
;;; $D280 (see above) through `BELLDATA`/`SETTINGS` $D300 (see below)
;;; 24 bytes - flags for each entry, set to $FF when copied to RAM disk.
ENTRY_COPIED_FLAGS := $D295
;;; 65 bytes - original prefix DeskTop was loaded with (e.g. "/HD/A2D")
DESKTOP_ORIG_PREFIX := $D2AD
;;; 17 bytes - prefix for RAMCard (e.g. "/RAM")
RAMCARD_PREFIX := $D2EE
;;; $00 = no ramcard found
;;; $C0 = ramcard found, but not copied (internal state)
;;; $80 = ramcard found, DeskTop copied
COPIED_TO_RAMCARD_FLAG := $D2FF
;;; ============================================================
;;; Sound & Settings
;;; These are stored in the custom ProDOS QUIT routine area in Main
;;; LCBANK2. See `lib/readwrite_settings.s`
BELLDATA := $D300
;;; See `kBellProcLength`
SETTINGS := $D380
;;; See `DeskTopSettings`
;;; ============================================================
;;; Invoker routine locations
;;; DeskTop and Selector both use a routine at $290 to launch
;;; other apps. See: `lib/invoker.s`
INVOKER_PREFIX := $220 ; Prefix to set
INVOKER := $290 ; Invoke other programs
INVOKER_FILENAME := $280 ; File to invoke (PREFIX must be set)
INVOKER_INTERPRETER := $380 ; If non-empty, use path as interpreter.
INVOKER_BITSY_COMPAT := $3C1 ; bit7 = set $280 like Bitsy does
;;; ============================================================
;;; Default Font
;;; Control Character Glyphs
;;;
;;; Glyphs $00-$1F are useful symbols; some overlap with MouseText
;;; (called out as MT:X in the table below)
;;;
;;; $00 = spacer ! $10 = TM left *
;;; $01 = folder left ! (MT:X) $11 = TM right *
;;; $02 = folder right ! (MT:Y) $12 = pound *
;;; $03 = file left ! $13 = pi *
;;; $04 = file right ! $14 = divide *
;;; $05 = disk left ! $15 = rarrow ! (MT:U)
;;; $06 = disk right ! $16 = degree !
;;; $07 = lock ! $17 = open circ
;;; $08 = larrow ! (MT:H) $18 = close (MT:])
;;; $09 = left box $19 = gray odd (MT:W)
;;; $0A = darrow ! (MT:J) $1A = gray even (MT:V)
;;; $0B = uarrow ! (MT:K) $1B = solid circ
;;; $0C = right box $1C = inv check (MT:E)
;;; $0D = return ! (MT:M) $1D = check ! (MT:D)
;;; $0E = (C) $1E = solid apple ! (MT:@)
;;; $0F = (R) $1F = open apple ! (MT:A)
;;;
;;; ! = Used in this application; glyphs must be present in font.
;;; Any other code points can be repurposed.
;;; * = Used to provide additional characters in some languages
;;; (notably Spanish) where Apple's character sets are lacking.
kGlyphSpacer = $00
kGlyphFolderLeft = $01
kGlyphFolderRight = $02
kGlyphFileLeft = $03
kGlyphFileRight = $04
kGlyphDiskLeft = $05
kGlyphDiskRight = $06
kGlyphLock = $07
kGlyphLeftArrow = $08
kGlyphRightArrow = $15
kGlyphUpArrow = $0B
kGlyphDownArrow = $0A
kGlyphReturn = $0D
kGlyphDegreeSign = $16
kGlyphOpenApple = $1F
kGlyphSolidApple = $1E
kGlyphCheckmark = $1D
;;; Menu (by default) uses:
;;; Solid Mod $1E
;;; Open Mod $1F
;;; Check $1D
;;; Control $01
;;; ============================================================
;;; Macros (specific to this project)
.macro DEFINE_LABEL ident, label, xpos, ypos
DEFINE_POINT .ident(.sprintf("%s_label_pos", .string(ident))), (xpos), (ypos)
.ident(.sprintf("%s_label_str", .string(ident))) := *
PASCAL_STRING {label}
.endmacro
;;; Define an rect for an inset frame drawn with a 4x2 pen, with a 4x2
;;; gap between the passed window bounds and the border. This is the
;;; standard style for modal dialog boxes and alerts.
kBorderDX = 4
kBorderDY = 2
.macro DEFINE_RECT_FRAME ident, width, height
ident := *
.scope ident
x1: .word kBorderDX
y1: .word kBorderDY
x2: .word ((width) - kBorderDX*2 + 1)
y2: .word ((height) - kBorderDY*2 + 1)
.refto x1
.refto y1
.refto x2
.refto y2
.endscope
.endmacro