mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-25 13:02:45 +00:00
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set. make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
1 line
62 KiB
NASM
1 line
62 KiB
NASM
*******************************************************************************
|
|
*
|
|
* Copyright 1990-1993 Apple Computer, Inc
|
|
* All Rights Reserved
|
|
*
|
|
* 26-Jan-93 SS -- Removed QDAuxStartup call
|
|
*
|
|
*******************************************************************************
|
|
|
|
string asis
|
|
blanks off
|
|
|
|
print push,off
|
|
|
|
include 'All.macros'
|
|
include 'E16.Menu'
|
|
include 'E16.Event'
|
|
include 'E16.Locator'
|
|
|
|
Import CurrentDirPath
|
|
Import MyOpenRec
|
|
Import MyDirEntry
|
|
Import TempNamePtr
|
|
Import tempString
|
|
Import MyClose
|
|
Import MyID
|
|
Import MyListCnt
|
|
Import MyList
|
|
Import ListCtrl
|
|
Import AsmtoolErr
|
|
Import MatchType
|
|
Import MatchStr
|
|
Import IdleWind
|
|
Import VolPopUp
|
|
Import StackHandle
|
|
Import StackLevel
|
|
Import PascalStack
|
|
Import EntryCount
|
|
Import Stopping
|
|
Import SetMessage
|
|
Import ListCtrl
|
|
Import screenMode
|
|
entry MyMemberDraw
|
|
entry InsertIntoList
|
|
entry InsertTheItem
|
|
entry GetHandle
|
|
entry SetPopup
|
|
|
|
Entry AsmAddFile
|
|
GBLA &Debug
|
|
&Debug Seta 0
|
|
print pop
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
SetAboutMessage PROC Export
|
|
*
|
|
* Description: This little routine will set the about message in the message
|
|
* box and cause it to be drawn.
|
|
*
|
|
*
|
|
* Inputs: None
|
|
*
|
|
* Outputs: None
|
|
*
|
|
* External Refs:
|
|
*
|
|
* Entry Points:
|
|
*
|
|
*******************************************************************************
|
|
PushLong #VersionInfo
|
|
jsl SetMessage
|
|
rtl
|
|
|
|
VersionInfo dc.B textEnd-textStart
|
|
textStart
|
|
dc.B $01,$4A,$01,$00 ; center justify
|
|
dc.B 'Find File',$0d
|
|
dc.B '©1990-93 Apple Computer Inc.',$0d
|
|
dc.B 'by Mensch, Yee, Lyons, & Stephenson',$0D
|
|
dc.B 'Tested by M.S. & B.K. & J.J.J'
|
|
textEnd
|
|
EndP
|
|
|
|
|
|
*******************************************************************************
|
|
*
|
|
* InstallMyRequestProc
|
|
*
|
|
* AcceptRequests(@reqProcName, MMStartUp, ffRequestProc);
|
|
*
|
|
*******************************************************************************
|
|
InstallMyRequestProc proc export
|
|
import ffRequestProc
|
|
|
|
pushlong #reqProcName
|
|
pha
|
|
_MMStartUp
|
|
pushlong #ffRequestProc
|
|
_AcceptRequests
|
|
rtl
|
|
|
|
reqProcName str 'Apple~FindFile~1.1~'
|
|
|
|
EndP
|
|
|
|
*******************************************************************************
|
|
*
|
|
* ffRequestProc
|
|
*
|
|
* This is Find File's Request Procedure, installed by AcceptRequests.
|
|
*
|
|
* We watch for systemSaysMenuKey(Command-F) and open ourselves.
|
|
*
|
|
*******************************************************************************
|
|
ffRequestProc PROC export
|
|
|
|
oldDPage equ 1
|
|
RTL1 equ oldDPage+2
|
|
DataOut equ RTL1+3
|
|
DataIn equ DataOut+4
|
|
Request equ DataIn+4
|
|
Result equ Request+2
|
|
|
|
phd
|
|
tsc
|
|
tcd
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
lda <Request
|
|
cmp #systemSaysMenuKey
|
|
bne @notMenuKey
|
|
|
|
jsr handleMenuKey
|
|
ror <Result
|
|
|
|
@notMenuKey plb
|
|
|
|
pld
|
|
lda 2,s
|
|
sta 12,s
|
|
lda 1,s
|
|
sta 11,s
|
|
ply
|
|
ply
|
|
ply
|
|
ply
|
|
ply
|
|
rtl
|
|
|
|
*******************************************************************************
|
|
*
|
|
* handleMenuKey
|
|
*
|
|
* Respond to a systemSaysMenuKey request.
|
|
*
|
|
* dataIn = pointer to task record as passed to MenuKey
|
|
*
|
|
* dataOut:
|
|
* +000: recvCount (filled in by Tool Locator)
|
|
*
|
|
* Return with SEC if we handled the request.
|
|
*
|
|
*******************************************************************************
|
|
import ffMenuItemID
|
|
handleMenuKey ldy #oModifiers
|
|
lda [<dataIn],y
|
|
and #appleKey+shiftKey+optionKey+controlKey+keyPad
|
|
cmp #appleKey
|
|
bne @notMe
|
|
|
|
ldy #oMessage
|
|
lda [<dataIn],y
|
|
and #$00df
|
|
cmp #'F' ;Command-F = our key equivalent
|
|
bne @notMe
|
|
|
|
pha ;space for OpenNDA result
|
|
lda ffMenuItemID
|
|
pha
|
|
_OpenNDA
|
|
pla ;ignore
|
|
|
|
sec ;accept the request
|
|
rts
|
|
|
|
@notMe clc
|
|
rts
|
|
|
|
EndP
|
|
|
|
|
|
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
;
|
|
; Equates
|
|
;
|
|
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
;
|
|
|
|
MenuItemPtr equ 36 ;This is the offset to menu mgr's direct page
|
|
; ;variable "itemptr"
|
|
y1 equ 0
|
|
x1 equ y1+2
|
|
y2 equ x1+2
|
|
x2 equ y2+2
|
|
|
|
ItemHeight equ 12
|
|
|
|
;
|
|
; ------ MENU record -----------------------------------------
|
|
;
|
|
MenuID equ 0 Menu's ID number.
|
|
MenuWidth equ MenuID+2 Width of menu.
|
|
MenuHeight equ MenuWidth+2 Height of menu.
|
|
MenuProc equ MenuHeight+2 Menu's definition procedure.
|
|
MenuFlag equ MenuProc+4 Bit flags.
|
|
MenuRes equ MenuFlag+1 Future expansion (makes record even).
|
|
NumOfItems equ MenuRes+1 Number of items in the menu
|
|
TitleWidth equ NumOfItems+2 Width of menu's title.
|
|
TitleName equ TitleWidth+2 Pointer to menu's title text.
|
|
|
|
MenuCache equ TitleName+4 Handle of menu's cache.
|
|
ItemList equ MenuCache+4 Array of items in menu.
|
|
MENUSIZE equ ItemList Size of menu record with no items.
|
|
|
|
;
|
|
; ------ ITEM record -----------------------------------------
|
|
;
|
|
ItemID equ 0 Item's ID number, zero = last item.
|
|
ItemChar equ ItemID+2 Keyboard equvalent, display in item.
|
|
ItemAltChar equ ItemChar+1 Alternate keyboard equvalent, not shown.
|
|
ItemCheck equ ItemAltChar+1 Item's mark.
|
|
ItemFlag equ ItemCheck+2 Bit flags.
|
|
ItemName equ ItemFlag+2 Pointer to item's text.
|
|
ITEMSIZE equ ItemName+4 Size of ITEM record.
|
|
|
|
ItemFlag2 equ 0 control attributes of structure
|
|
ItemTitleRef equ ItemFlag2+2 reference to item name
|
|
ItemIconRef equ ItemTitleRef+4 reference to icon associated with item
|
|
|
|
ItemStructSize equ ItemIconRef+4 size of structure
|
|
|
|
MaxEntries equ 200
|
|
MaxPerLevel equ 1
|
|
|
|
; this used to save some room
|
|
|
|
PushLongVolPopup Proc
|
|
plx
|
|
lda >VolPopup+2
|
|
pha
|
|
lda >VolPopup
|
|
pha
|
|
phx
|
|
rts
|
|
EndP
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; GSOStoPString
|
|
;
|
|
; Converts a GS/OS output string to a pstring.
|
|
;
|
|
; IN: ptr to dest pstring:LONG (Destination)
|
|
; ptr to GSOS output string:LONG (Source)
|
|
;
|
|
; OUT: dest has been converted to a pstring
|
|
;
|
|
;------------------------------------------------------------------
|
|
GSOStoPString PROC EXPORT
|
|
i equ 1
|
|
oldDPage equ i+2
|
|
theRTL equ oldDPage+2
|
|
Source equ theRTL+3
|
|
Dest equ source+4
|
|
|
|
phd
|
|
pha ; make room for the data
|
|
tsc
|
|
tcd ; set our new direct page...
|
|
;
|
|
; Start by getting the proper length into i and dest
|
|
lda [<source] ; its the first word of the source
|
|
cmp #$0100 ; is it too large???
|
|
blt @SizeOK ; size is ok,
|
|
lda #$00FF ; else make it smaller
|
|
@SizeOK sta <i ; save the size...
|
|
sta [<Dest] ; and save the size in our pstring
|
|
; now bump the source pointer by one so we can use the same offset all the time
|
|
inc <source
|
|
bne @1
|
|
inc <source+2
|
|
@1
|
|
; Now start the copy
|
|
sep #$20
|
|
Longa Off ; do it a byte at a time...
|
|
ldy <i ; get our index
|
|
@CopyLoop lda [<source],y ; get a source byte
|
|
sta [<dest],y ; and save it
|
|
dey ; lower the count by 1
|
|
bne @CopyLoop ; loop till zero
|
|
; Now that we are all copied clean up after ourselves and leave
|
|
plx ; pull off the crap
|
|
pld ; pull off the direct page
|
|
pla ; save the return address
|
|
ply ; NOTE: A still in short mode
|
|
|
|
plx ; discard the input parms
|
|
plx
|
|
plx
|
|
plx
|
|
|
|
phy ; put the return address back
|
|
pha
|
|
rep #$20 ; turn long <A> back on
|
|
longa On
|
|
lda #0
|
|
clc ; exit like a tool call
|
|
rtl ; and leave
|
|
EndP
|
|
|
|
;---------------------------------------------------------------------------
|
|
;
|
|
; Global record for use with the popup menu stuff and disk switch stuff.
|
|
;
|
|
;---------------------------------------------------------------------------
|
|
popUpGlobals record
|
|
|
|
Count ds.w 1 ; stores the number of items in the menu
|
|
MenuItemTemplate
|
|
Version dc.w 0 ; must be zero
|
|
MyItemID ds.w 1
|
|
dc.b 0 ; ItemChar, no key equivs...
|
|
dc.b 0 ; ItemAltChar
|
|
dc.w 0 ; ItemCheck
|
|
dc.w $4520 ; bits 9 and 10 describe the item struct.
|
|
; ; ItemFlag, XOR hiliting, title is a handle
|
|
ItemStruct ds.l 1 ; This will be a handle to the volume name
|
|
|
|
;
|
|
; ---- GS/OS parameter block definitions --------------
|
|
;
|
|
|
|
SearchDevNum ds.w 1 ; Device number that was last searched (22-May-91 MSD)
|
|
|
|
DInfoPBlock dc.w 8 ; pcount
|
|
DevNum ds.w 1 ; device number
|
|
dc.l DevNameBuffer ; pointer to buffer to store device name
|
|
Characteristics ds.w 1 ; characteristics
|
|
ds.l 1 ; totalBlocks
|
|
ds.w 1 ; slotnum
|
|
ds.w 1 ; unitnum
|
|
ds.w 1 ; version
|
|
DeviceID ds.w 1 ; deviceID
|
|
|
|
VolumePBlock dc.w 2 ; pcount
|
|
dc.l DevName ; device name (GS/OS input string)
|
|
dc.l VolNameBuffer ; pointer to buffer to store volume name
|
|
|
|
|
|
DevNameBuffer dc.w 35 ; word length count
|
|
DevName ds.b 35 ; buffer to store device name
|
|
|
|
VolNameBuffer dc.w 35 ; word length count
|
|
VolumeName ds.b 35 ; buffer to store volume name
|
|
|
|
GetVolNameFlag ds.W 1 ; flag for get vol name...
|
|
|
|
DStatusPBlock dc.W 5 ; pCount
|
|
DStatDevNum ds.W 1 ; device number
|
|
dc.W 0 ; status code
|
|
dc.L StatusList ; status info returned here
|
|
dc.L $00000002 ; request count, no. of bytes to return
|
|
ds.L 1 ; amount of info actually returned
|
|
StatusList
|
|
StatusWord ds.W 1 ; status word returned for device
|
|
|
|
NotifyPBlock dc.w 1 ; pCount
|
|
theRoutine ds.L 1 ; the notificaton proc
|
|
|
|
DiskEject equ $0010
|
|
|
|
DeviceSwitched ds.w 1
|
|
DeviceInserted ds.w 1
|
|
|
|
theName ds.L 1
|
|
|
|
StaticDeviceTable ds.B 128 ;table of devices not to make DStatus call on.
|
|
|
|
|
|
EndR
|
|
|
|
|
|
;==============================================================================
|
|
;
|
|
; PollDevices
|
|
;
|
|
; This routine just polls all devices making DStatus calls on them, trying to
|
|
; trigger a disk switch event. If one occurs then GS/OS calls my routine
|
|
; NotificationPROC to handle the event.
|
|
;
|
|
;==============================================================================
|
|
PollDevices PROC EXPORT
|
|
Import ServiceDiskSwitch
|
|
|
|
with PopUpGlobals
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
*** added 23-Apr-91 DAL -- limit polling frequency to 1.5 seconds
|
|
jsr GetTick
|
|
sec
|
|
sbc prevPollTick
|
|
cmp #180
|
|
bcc DoNothing
|
|
*** end of 23-Apr-91 DAL
|
|
|
|
stz DStatDevNum ;reset the device number so we can search from begining
|
|
|
|
BigLooper inc DStatDevNum ;check next device
|
|
lda DStatDevNum ;Check our table to see if this device even needs to be
|
|
cmp #65 ;polled. Non-removable devices and 5.25s are not polled.
|
|
bcs @done ;exit when we reach our 64 device limit
|
|
asl a
|
|
tax
|
|
lda StaticDeviceTable-2,x
|
|
bmi BigLooper
|
|
|
|
_DStatusGS DStatusPBlock
|
|
bcc BigLooper ;loop until we run out of devices
|
|
|
|
@done
|
|
*** added 23-Apr-91 DAL
|
|
jsr GetTick
|
|
sta prevPollTick
|
|
*** end of 23-Apr-91 DAL
|
|
|
|
DoNothing plb
|
|
|
|
rtl
|
|
|
|
prevPollTick dc.w 0
|
|
|
|
GetTick pha
|
|
pha
|
|
_TickCount
|
|
pla
|
|
plx
|
|
rts
|
|
|
|
ENDP
|
|
|
|
|
|
;==============================================================================
|
|
;
|
|
; NotificationPROC
|
|
;
|
|
; This is the routine that gets installed into GS/OS's notification queue.
|
|
; NumVolumes is incremented or decremented depending on the disk switch. We
|
|
; save off the device number of the disk that got switched and the flag that
|
|
; tells us whether an insertion or ejection occurred.
|
|
; We pay particular attention to disk ejects that occurred on the currently
|
|
; displayed volume.
|
|
;
|
|
; On entry: Acc = device number
|
|
; event_code = bit 4 set = eject
|
|
; bit 3 set = insert
|
|
;
|
|
;==============================================================================
|
|
NotificationPROC PROC EXPORT
|
|
with PopupGlobals
|
|
|
|
Reserved1 ds.L 1 ;link to next task in queue
|
|
Reserved2 ds.W 1
|
|
Signature dc.W $A55A
|
|
Event_flags dc.L $00000018 ;want disk inserts/ejects
|
|
Event_code ds.L 1 ;curent event code will be put here by GS/OS
|
|
|
|
with PopUpGlobals
|
|
|
|
phk ;first set the data bank correctly
|
|
plb
|
|
|
|
cmp #65 ; beyond our 64-device limit?
|
|
bcs @done ; yes, just ignore it
|
|
|
|
tay ; move device number of disk switched device into y-reg
|
|
asl a
|
|
tax
|
|
lda StaticDeviceTable-2,x
|
|
bmi @Done ; ignore 5.25's and non-removeable media drives
|
|
|
|
lda Event_Code ;save flag that tells us whether an insert or eject happened
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
and #%0011
|
|
ora StaticDeviceTable-2,x
|
|
sta StaticDeviceTable-2,x
|
|
sty DeviceSwitched ;set flag to show that we've been through here
|
|
;list is automatically redrawn on disk insertion.
|
|
@Done rtl
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
;==================================================
|
|
; This routine inserts the notification routine
|
|
; into the GS/OS notification queue to get
|
|
; informed of disk switch events
|
|
;==================================================
|
|
CallNotifyProc Proc Export
|
|
with PopupGlobals
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
lda #NotificationPROC
|
|
sta theRoutine
|
|
lda #^NotificationPROC
|
|
sta theRoutine+2
|
|
|
|
_AddNotifyProcGS NotifyPBlock
|
|
|
|
plb
|
|
|
|
rtl
|
|
|
|
EndP
|
|
|
|
;==================================================
|
|
; This routine removes the notification routine
|
|
; from the GS/OS notification queue
|
|
;==================================================
|
|
CallDelNotifyProc Proc Export
|
|
with PopupGlobals
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
_DelNotifyProcGS NotifyPBlock
|
|
|
|
plb
|
|
|
|
rtl
|
|
|
|
EndP
|
|
|
|
;===========================================================
|
|
;
|
|
;===========================================================
|
|
ServiceDiskSwitch Proc Export
|
|
with PopupGlobals
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
lda DeviceSwitched ; check if there was a disk switch
|
|
bne gotSwitch
|
|
brl exit ; that was easy!
|
|
gotSwitch
|
|
pha ; save current menu bar on the stack
|
|
pha
|
|
_GetMenuBar
|
|
|
|
jsr PushLongVolPopup ; set new menu bar to popup control
|
|
_SetMenuBar
|
|
|
|
stz DeviceInserted ; init this
|
|
|
|
ldx #0 ; now we walk the list, looking for ANY disk switch
|
|
@switch_loop
|
|
lda StaticDeviceTable,x
|
|
bmi @skip_it ; skip over 5.25's and non-removables
|
|
beq @skip_it ; no eject/insert here!
|
|
phx ; save index
|
|
txa ; convert to device number
|
|
lsr a
|
|
inc a ; adjust for 1-based array
|
|
sta DeviceSwitched ; set this for the update_menu subroutine
|
|
jsr update_menu ; go update the popup
|
|
plx ; retrieve index
|
|
lda StaticDeviceTable,x ;get the eject/insert bits
|
|
and #%0001 ; was the device inserted?
|
|
beq @no_insert ; no...
|
|
lda DeviceSwitched ; else save the device number
|
|
sta DeviceInserted ; so we can update the menu properly
|
|
@no_insert
|
|
stz StaticDeviceTable,x
|
|
@skip_it
|
|
inx ; step to next device
|
|
inx
|
|
cpx #128 ; maximum of 64 devices in table
|
|
bcc @switch_loop
|
|
|
|
; now that we've handled all the ejects/inserts, update the displayed menu
|
|
|
|
lda DeviceInserted ;the last device number that was inserted
|
|
bne @use_this
|
|
pha ; get the current setting
|
|
jsr PushLongVolPopup
|
|
_GetCtlValue
|
|
pla
|
|
cmp DeviceSwitched ; was the ejected device currently set?
|
|
beq @reset ; if so, reset menu to first device
|
|
@use_this
|
|
pha
|
|
jsr PushLongVolPopup
|
|
_SetCtlValue ; set popup result to name of newly inserted disk
|
|
|
|
pha ; now let's make sure it was a valid value
|
|
jsr PushLongVolPopup
|
|
_GetCtlValue
|
|
pla
|
|
bne @was_valid
|
|
@reset
|
|
pha ; space for result
|
|
pea 1 ; menu id
|
|
_CountMItems ; is there anything in the menu?
|
|
pla
|
|
beq @was_valid ; nope, just leave it set to 0
|
|
|
|
jsr SetPopup
|
|
@was_valid
|
|
pea 0 ; width
|
|
pea 0 ; height
|
|
pea 1 ; ID of menu
|
|
_CalcMenuSize
|
|
|
|
_SetMenuBar ; restore original menu bar
|
|
exit
|
|
stz DeviceSwitched ; set up for next time through the loop
|
|
|
|
plb
|
|
|
|
rtl
|
|
|
|
update_menu
|
|
;
|
|
; ----- Handle disk ejection -----------------------------------
|
|
;
|
|
doEject
|
|
|
|
; ----- Get rid of the memory for the item struct assoc. with this item
|
|
;
|
|
DPage equ 1
|
|
thePtr equ DPage+2
|
|
theHandle equ thePtr+4
|
|
|
|
lda #0 ; space for result
|
|
pha
|
|
pha
|
|
lda DeviceSwitched
|
|
pha ; that's our menu item number
|
|
ldx #$4A0F
|
|
jsl $E10000 ; GetItemStruct
|
|
bcs doInsert ; it wasn't in the menu to begin with!
|
|
lda 1,s ; was the item really there?
|
|
ora 3,s
|
|
beq doInsert ; no...
|
|
|
|
pha ; space for derefing itemstruct so we can get at
|
|
pha ; the handle to the item's name
|
|
phd
|
|
tsc
|
|
tcd
|
|
|
|
lda [<theHandle] ; deref handle to itemstruct
|
|
sta <thePtr
|
|
ldy #2
|
|
lda [<theHandle],y
|
|
sta <thePtr+2
|
|
|
|
ldy #ItemTitleRef+2 ; get rid of the handle we got for the item's name
|
|
lda [<thePtr],y
|
|
pha
|
|
ldy #ItemTitleRef
|
|
lda [<thePtr],y
|
|
pha
|
|
_DisposeHandle
|
|
|
|
pld
|
|
pla ; remove the ptr to itemstruct
|
|
pla
|
|
_DisposeHandle ; now get rid of handle to itemstruct itself (still on stack)
|
|
|
|
|
|
PushWord DeviceSwitched
|
|
_DeleteMItem ; get rid of the device ejected from the popup
|
|
|
|
bra doInsert2
|
|
|
|
;
|
|
; ----- Handle disk insertion -------------------------------------
|
|
;
|
|
doInsert
|
|
pla ;clean up stack from GetMItemStruct call
|
|
pla
|
|
doInsert2
|
|
lda DeviceSwitched
|
|
sta DevNum
|
|
_DInfoGS DInfoPBlock
|
|
bcs errorExit
|
|
_VolumeGS VolumePBlock
|
|
bcs errorExit
|
|
|
|
lda #33 ; size of memory block we want
|
|
jsr GetHandle
|
|
bcs errorExit
|
|
|
|
phx
|
|
pha
|
|
phd ; save original direct page
|
|
|
|
tsc
|
|
tcd ; turn stack into direct page so we can deref handle
|
|
|
|
origD equ 1
|
|
Handle equ origD+2
|
|
|
|
lda [<Handle]
|
|
tax
|
|
ldy #2
|
|
lda [<Handle],y
|
|
pld ; restore direct page
|
|
|
|
pha ; destination of PString
|
|
phx
|
|
PushLong #VolumeName ; GS/OS output string to convert
|
|
jsl GSOStoPString
|
|
|
|
pla ; get handle for volume name off stack and return
|
|
plx ; in a and x registers back to calling program
|
|
|
|
jsr InsertTheItem
|
|
|
|
errorExit
|
|
rts
|
|
|
|
EndP
|
|
|
|
|
|
;===========================================================
|
|
; This routine sets the popup control result to the first
|
|
; menu item in the popup.
|
|
;===========================================================
|
|
SetPopup Proc
|
|
with PopupGlobals
|
|
|
|
OrigD equ 1
|
|
theMenu equ OrigD+2
|
|
|
|
|
|
pea 0 ; space for result
|
|
pea 0 ; space for result
|
|
pea 1 ; menu ID
|
|
_GetMHandle
|
|
phd
|
|
tsc ; turn stack into direct page
|
|
tcd
|
|
|
|
ldy #2
|
|
lda [<theMenu],y
|
|
tax
|
|
lda [<theMenu]
|
|
sta <theMenu
|
|
stx <theMenu+2
|
|
|
|
ldy #ItemList ; offset to first item in the menu
|
|
lda [<theMenu],y ; first word in item record is the item id
|
|
|
|
pld ; restore original direct page
|
|
plx ; remove ptr to popup control
|
|
plx
|
|
|
|
pha ; item ID
|
|
jsr PushLongVolPopup
|
|
_SetCtlValue
|
|
|
|
rts
|
|
|
|
EndP
|
|
|
|
;===========================================================
|
|
; This routine inserts the specified volume name (handle in
|
|
; a & x registers) into the popup menu.
|
|
;===========================================================
|
|
InsertTheItem Proc
|
|
with PopupGlobals
|
|
|
|
phx ; store volume name on stack for now
|
|
pha
|
|
|
|
lda #ItemStructSize
|
|
jsr GetHandle
|
|
bcc @gotMem2
|
|
|
|
_DisposeHandle ; get rid of the handle we just got for the volume name
|
|
sec
|
|
rts
|
|
|
|
@gotMem2 phx
|
|
pha
|
|
stx ItemStruct+2 ; store handle to item struct in our menu item template
|
|
sta ItemStruct
|
|
|
|
theDPage equ 1
|
|
tempPtr equ theDPage+2
|
|
theStruct equ tempPtr+4
|
|
theVolName equ theStruct+4
|
|
|
|
phx ; make space for temporary pointer
|
|
pha
|
|
phd ; save current direct page register
|
|
tsc ; turn stack into direct page
|
|
tcd
|
|
|
|
ldy #2 ; deref handle to the item struct
|
|
lda [<theStruct],y
|
|
tax
|
|
lda [<theStruct]
|
|
sta <theStruct
|
|
stx <theStruct+2
|
|
|
|
; *** Removed 16-Mar-92 DAL, because the Menu Manager takes care of this now
|
|
;
|
|
;; Before we place the volume name into the menu, we must make sure that it isn't so
|
|
;; long that it extends into the down-arrow at the right end of the menu. If it is
|
|
;; too long, we simply reduce the length and add an ellipsis as the last displayable
|
|
;; character.
|
|
;
|
|
; lda [<theVolName],y ; deref handle to volume name
|
|
; sta <tempPtr+2
|
|
; lda [<theVolName]
|
|
; sta <tempPtr
|
|
;@shortened
|
|
; pha ; make space for result
|
|
; pei <tempPtr+2 ; string pointer
|
|
; pei <tempPtr
|
|
; _StringWidth ; how long is this sucker???
|
|
; pla
|
|
; cmp #98 ; too long?
|
|
; bcc @good_length ; nope, we can use it as is
|
|
; sep #$30 ; 8-bit registers
|
|
; longa off
|
|
; longi off
|
|
; lda [<tempPtr] ; get the length
|
|
; dec a ; reduce by 1 character
|
|
; sta [<tempPtr] ; store the new length
|
|
; tay ; index to new last character
|
|
; lda #'É' ; replace with elipsis
|
|
; sta [<tempPtr],y
|
|
; rep #$30 ; back to 16-bit accumulator
|
|
; longa on
|
|
; longi on
|
|
; bra @shortened ; go back and try again
|
|
;
|
|
;@good_length
|
|
|
|
*** 16-Mar-92 DAL -- strip leading colon off the volume name
|
|
ldy #2
|
|
lda [<theVolName],y ; deref handle to volume name
|
|
sta <tempPtr+2
|
|
lda [<theVolName]
|
|
sta <tempPtr
|
|
|
|
ldy #1
|
|
lda [<tempPtr],y
|
|
and #$00ff
|
|
cmp #$003a
|
|
bne @notColon
|
|
|
|
ldx <tempPtr+2
|
|
lda <tempPtr
|
|
clc
|
|
adc #2
|
|
bcc @1
|
|
inx
|
|
@1 phx
|
|
pha ;source = tempPtr+2
|
|
ldx <tempPtr+2
|
|
lda <tempPtr
|
|
inc a
|
|
bne @2
|
|
inx
|
|
@2 phx
|
|
pha ;dest = tempPtr+1
|
|
pea 0 ;size high = 0
|
|
lda [<tempPtr]
|
|
and #$00ff
|
|
dec a
|
|
pha ;size low = pstring length - 1
|
|
_BlockMove
|
|
|
|
lda [<tempPtr]
|
|
dec a
|
|
sta [<tempPtr]
|
|
@notColon
|
|
*** end 16-Mar-92
|
|
|
|
ldy #ItemFlag2
|
|
lda #$8000 ; bit 15 indicates item has an icon associated with it
|
|
sta [<theStruct],y
|
|
ldy #ItemTitleRef ; store item title in its new location
|
|
lda <theVolName
|
|
sta [<theStruct],y
|
|
lda <theVolName+2
|
|
iny
|
|
iny
|
|
sta [<theStruct],y
|
|
|
|
*** use GetSysIcon instead of our local hard-coded icons, 23-Apr-91 DAL
|
|
pha
|
|
pha ;space for GetSysIcon result
|
|
pea 1 ;get a device icon
|
|
lda DeviceID
|
|
pha
|
|
pha
|
|
pha ;auxvalue ignored
|
|
_GetSysIcon
|
|
pla
|
|
ldy #ItemIconRef
|
|
sta [<theStruct],y
|
|
iny
|
|
iny
|
|
pla
|
|
sta [<theStruct],y
|
|
*** end of 23-Apr-91 DAL
|
|
|
|
pld ; turn direct page back into our stack
|
|
tsc ; clean up stack
|
|
clc
|
|
adc #12
|
|
tcs
|
|
|
|
lda DevNum
|
|
sta MyItemID ; set item id to that of the device number
|
|
|
|
pea 0 ; refdesciptor = 0, ptr to item template
|
|
PushLong #MenuItemTemplate
|
|
pea $FFFF ; insert at end of list
|
|
pea 1
|
|
_InsertMItem2
|
|
|
|
clc
|
|
|
|
rts
|
|
|
|
EndP
|
|
|
|
;----------------------------------------------------------------------
|
|
;
|
|
;----------------------------------------------------------------------
|
|
AddVolumeMenu Proc Export
|
|
;
|
|
; Stack for this call...
|
|
tempDeref equ 1
|
|
tempHandle equ tempDeref+4
|
|
MyRefNum equ tempHandle+4
|
|
MyPathLevel equ MyRefNum+2
|
|
i equ MyPathLevel+2
|
|
lastDevNum equ i+2
|
|
OldDPage equ lastDevNum+2
|
|
OldDB equ OldDPage+2
|
|
theRTL equ OldDB+1
|
|
FrameSize equ theRTL
|
|
;
|
|
; Begin by setting up our stack frame......
|
|
|
|
phb
|
|
phd
|
|
tsc
|
|
sec
|
|
sbc #FrameSize
|
|
tcd
|
|
tcs
|
|
|
|
phk
|
|
plb
|
|
; First, build a list of volume names
|
|
;END
|
|
|
|
jsr CreatePopUp ; call NewControl2 to create, and the add all
|
|
; ; the names of all volumes on-line into the popup
|
|
; end; {procedure}
|
|
EndVolMenu
|
|
tdc ; unlink our local frame
|
|
clc
|
|
adc #FrameSize
|
|
tcs ; make it our current stack
|
|
pld ; recover the orihginal dpage
|
|
plb
|
|
RTL
|
|
|
|
|
|
;===========================================================
|
|
;
|
|
; CreatePopup
|
|
;
|
|
; This routine creates an empty popup control, makes
|
|
; the popup control the current menubar, then adds
|
|
; all the names of the volumes on-line into the popup
|
|
; and then restores the original menubar.
|
|
;
|
|
;===========================================================
|
|
CreatePopup
|
|
_WaitCursor
|
|
|
|
pha ; space for result from NewControl2
|
|
pha
|
|
PushLong >idleWind ; push grafport ptr
|
|
PushWord #0 ; input ref is a pointer to a single item template
|
|
PushLong #PopUpControl1
|
|
_NewControl2
|
|
pla
|
|
sta >VolPopUp
|
|
pla
|
|
sta >VolPopUp+2
|
|
|
|
pha ; space for handle to menubar
|
|
pha
|
|
_GetMenuBar ; save current menubar, leave handle on stack
|
|
|
|
jsr PushLongVolPopup ; set menubar to popup menu so we can
|
|
_SetMenuBar ; operate on the popup
|
|
|
|
jsr AddItems ; find all volumes on-line and insert into popup
|
|
|
|
pea 0 ; calculate height and width of newly formed
|
|
pea 0 ; volumes popup
|
|
pea 1 ; ID of menu to calculate
|
|
_CalcMenuSize
|
|
|
|
_SetMenuBar ; Restore original menubar
|
|
|
|
_InitCursor
|
|
|
|
rts
|
|
|
|
; ---------------------------------------------------------------------
|
|
; NewControl2 template for a popup control.
|
|
; ---------------------------------------------------------------------
|
|
PopUpControl1 dc.w 9 ; pcount
|
|
dc.l 1 ; ID of control
|
|
dc.w 5+1,10,18,220 ; rectangle for popup control (8-Dec-91 DAL)
|
|
dc.l $87000000 ; popup procref
|
|
dc.w $0060 ; type 2 popup, don't hilite title, {right justify title}
|
|
dc.w $10A0 ; more flags, fctlProcNotPtr, fDrawIconInResult, fDrawArrowIcon
|
|
dc.l 0 ; no refcon
|
|
dc.w 0 ; title width
|
|
dc.l PopupMenu1 ; ptr to menu item list
|
|
dc.w 1 ; initial value of popup selection
|
|
|
|
PopupMenu1 dc.w 0 ; version, must be zero
|
|
xMenuID dc.w 1 ; id of popup menu
|
|
dc.w $0000 ; menu flag
|
|
dc.l PopupTitle1 ; title of popup menu
|
|
dc.l 0000 ; no items, empty menu
|
|
|
|
PopupTitle1 str 'Disks: '
|
|
|
|
;==================================================
|
|
;
|
|
; AddItems
|
|
;
|
|
; This routine calls routine GetNextVolume, which
|
|
; returns the next volume that is online. This
|
|
; volume is then inserted into the "volumes" popup.
|
|
;
|
|
;==================================================
|
|
AddItems
|
|
With popUpGlobals
|
|
|
|
; First we zero out the device table
|
|
|
|
ldx #128
|
|
@ZeroLoop stz StaticDeviceTable-2,x
|
|
dex
|
|
dex
|
|
bne @ZeroLoop
|
|
|
|
stz DevNum ; start looking starting at DevNum = 1
|
|
|
|
;
|
|
; ----------- First make sure the popup is empty -------------------------
|
|
;
|
|
pha ; space for result
|
|
pea 1 ; ID of menu we want
|
|
_CountMItems
|
|
pla
|
|
sta Count
|
|
|
|
beq @PopupEmpty
|
|
|
|
pea 0 ; new value of popup selection
|
|
jsr PushLongVolPopup ; this erases current result
|
|
_SetCtlValue
|
|
|
|
@DeleteAnother pea $FFFF ; to delete last item
|
|
_DeleteMItem
|
|
|
|
dec Count
|
|
lda Count
|
|
bne @DeleteAnother
|
|
|
|
pea 0 ; width
|
|
pea 0 ; height
|
|
pea 1 ; ID of menu
|
|
_CalcMenuSize
|
|
|
|
lda >MyID
|
|
ora #$0600
|
|
pha
|
|
_DisposeAll ; get rid of all other handles allocated for volume names
|
|
|
|
@PopupEmpty lda #0
|
|
sta >getVolNameFlag
|
|
InsertNext
|
|
jsr GetNextVolume ; returns with a & x set to ptr to the volume name
|
|
bcs NoMoreVolumes
|
|
|
|
jsr InsertTheItem
|
|
bcc InsertNext
|
|
|
|
NoMoreVolumes
|
|
jsr SetPopup ; sets result of popup to first menu item
|
|
|
|
stz DeviceSwitched
|
|
|
|
rts
|
|
|
|
|
|
;==================================================
|
|
;
|
|
; GetNextVolume
|
|
;
|
|
; This routine returns the volume name of the next
|
|
; volume that is on-line.
|
|
;
|
|
; Each time into this routine we bump the device
|
|
; number to use as input to _DInfo so we always get
|
|
; the next device. _DInfo returns the device name
|
|
; which in turn is used as input to _Volume which
|
|
; returns the volume name.
|
|
;
|
|
; For each new device that we ecounter we get a new
|
|
; handle to store this name.
|
|
;
|
|
; When we finally get error $11(invalid device number)
|
|
; from _DInfo we know there are no more devices.
|
|
; We set the carry upon exit from this routine when
|
|
; we encounter this error.
|
|
;
|
|
; GetNextVolume always returns either a valid volume
|
|
; name or carry set which means no more volumes found.
|
|
;
|
|
; OUT: a = low word of handle to volume
|
|
; x = high word of handle to volume
|
|
;
|
|
;==================================================
|
|
export GetNextVolume
|
|
GetNextVolume
|
|
with popUpGlobals
|
|
|
|
import GSOStoPString
|
|
|
|
|
|
NextDevice inc DevNum ; bump the device number to search
|
|
|
|
_DInfoGS DInfoPBlock ; make GS/OS call
|
|
bcc NoError
|
|
|
|
cmp #$11 ; check for "invalid device number" error
|
|
; if we get this then we're done
|
|
bne NoError
|
|
brl NoMoreDevices
|
|
NoError
|
|
lda DeviceID
|
|
bne MakeVolumeCall
|
|
|
|
;
|
|
; ----- We've got a 5.25 drive -----------------------------------------
|
|
;
|
|
lda DevNum
|
|
sta DStatDevNum
|
|
_DStatusGS DStatusPBlock
|
|
|
|
lda StatusWord
|
|
and #$0010 ; Is there a disk in the 5.25 drive
|
|
beq NextDevice ; If OS says there is then the drive is on-line, else...
|
|
|
|
jsr InsertIntoList
|
|
|
|
lda #DevName
|
|
sta theName
|
|
lda #^DevName
|
|
sta theName+2
|
|
bra doNewHandle
|
|
|
|
MakeVolumeCall
|
|
_VolumeGS VolumePBlock
|
|
bcs NextDevice ; if we get an error then we need to go to next device
|
|
lda #VolumeName
|
|
sta theName
|
|
lda #^VolumeName
|
|
sta theName+2
|
|
|
|
lda Characteristics
|
|
and #$0004 ; Check if this device contains removable media
|
|
bne doNewHandle
|
|
jsr InsertIntoList
|
|
|
|
doNewHandle
|
|
lda #33 ; size of memory block we want
|
|
|
|
jsr GetHandle ; a = low word of handle, x = high word
|
|
bcs NoMoreDevices ; get out if we couldn't get the memory to store the name
|
|
|
|
phx
|
|
pha
|
|
phd ; save original direct page
|
|
|
|
tsc
|
|
tcd ; turn stack into direct page so we can deref handle
|
|
|
|
origD equ 1
|
|
Handle equ origD+2
|
|
|
|
lda [<Handle]
|
|
tax
|
|
ldy #2
|
|
lda [<Handle],y
|
|
pld ; restore direct page
|
|
|
|
pha ; destination of PString
|
|
phx
|
|
PushLong theName ; GS/OS output string to convert
|
|
jsl GSOStoPString
|
|
|
|
pla ; get handle for volume name off stack and return
|
|
plx ; in a and x registers back to calling program
|
|
|
|
clc ; no error
|
|
rts
|
|
|
|
NoMoreDevices sec
|
|
rts
|
|
|
|
EndP
|
|
|
|
;==================================================
|
|
;
|
|
; GetHandle
|
|
;
|
|
; IN: a = number of bytes to allocate
|
|
;
|
|
; OUT: carry clear is handle allocated, a+x = handle
|
|
; carry set if error, y = error returned by Mem Mgr
|
|
;
|
|
;==================================================
|
|
GetHandle PROC
|
|
with popUpGlobals
|
|
|
|
pha ; space for returned handle
|
|
pha
|
|
pea 0 ; high word of size
|
|
pha ; low word of size, passed as input to routine
|
|
lda >MyID
|
|
ora #$0600 ; set ID to $x1xx so we can get rid of this memory easily
|
|
pha
|
|
pea 0 ; no attributes
|
|
pha
|
|
pha
|
|
_NewHandle
|
|
tay
|
|
pla ; a = low word
|
|
plx ; x = high word
|
|
|
|
rts
|
|
|
|
|
|
EndP
|
|
|
|
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; InsertIntoList
|
|
;
|
|
; Inserts device into list of non-removable media devices. This is
|
|
; the list that is used to determine whether a device should be
|
|
; polled for disk switch or not. (i.e. should we make the DStatus
|
|
; call on the device) Apple 5.25 drives are also included in this
|
|
; list.
|
|
;
|
|
;------------------------------------------------------------------
|
|
InsertIntoList PROC
|
|
with PopUpGlobals
|
|
|
|
lda DevNum ;use device number as index into this list
|
|
cmp #65 ;beyond our 64-device limit?
|
|
bcs @skip_it ;yes, just ignore it
|
|
|
|
asl a
|
|
tax
|
|
lda #$8000
|
|
@StoreIt sta StaticDeviceTable-2,x
|
|
@skip_it
|
|
rts
|
|
|
|
ENDP
|
|
|
|
;------------------------------------------------------------------
|
|
; 22-May-91 MSD Now saves device number that we'll be searching
|
|
; in a separate variable so that we can use it
|
|
; later to display the correct volume icon in the
|
|
; path display for a file.
|
|
;
|
|
;------------------------------------------------------------------
|
|
MakeCurPath Proc Export
|
|
with popUpGlobals
|
|
import GetNextVolume
|
|
;
|
|
OldDPage equ 1
|
|
OldDBank equ OldDPage+2
|
|
theRTL equ oldDBank+1
|
|
theResult equ theRTL+3
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
phd
|
|
tsc
|
|
tcd
|
|
|
|
lda #$FFFF
|
|
sta theResult
|
|
|
|
pha
|
|
jsr PushLongVolPopup
|
|
_GetCtlValue
|
|
pla
|
|
sta SearchDevNum ; remember device number we're searching (22-May-91 MSD)
|
|
sta DevNum
|
|
_DInfoGS DInfoPBlock ; find out the device name
|
|
bcs ErrorExit
|
|
noError
|
|
_VolumeGS VolumePBlock ; now get the volume name
|
|
bcs ErrorExit
|
|
|
|
PushLong #CurrentDirPath
|
|
PushLong #VolumeName
|
|
jsl GSOStoPString ; convert to pstring
|
|
|
|
gotPath
|
|
lda >CurrentDirPath
|
|
inc a
|
|
sta >CurrentDirPath
|
|
and #$00FF
|
|
tax
|
|
lda #':'
|
|
sta >CurrentDirPath,x
|
|
exit pld
|
|
plb
|
|
rtl
|
|
|
|
ErrorExit
|
|
stz theResult
|
|
|
|
PushLong #theMessage
|
|
jsl SetMessage
|
|
bra exit
|
|
|
|
theMessage dc.B textEnd-textStart
|
|
textStart dc.B $01,$4A,$00,$00
|
|
dc.B 'Problems reading the disk.'
|
|
textEnd
|
|
EndP
|
|
|
|
|
|
*******************************************************************************
|
|
*
|
|
* MakeSureExtraToolsAreHere -- load and start other tools as needed
|
|
*
|
|
*******************************************************************************
|
|
MakeSureExtraToolsAreHere proc export
|
|
|
|
*** removed 26-Jan-93 SS -- not needed in 6.0
|
|
; pea 0
|
|
; _QDAuxStatus
|
|
; pla
|
|
; bne @ok
|
|
;
|
|
;@again pea $0012 ;tool number = QD Aux
|
|
; pea $0304 ;version 3.4
|
|
; _LoadOneTool
|
|
; bcs @again
|
|
;
|
|
; _QDAuxStartUp
|
|
;@ok
|
|
*** end 26-Jan-93
|
|
|
|
*** added 24-Sep-91 DAL -- make sure List Manager is here, too
|
|
pea 0
|
|
_ListStatus
|
|
pla
|
|
bne @ListOK
|
|
|
|
@listAgain pea $001C ;tool number = List Manager
|
|
pea $0303 ;version 3.3
|
|
_LoadOneTool
|
|
bcs @listAgain
|
|
|
|
_ListStartUp
|
|
@ListOK
|
|
*** end 24-Sep-91
|
|
rtl
|
|
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
GetUpTextFromLE PROC Export
|
|
*
|
|
* Description: This routine returns a Pascal string from a line edit item
|
|
* that is all upper case. All you do is pass the LERechandle
|
|
* and I do the rest!
|
|
*
|
|
*
|
|
* Inputs: theLERecHandle:Handle
|
|
* theStr:Str32;
|
|
*
|
|
* Outputs: none
|
|
*
|
|
* External Refs: none
|
|
*
|
|
* Entry Points: none
|
|
*
|
|
*******************************************************************************
|
|
;
|
|
; Stack frame for this call...
|
|
tempPtr equ 1
|
|
oldDPage equ tempPtr+4
|
|
theRTL equ oldDPage+2
|
|
theStr equ theRTL+3
|
|
theLERecHandle equ theStr+4
|
|
;
|
|
; First link a stack frame...
|
|
phd
|
|
pha
|
|
pha
|
|
tsc
|
|
tcd
|
|
|
|
;
|
|
; Now get the length of the text we are going to use...
|
|
pha
|
|
pei theLERecHandle+2
|
|
pei theLERecHandle
|
|
_LEGetTextLen
|
|
tax
|
|
pla
|
|
bcc @cont
|
|
brl Anerror
|
|
|
|
@Cont sta [theStr] ; save the length in the string...
|
|
beq Done ; if its zero, then we are done!
|
|
;
|
|
; Now get the string handle from line edit...
|
|
pha
|
|
pha
|
|
pei theLERecHandle+2
|
|
pei theLERecHandle
|
|
_LEGetTextHand
|
|
tax
|
|
pla
|
|
sta tempPtr
|
|
pla
|
|
sta tempPtr+2
|
|
bcc @Cont1
|
|
brl AnError
|
|
;
|
|
; Now that we have all the data move it into the string!
|
|
@Cont1
|
|
ldy #2 ; deref the handle
|
|
lda [tempPtr],y
|
|
tax
|
|
lda [tempPtr]
|
|
bne @ItsOK
|
|
dec a
|
|
dex
|
|
bra @cont3
|
|
@ItsOK
|
|
dec a ; remember to remember the based data
|
|
@Cont3 sta tempPtr
|
|
stx tempPtr+2 ; we now have a pointer to that data!
|
|
|
|
lda [theStr]
|
|
tay ; init our counter...
|
|
sep #$20
|
|
longa Off
|
|
@Loop
|
|
lda [tempPtr],y
|
|
cmp #'A'
|
|
blt @Loop10
|
|
cmp #'Z'+1
|
|
bge @Loop10
|
|
ora #$20
|
|
@Loop10 sta [theStr],y
|
|
dey
|
|
bne @Loop
|
|
rep #$20
|
|
longA On
|
|
Done
|
|
pla ; unlink the stack
|
|
pla
|
|
pld
|
|
sep #$20
|
|
longa Off
|
|
pla
|
|
ply
|
|
|
|
plx
|
|
plx
|
|
plx
|
|
plx
|
|
|
|
phy
|
|
pha
|
|
rep #$20
|
|
longa On
|
|
RTL
|
|
AnError txa
|
|
sta AsmToolErr
|
|
bra Done
|
|
EndP
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
CreatePathList PROC Export
|
|
with PopupGlobals
|
|
*
|
|
* Description: This routine will take a pointer to a string and turn it into
|
|
* a list to be displayed by the list manager.
|
|
*
|
|
*
|
|
* Inputs: theStr:str255
|
|
*
|
|
* Outputs: None
|
|
*
|
|
* External Refs:
|
|
*
|
|
* Entry Points:
|
|
*
|
|
*******************************************************************************
|
|
; My member record for use with the passed member record
|
|
MemString equ 0 ; 4
|
|
MemFlag equ MemString+4 ; 6
|
|
MemFullName equ MemFlag+2 ; 10
|
|
MemType equ MemFullName+4 ; 12
|
|
MemAux equ MemType+2 ; 16
|
|
MemEOF equ MemAux+4 ; 20 member record is 20 bytes...
|
|
MemRecSize equ MemEOF+4
|
|
;
|
|
;
|
|
tempPtr equ 1
|
|
tempInt equ tempPtr+4
|
|
OldDBank equ tempInt+2
|
|
OldDPage equ OldDBank+1
|
|
theRTL equ OldDPage+2
|
|
theInStr equ theRTL+3
|
|
ThisRtnAux equ $0300 ; subID for all memory used by this routine
|
|
;
|
|
; First thing, get rid of any old pathlist data...
|
|
lda >MyID
|
|
ora #ThisRtnAux
|
|
pha
|
|
_DisposeAll ; dump the old handles
|
|
|
|
phd
|
|
phb
|
|
phk
|
|
plb ; switch to this databank...
|
|
pha
|
|
pha
|
|
pha
|
|
tsc
|
|
tcd ; set up our stack frame...
|
|
;
|
|
; Now clean out my pathname list list...
|
|
ldx #SizeOfPathList-2
|
|
lda #0
|
|
@CleanLoop sta PathList,x
|
|
dex
|
|
dex
|
|
bpl @CleanLoop
|
|
;
|
|
; Now that the path list is all cleaned out, let's create the list of names!
|
|
;
|
|
lda [theInStr] ; set the current length
|
|
and #$00FF
|
|
sta PathLeft
|
|
jsr StripFileName ; strip off the first file name throw it away
|
|
stz <TempInt ; create item number 0!
|
|
@NextName
|
|
; To Add a name to the list, allocate a handle for its file name...
|
|
jsr StripFileName ; get the next level up...
|
|
ldx #0
|
|
pha ; room for result
|
|
pha
|
|
phx ; size of handle
|
|
pha ; <A> has size of handle to get...
|
|
lda >MyID
|
|
ora #ThisRtnAux ; special stack memory
|
|
pha
|
|
pea $4000 ; fixed
|
|
phx
|
|
phx ;
|
|
_NewHandle
|
|
pla
|
|
sta <TempPtr
|
|
pla
|
|
sta <TempPtr+2
|
|
lda [tempPtr]
|
|
tax
|
|
ldy #2
|
|
lda [tempPtr],y
|
|
sta <tempPtr+2
|
|
stx <TempPtr ; deref the handle...
|
|
; now copy the file name into the handle...
|
|
lda tempNameBuf ; get the length of the string...
|
|
and #$00FF
|
|
tay
|
|
longa off
|
|
sep #$20
|
|
@CPLoop lda TempNameBuf,y
|
|
sta [TempPtr],y
|
|
dey
|
|
bpl @CPLoop
|
|
rep #$20
|
|
longa on
|
|
; now build the proper list entry...
|
|
lda <tempInt ; get the entry number
|
|
asl a ; multiply it by 20.. (list size...)
|
|
asl a ; by 4
|
|
pha
|
|
asl a
|
|
asl a ; by 16
|
|
clc
|
|
adc 1,s ; create *20
|
|
plx ; discard our temp..
|
|
tax ; and put the offset into <X>
|
|
|
|
lda <TempPtr
|
|
sta PathList+MemString,x
|
|
lda <TempPtr+2
|
|
sta PathList+MemString+2,x
|
|
; set the flags...
|
|
lda #$000F ; say its a folder for now...
|
|
sta PathList+MemType,x
|
|
lda #$8060
|
|
sta PathList+MemFlag,x
|
|
; and the entry is made! Now, determine if we need to get more stuff
|
|
lda PathLeft
|
|
beq @ListDone
|
|
lda <tempInt ; bump the list entry count
|
|
cmp #$000F ; we at 16 entries yet?
|
|
bge @ListTooBig
|
|
inc a
|
|
sta <TempInt
|
|
brl @NextName ; and do another entry
|
|
@ListDone
|
|
; Note at this point <X> still points to our list entry
|
|
lda #$0001
|
|
sta PathList+MemType,x
|
|
@ListTooBig
|
|
; Now its time to do the new list2 call on this here list...
|
|
; PathList:=getCtlHandleFromID(IdleWind,1015 + screenMode);
|
|
; ShowControl(PathList);
|
|
PushLong #MyMemberDraw
|
|
pea 1
|
|
PushLong #PathList
|
|
pea 0
|
|
lda <tempint
|
|
inc a
|
|
pha
|
|
;
|
|
pha
|
|
pha
|
|
PushLong >IdleWind
|
|
ldx #0
|
|
lda >screenMode
|
|
clc
|
|
adc #1015
|
|
bcc @1
|
|
inx
|
|
@1 phx
|
|
pha
|
|
_GetCtlHandleFromID
|
|
_NewList2
|
|
; now the list is made and can be displayed at will!
|
|
pla
|
|
pla
|
|
pla
|
|
plb
|
|
pld
|
|
longa off
|
|
sep #$20
|
|
pla
|
|
ply
|
|
plx
|
|
plx
|
|
phy
|
|
pha
|
|
longa On
|
|
Rep #$20
|
|
rtl
|
|
;
|
|
; This next routine strips a file name down to the colon and stores it in
|
|
; the temp buffer...
|
|
StripFileName
|
|
longa off
|
|
sep #$20
|
|
ldy PathLeft ; index into the string
|
|
ldx #0 ; index into tempnamebuf
|
|
@StripLoop1 lda [theInStr],y ; get the next value...
|
|
dey ; lower our string counter..
|
|
inx
|
|
cmp #':' ; if its a colon the pathname is over..
|
|
bne @StripLoop1
|
|
; ok, we now know the length of the string to move and
|
|
; now copy the string...
|
|
stx TempNameBuf ; save the string length first!
|
|
cpx #0
|
|
beq @SL2Done
|
|
ldy PathLeft
|
|
@StripLoop2 lda [theInStr],y
|
|
;;; sta TempNameBuf,x
|
|
*** 8-Dec-91 DAL
|
|
cpx #1
|
|
beq @skipColon
|
|
sta TempNameBuf-1,x
|
|
@skipColon
|
|
*** end 8-Dec-91 DAL
|
|
dey
|
|
dex
|
|
bne @StripLoop2
|
|
@SL2Done
|
|
; the string is done, now update the PathLeft Value...
|
|
sty PathLeft ; and save the value...
|
|
|
|
*** 8-Dec-91 DAL
|
|
dec TempNameBuf ;we skipped the leading colon
|
|
*** end 8-Dec-91
|
|
|
|
lda TempNameBuf ; get the length in <A>
|
|
rep #$20
|
|
longa On
|
|
and #$00FF
|
|
inc a ; account for the length byte
|
|
rts ; and return
|
|
|
|
PathLeft ds.W 1
|
|
PathList ds.B MemRecSize*16 ; allow 16 levels of directories...
|
|
SizeOfPathList equ *-PathList ; bytes in our local pathlist..
|
|
TempNameBuf ds.B 32 ; enough to hold a single pathname
|
|
endp
|
|
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
MyMemberDraw PROC Export
|
|
with PopupGlobals
|
|
*
|
|
* Description: Procedure used to draw members in my list. This procedure will
|
|
* take care of drawing each member in the list as well as drawing
|
|
* the proper small icon to the left of it.
|
|
*
|
|
*
|
|
*
|
|
; My member record for use with the passed member record
|
|
MemString equ 0
|
|
MemFlag equ MemString+4
|
|
MemFullName equ MemFlag+2
|
|
MemType equ MemFullName+4
|
|
MemAux equ MemType+2
|
|
MemEOF equ MemAux+4
|
|
* Inputs: None
|
|
*
|
|
* Outputs: None
|
|
*
|
|
* External Refs:
|
|
*
|
|
* Entry Points:
|
|
*
|
|
*******************************************************************************
|
|
; theStack
|
|
thedPage equ 1
|
|
theRTL equ thedPage+2
|
|
ListHndl equ theRTL+3
|
|
memPtr equ ListHndl+4
|
|
rectPtr equ memPtr+4
|
|
|
|
phd ; save the old dpage
|
|
tsc
|
|
tcd
|
|
|
|
pei <rectPtr+2
|
|
pei <rectPtr
|
|
_EraseRect ; erase the old rectangle...
|
|
|
|
ldy #2
|
|
lda [rectPtr],y ; get the Y coordinant
|
|
clc
|
|
adc #28
|
|
tax ; save for a bit
|
|
lda >screenMode ; 320 or 640 mode?
|
|
cmp #640
|
|
beq @its_640 ; 640, position is correct
|
|
txa ; get calculated position
|
|
sec
|
|
sbc #13 ; adjust for "narrower" icon in 320 mode
|
|
tax
|
|
@its_640
|
|
phx ; put horizontal position on stack
|
|
iny
|
|
iny
|
|
lda [rectPtr],y
|
|
dec a
|
|
pha
|
|
_MoveTo ; move to the proper spot
|
|
|
|
ldy #2
|
|
lda [memPtr],y
|
|
pha
|
|
lda [memPtr]
|
|
pha
|
|
_Drawstring
|
|
;
|
|
; Now that the member string has been drawn its time to draw the
|
|
; proper icon for this item...
|
|
;
|
|
|
|
*** 23-Apr-91 DAL -- use GetSysIcon instead of our local hard-coded icon tables
|
|
*** 22-May-91 MSD -- Use SearchDevNum for device number instead of the volume
|
|
*** selected in the volume pop-up. This fixes the bug where
|
|
*** the user changes the volume pop-up and that icon gets used
|
|
*** in the path display when you click on a found file.
|
|
|
|
pha
|
|
pha ;space for GetSysIcon result
|
|
|
|
ldy #memFlag
|
|
lda [memPtr],y
|
|
bpl @notDevice ; high bit = the bottom list; everything is device/folder
|
|
|
|
ldy #memType
|
|
lda [<memPtr],y
|
|
cmp #$000f
|
|
beq @notDevice
|
|
|
|
lda >SearchDevNum ; get volume actually searched (22-May-91 MSD)
|
|
sta >DevNum
|
|
_DInfoGS DInfoPBlock
|
|
lda >DeviceID
|
|
pea 1 ;flag for device icon
|
|
pha ;device ID
|
|
pea 0 ;moved here 5-Oct-92 DAL
|
|
pea 0 ;moved here from below (auxtype value)
|
|
bra @common
|
|
|
|
@notDevice ldy #memFlag ;use open folders for bottom list
|
|
lda [<memPtr],y
|
|
rol a
|
|
rol a
|
|
rol a
|
|
and #$0004
|
|
pha ;flag = 0 or 4
|
|
ldy #memType
|
|
lda [<memPtr],y
|
|
pha ;push file type
|
|
*** 5-Oct-92 DAL -- pass a real auxiliary type, not always zero
|
|
ldy #memAux+2
|
|
lda [<memPtr],y
|
|
pha
|
|
dey
|
|
dey
|
|
lda [<memPtr],y
|
|
pha
|
|
*** end 5-Oct-92
|
|
|
|
@common _GetSysIcon
|
|
|
|
*** end of 23-Apr-91 DAL (icon pointer now on stack)
|
|
|
|
pea 0 ; display mode
|
|
|
|
ldy #2 ; upper left corner of where icon is to go
|
|
lda [RectPtr],y
|
|
inc a
|
|
pha
|
|
lda [RectPtr]
|
|
inc a
|
|
pha
|
|
_DrawIcon
|
|
|
|
@IconDone
|
|
;
|
|
; At this point its time to dim or select the item...
|
|
ldy #MemFlag
|
|
lda [memPtr],y
|
|
and #$00C0 ; test to see if its selected
|
|
beq memDrawn
|
|
cmp #$0080
|
|
bne noSelect
|
|
|
|
pei <rectPtr+2
|
|
pei <rectPtr
|
|
_InvertRect
|
|
; bra memDrawn ;*** removed 26-Jan-93 SS
|
|
noSelect
|
|
; To support Item Dimming for non-selectable items, uncomment the following
|
|
; 6 lines of code. NOTE This has been left out because we don't want to dim in findfile...
|
|
; PushLong #DimMask
|
|
; _SetPenMask
|
|
; PushLong RectPtr
|
|
; _EraseRect
|
|
; PushLong #NorMask
|
|
; _SetPenMask
|
|
memDrawn
|
|
|
|
; clean up the stack
|
|
lda theRTL+1
|
|
sta theRTL+13 ; mopve the return address down 12
|
|
lda theRTL
|
|
sta theRTL+12
|
|
pld ; restore the original dpage
|
|
|
|
pla ; remove the passed parms
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
rtl ; and just exit...
|
|
|
|
tempRect ds.W 4 ; used for drawing and masking...
|
|
|
|
EndP
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
ProcessLevel Proc Export
|
|
*
|
|
* Description: This routine will recursively step down directories
|
|
* adding items to our file list as it goes...
|
|
*
|
|
*
|
|
* Inputs: SpudFlag:Integer; Who called me...
|
|
*
|
|
* Outputs: None
|
|
*
|
|
* External Refs:
|
|
*
|
|
* Entry Points:
|
|
*
|
|
*******************************************************************************
|
|
;
|
|
; Stack for this call...
|
|
;
|
|
tempDeref equ 1
|
|
tempHandle equ tempDeref+4
|
|
MyRefNum equ tempHandle+4
|
|
MyPathLevel equ MyRefNum+2
|
|
i equ MyPathLevel+2
|
|
OldDPage equ i+2
|
|
theRTL equ OldDPage+2
|
|
passedFlag equ theRTL+2
|
|
FrameSize equ theRTL
|
|
;
|
|
; Nonframed equates
|
|
;
|
|
spudDPage equ 1
|
|
spudRTL equ 1
|
|
spudFlag equ spudRTL+3 ; so we can read the flag proper...
|
|
spudresult equ spudflag+2
|
|
|
|
; Always zero out tool error here!
|
|
lda #0
|
|
sta >AsmToolErr
|
|
|
|
; Now, before we start this function let's look at the spudflag and determine if we need to
|
|
; swap in our alternate stack...
|
|
lda spudFlag,s ; zero means called from pascal set up the stack stuff
|
|
bpl @notReentry
|
|
brl @ReEntry ; if negative means this is a reentry
|
|
@notReentry bne @Running ; if non-zero positive then we are currently running
|
|
lda >StackHandle+1 ; see if we are still running
|
|
bne @Running ; if this is non-zero then nope...
|
|
;
|
|
; If we are here then the DA is not yet started to search. This will now allocate a new
|
|
; stack for us to use...
|
|
ldx #0
|
|
pha ; room for result
|
|
pha
|
|
phx ; size of handle
|
|
pea $0800 ; in this case a 2k stack...
|
|
lda >MyID
|
|
ora #$0900 ; special stack memory
|
|
pha
|
|
pea $4005 ; fixed page align in abs bank
|
|
phx
|
|
phx ; X MUST BE ZERO!!!!
|
|
_NewHandle
|
|
tax ; save the error code for now!
|
|
pla
|
|
sta >StackHandle
|
|
pla
|
|
sta >StackHandle+2
|
|
bcc @gotStack
|
|
txa
|
|
sta >AsmToolErr ; save the tool error!
|
|
brl ProcessError1
|
|
@GotStack
|
|
; now deref the stack handle...
|
|
; get the pascal stack value
|
|
tsc ; get the current stack pointer
|
|
sta >PascalStack ; save the current stack level
|
|
tdc ;GACK! This was a TCD. 24-Sep-91 DAL
|
|
sta >PascalDPage ; also save the pascal dpage
|
|
|
|
phd
|
|
lda >StackHandle+2 ; we wanna deref this in fact...
|
|
pha ; we need to deref something...
|
|
lda >StackHandle
|
|
pha ; so give me some stack for a second...
|
|
tsc
|
|
tcd
|
|
lda [1] ; get our stack pointer
|
|
plx ; undo the temp direct page
|
|
plx
|
|
pld
|
|
clc
|
|
adc #$07F0 ; put us at the end!
|
|
sta >StackLevel ; save the new stack pointer into <X>
|
|
|
|
; we come here when we know that we already have a stack allocated
|
|
; this code will swap out the old stack and swap in the new stack if needed
|
|
tcs ; make it the new stack
|
|
lda #0 ; shortcut the next 2 lines
|
|
pha
|
|
; pea 0 ; and zero recursion stack its the end..
|
|
; lda #0 ; zero out the entry count
|
|
sta >EntryCount ; so we know when to exit properly
|
|
bra @EntryCont ; fininish the entry
|
|
brl Repeat ; now the proper stack is in place so continue
|
|
@running
|
|
; we come here when we know that we already have a stack allocated
|
|
; this code will swap out the old stack and swap in the new stack if needed
|
|
tsc ; get the current stack pointer
|
|
sta >PascalStack ; save the current stack level
|
|
tdc ;GACK! This was a TCD too! 24-Sep-91 DAL
|
|
sta >PascalDPage ; also save the pascal dpage
|
|
|
|
lda >StackLevel ; get the asynch stack pointer
|
|
tcs ; make it the new stack
|
|
pld ; get the proper direct page
|
|
pea 0 ; and zero recursion stack its the end..
|
|
lda #0 ; zero out the entry count
|
|
sta >EntryCount ; so we know when to exit properly
|
|
brl Repeat ; now the proper stack is in place so continue
|
|
@ReEntry
|
|
tsc ; get the current stack pointer
|
|
pha ; save it on the stack...
|
|
@EntryCont
|
|
; now enter the function proper
|
|
;
|
|
; Begin by setting up our stack frame......
|
|
phd
|
|
tsc
|
|
sec
|
|
sbc #FrameSize
|
|
tcd
|
|
tcs
|
|
|
|
;
|
|
; Now that our frame is set up, let's get to work...
|
|
; MyOpenRec.openPathname:=@currentDirPath;
|
|
|
|
lda #CurrentDirPath>>16
|
|
sta >MyOpenRec+4
|
|
lda #CurrentDirPath
|
|
sta >MyOpenRec+2
|
|
lda #0
|
|
sta >MyOpenRec
|
|
|
|
; OpenPD(MyOpenRec);
|
|
_OpenPD MyOpenRec
|
|
bcc @1
|
|
cmp #$45 ;VolNotFound?
|
|
bne @otherError
|
|
sta >Stopping
|
|
@otherError
|
|
sta >AsmToolErr
|
|
brl EndProcLevel
|
|
@1
|
|
|
|
; MyRefNum:=MyOpenRec.Openrefnum;
|
|
lda >MyOpenRec
|
|
sta <MyRefNum
|
|
|
|
; MyDirEntry.base:=1;
|
|
; MyDirEntry.Displacement:=1;
|
|
lda #1
|
|
sta >MyDirEntry+4
|
|
sta >MyDirEntry+6
|
|
|
|
; MyDirEntry.NameBuffer:=@tempNamePtr;
|
|
lda #TempNamePtr>>16
|
|
sta >MyDirEntry+$000A
|
|
lda #TempNamePtr
|
|
sta >MyDirEntry+$0008
|
|
|
|
; tempNamePtr.stat:=16;
|
|
lda #40
|
|
sta >TempNamePtr
|
|
|
|
Repeat
|
|
; For proper asynch operation, we must now test the entrycount first, if we
|
|
; have passed our threshold of entries then we need to back out for now...
|
|
lda >EntryCount ; get the current entry count
|
|
cmp #MaxPerLevel ; have we done the proper number yet?
|
|
blt @Repeatcont
|
|
brl AsynchExit ; else exit asynch level
|
|
@RepeatCont
|
|
; MyDirEntry.refnum:=MyRefNum;
|
|
lda <MyRefNum
|
|
sta >MyDirEntry
|
|
;
|
|
; Now we determine if we should stop now.
|
|
lda >Stopping
|
|
bne @BetterStop ; if the flag is non-zero then we must stop
|
|
; Get_Dir_Entry(MyDirEntry);
|
|
_Get_Dir_Entry MyDirEntry
|
|
bcc @2
|
|
cmp #$45 ; Volume Not Found?
|
|
bne @BetterStop ; no, exit normally
|
|
sta >Stopping ; else make sure we stop completely
|
|
@BetterSTop brl GDEError
|
|
|
|
; if AsmToolErr=0 then
|
|
; begin
|
|
; tempString[0]:=char(tempNamePtr.length); {Set the length of the string}
|
|
@2
|
|
;
|
|
; First bump the entry count to indicate we got a good one
|
|
lda >EntryCount
|
|
inc a
|
|
sta >EntryCount
|
|
|
|
lda >TempNamePtr+2
|
|
sep #$20
|
|
Longa Off
|
|
sta >tempString
|
|
rep #$20
|
|
Longa On
|
|
|
|
; for i:=1 to 32 do
|
|
; tempString[i]:=tempNamePtr.theName[i];
|
|
ldx #0
|
|
@CopyLoop1
|
|
lda >tempNamePtr+4,x
|
|
sta >tempString+1,x
|
|
inx
|
|
inx
|
|
cpx #32 ; see if we are finished...
|
|
blt @CopyLoop1
|
|
|
|
|
|
; AddFile(tempString); {Add the filename to the list...}
|
|
PushLong #tempString
|
|
jsl AsmAddFile
|
|
pla
|
|
pla
|
|
|
|
; if MyDirEntry.fileType = $000F then {Check for recursion...}
|
|
; begin
|
|
lda >MyDirEntry+$000E
|
|
cmp #$000F
|
|
beq @3
|
|
brl NotADirectory
|
|
|
|
; MyPathLevel:=ord(CurrentDirPath[0]); {Save the old pathname}
|
|
@3 lda >CurrentDirPath
|
|
and #$00FF
|
|
sta <MyPathLevel
|
|
|
|
|
|
; if MyPathLevel+tempNamePtr.length<255 then
|
|
clc
|
|
adc >tempNamePtr+2
|
|
cmp #$0100
|
|
blt @4
|
|
brl fNameTooLong
|
|
|
|
;
|
|
; begin
|
|
; currentDirPath:=Concat(currentDirPath,tempString,':');
|
|
@4
|
|
lda #currentDirPath>>16 ; create a pointer to our dest string
|
|
sta <tempDeref+2
|
|
lda #currentDirPath
|
|
sta <tempDeref
|
|
lda >currentDirPath ; add its current length...
|
|
and #$00FF
|
|
sec ;always add 1 extra
|
|
adc <tempderef
|
|
sta <tempDeref
|
|
bcc @5
|
|
inc <tempDeref+2
|
|
@5
|
|
lda >tempNamePtr+2 ; get the length to copy
|
|
sta <i ; save it on direct page
|
|
|
|
ldx #0 ; now do our copy...
|
|
@concatLoop lda >tempNamePtr+4,x ; source word
|
|
txy
|
|
sta [<tempderef],y ; save it in our destination
|
|
inx
|
|
inx
|
|
cpx <i ; are we done?
|
|
blt @concatLoop ; nope, keep going...
|
|
; we are now done copying the string, now fix the length and add the : at the end
|
|
|
|
lda >currentDirPath
|
|
clc
|
|
adc <i
|
|
inc a ; add 1 for the ":"
|
|
sta >currentDirPath
|
|
and #$00FF ; just get the length
|
|
tax ; use as an index
|
|
lda #':' ; load the terminator char
|
|
sta >currentDirPath,x ; and finish the name
|
|
|
|
; ProcessLevel;
|
|
pha ; room for result
|
|
pea $FFFF ; flag says we are reentering
|
|
jsl ProcessLevel ; do the next level...
|
|
pla
|
|
; AsmToolErr:=0;
|
|
|
|
; CurrentDirPath[0]:=chr(MyPathLevel); {Back the sucker off now...}
|
|
lda <MyPathLevel
|
|
sep #$20
|
|
longa Off
|
|
sta >CurrentDirPath
|
|
rep #$20
|
|
LongA On
|
|
|
|
; end;
|
|
; end;
|
|
; end;
|
|
fNameTooLong
|
|
NotADirectory
|
|
brl Repeat
|
|
;
|
|
; Interupt ready...
|
|
AsynchExit
|
|
phd ; save the current direct page also!
|
|
tsc ; get the current stack level
|
|
sta >StackLevel ; and save it in our global
|
|
lda >PascalStack ; get the DA stack level back
|
|
tcs ; and make it the current stack
|
|
lda >PascalDPage
|
|
tcd
|
|
lda #1 ; get the proper level flag
|
|
sta spudResult,s ; and make it the result for now...
|
|
lda spudRTL+1,s ; move the RTL down
|
|
sta spudRTL+3,s ; down 2 bytes
|
|
lda spudRTL,s
|
|
sta spudRTL+2,s
|
|
pla ; recover the crap
|
|
RTL ; and finally return
|
|
GDEError
|
|
; until AsmToolErr<>0;
|
|
; debug;
|
|
|
|
; MyClose.fileRefNum:=MyRefNum;
|
|
; ClosePD(MyClose);
|
|
lda <MyRefNum
|
|
sta >MyClose
|
|
_ClosePD MyClose
|
|
|
|
; end; {procedure}
|
|
EndProcLevel
|
|
ProcessError1
|
|
tdc ; unlink our local frame
|
|
clc
|
|
adc #FrameSize
|
|
tcs ; make it our current stack
|
|
pld ; recover the orihginal dpage
|
|
;
|
|
; Now we need to unlink the rest of the alternate stack crap
|
|
; and also see where we were called from...
|
|
pla ; recover the old stack level
|
|
bne @proce1 ; if this is non-zero then we are recursed
|
|
lda >PascalDPage ; recover the direct page
|
|
tcd
|
|
lda >PascalStack ; if zero, get the pascal stack level
|
|
@ProcE1
|
|
tcs ; make it the current stack pointer
|
|
lda spudFlag,s ; get the spudflag
|
|
sta spudResult,s ; and make it the result for now...
|
|
lda spudRTL+1,s ; move the RTL down
|
|
sta spudRTL+3,s ; down 2 bytes
|
|
lda spudRTL,s
|
|
sta spudRTL+2,s
|
|
pla ; recover the crap
|
|
RTL ; and finally return
|
|
|
|
PascalDPage ds.W 1 ; place to save the pascal direct page
|
|
EndP
|
|
|
|
;
|
|
; The following will do the proper comparison and then add the item to the list if
|
|
; it matches the proper criterion
|
|
;
|
|
AsmAddFile Proc Export
|
|
with PopupGlobals
|
|
import InvisibleFlag
|
|
|
|
; Stack for this call...
|
|
tempDeref equ 1
|
|
tempHandle equ tempDeref+4
|
|
InputString equ tempHandle+4
|
|
i equ InputString+4
|
|
OldDPage equ i+2
|
|
theRTL equ OldDPage+2
|
|
theName equ theRTL+3
|
|
|
|
FrameSize equ theRTL
|
|
;
|
|
;DirEntryRec = RECORD
|
|
;
|
|
DERrefNum equ 0 ; integer
|
|
DERreserved equ DERRefNum+2 ; integer
|
|
DERbase equ DERreserved+2 ; Integer;
|
|
DERdisplacement equ DERbase+2 ; Integer;
|
|
DERnameBuffer equ DERdisplacement+2 ; Ptr;
|
|
DERentryNum equ DERnameBuffer+4 ; Integer;
|
|
DERfileType equ DERentryNum+2 ; Integer;
|
|
DERendOfFile equ DERfileType+2 ; Longint;
|
|
DERblockCount equ DERendOfFile+4 ; Longint;
|
|
DERcreateTime equ DERblockCount+4 ; TimeRec;
|
|
DERmodTime equ DERcreateTime+8 ; TimeRec;
|
|
DERaccess equ DERmodTime+8 ; Integer;
|
|
DERauxType equ DERaccess+2 ; Longint;
|
|
DERfileSysID equ DERauxType+4 ; Integer;
|
|
|
|
;
|
|
; Begin by setting up our stack frame......
|
|
;
|
|
lda 4,s
|
|
tax
|
|
lda 6,s
|
|
tay ; recover our parameter
|
|
|
|
phd
|
|
tsc
|
|
sec
|
|
sbc #FrameSize
|
|
tcd
|
|
tcs
|
|
|
|
stx <InputString
|
|
sty <InputString+2
|
|
|
|
*** added 1-Oct-91 DAL -- only find invisible files if we want them
|
|
lda >MyDirEntry+DERaccess
|
|
and #$0004 ;invisible bit
|
|
beq @notInvisible
|
|
lda >InvisibleFlag
|
|
and #$00ff
|
|
bne @findItAnyway
|
|
brl EndProcLevel
|
|
@findItAnyway
|
|
@notInvisible
|
|
*** end 1-Oct-91
|
|
|
|
; Now do the proper match
|
|
jsr MatchIt
|
|
bcc @addIt
|
|
brl EndProcLevel
|
|
@addit
|
|
lda >MyListCnt ; see if we have too many items
|
|
cmp #MaxEntries ; see if we are beyond the threshold
|
|
blt @Addit010 ; if not, then continue
|
|
lda #$FFFF ; flag list overrun
|
|
sta >Stopping ; and save it in our flag to say stop
|
|
brl EndProcLevel
|
|
@Addit010
|
|
; tempHandle:=Str255Hndl(NewHandle(16,MyID+$0700,attrFixed,NIL));
|
|
pha ; room for result
|
|
pha
|
|
pea 0 ; size
|
|
pea 40 ; 32 bytes
|
|
lda >MyID
|
|
ora #$0700
|
|
pha
|
|
pea $4000
|
|
pha
|
|
pha
|
|
_NewHandle
|
|
pla
|
|
plx
|
|
sta <tempHandle
|
|
stx <tempHandle+2
|
|
|
|
; PtrToHand(@theFile,Handle(tempHandle),16); {copy the file name...}
|
|
pei <InputString+2
|
|
pei <InputString
|
|
pei <tempHandle+2
|
|
pei <tempHandle
|
|
PushLong #40
|
|
_PtrToHand
|
|
|
|
; MyList^^[myListCnt].memString:=Ptr(tempHandle^); {save the string pointer}
|
|
lda >MyList ; deref MyList
|
|
sta <tempDeref
|
|
lda >MyList+2
|
|
sta <tempDeref+2
|
|
ldy #2
|
|
lda [<tempDeref],y
|
|
tax
|
|
lda [<tempDeref]
|
|
sta <tempDeref
|
|
stx <tempDeref+2
|
|
; now create a pointer to the proper record in the list...
|
|
; each list entry is 20
|
|
lda >MyListCnt ; create MyListCnt*10
|
|
asl a
|
|
pha
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc 1,s
|
|
plx
|
|
asl a ; multiply by 2 to get *20
|
|
clc
|
|
adc <tempDeref ; add the low byte first
|
|
tax ; and save it...
|
|
ldy #2 ; now the high byte
|
|
lda <tempDeref+2
|
|
bcc @2
|
|
inc a
|
|
@2 sta <tempDeref+2
|
|
stx <tempDeref
|
|
;
|
|
; Lucky for us all the proper file info is in the current dir entry record
|
|
; still. So suck some more info out of the dir entry and put them into my record
|
|
; here...
|
|
;
|
|
memFlag equ 4
|
|
memFullName equ 6
|
|
memFileType equ 10
|
|
memAuxType equ 12
|
|
memEOF equ 16
|
|
;
|
|
; we now have a pointer to the list element let's stuff it
|
|
; First the string pointer
|
|
ldy #2
|
|
lda [<tempHandle],y
|
|
sta [<tempDeref],y
|
|
lda [<tempHandle]
|
|
sta [<tempDeref]
|
|
|
|
; MyList^^[myListCnt].memFlag:=0; {set to member type}
|
|
lda #0
|
|
ldy #4
|
|
sta [<tempDeref],y
|
|
;
|
|
; And now, update the rest of the files data to reflect the dir entry data
|
|
lda >MyDirEntry+DERAuxType
|
|
ldy #memAuxType
|
|
sta [tempDeref],y
|
|
lda >MyDirEntry+DERAuxType+2
|
|
ldy #memAuxType+2
|
|
sta [tempDeref],y
|
|
lda >MyDirEntry+DERfileType
|
|
ldy #memfileType
|
|
sta [tempDeref],y
|
|
lda >MyDirEntry+DERendOfFile
|
|
ldy #memEOF
|
|
sta [tempDeref],y
|
|
lda >MyDirEntry+DERendOfFile+2
|
|
ldy #memEOF+2
|
|
sta [tempDeref],y
|
|
;
|
|
; Now that the record is updated, update the list
|
|
; tempHandle:=Str255Hndl(NewHandle(ord(theFile[0])+ord(CurrentDirPath[0])+3,MyID+$0700,0,NIL));
|
|
|
|
lda [<InputString]
|
|
clc
|
|
adc >CurrentDirPath
|
|
and #$00FF
|
|
adc #3
|
|
|
|
pha
|
|
pha
|
|
|
|
pea 0
|
|
pha
|
|
lda >MyID
|
|
ora #$0700
|
|
pha
|
|
pea 0
|
|
pha
|
|
pha
|
|
_NewHandle
|
|
; MyList^^[myListCnt].MemFullName:=newHandle;
|
|
ldy #6
|
|
pla
|
|
sta [<tempDeref],y
|
|
sta <tempHandle
|
|
iny
|
|
iny
|
|
pla
|
|
sta [<tempDeref],y
|
|
sta <tempHandle+2
|
|
|
|
; tempHandle^^:=Concat(currentDirPath,tempString);
|
|
ldy #2
|
|
lda [<tempHandle],y
|
|
sta <tempderef+2
|
|
lda [<tempHandle]
|
|
sta <tempDeref
|
|
; First, copy current path over
|
|
lda >currentDirPath
|
|
and #$00FF
|
|
sta <i ; set the length to copy
|
|
|
|
ldy #1
|
|
ldx #1
|
|
; and start the copy
|
|
@copyCur lda >currentDirPath,x
|
|
sta [<tempderef],y
|
|
iny
|
|
inx
|
|
cpx <i
|
|
blt @copyCur
|
|
|
|
; now copy input string to the end...
|
|
lda <i
|
|
clc
|
|
adc <tempDeref
|
|
sta <tempderef
|
|
bcc @10
|
|
inc <tempDEREF+2
|
|
@10
|
|
; compute new size to copy
|
|
lda [<inputString]
|
|
and #$00FF
|
|
sta <i
|
|
ldy #1
|
|
;
|
|
@Loop
|
|
lda [<inputString],y
|
|
sta [<tempDeref],y
|
|
iny
|
|
cpy <i
|
|
blt @Loop
|
|
;
|
|
; Now compute the new string length...
|
|
lda >currentDirPath
|
|
and #$00FF
|
|
clc
|
|
adc <i
|
|
and #$00FF
|
|
sta <i
|
|
|
|
ldy #2
|
|
lda [<tempHandle],y
|
|
sta <tempderef+2
|
|
lda [<tempHandle]
|
|
sta <tempDeref
|
|
lda [<tempDeref]
|
|
and #$FF00
|
|
ora <i
|
|
sta [<tempDeref]
|
|
|
|
lda >MyListCnt
|
|
inc a
|
|
sta >MyListCnt
|
|
|
|
; NewList2(MyMemberDraw,-1,ref(MyList),1,myListCnt,listCtrl);
|
|
|
|
PushLong #MyMemberDraw
|
|
pea $FFFF
|
|
PushLong MyList
|
|
pea 1
|
|
lda >MyListCnt
|
|
pha
|
|
PushLong ListCtrl
|
|
_NewList2
|
|
EndProcLevel
|
|
tdc ; unlink our local frame
|
|
clc
|
|
adc #FrameSize
|
|
tcs ; make it our current stack
|
|
pld ; recover the orihginal dpage
|
|
RTL
|
|
|
|
MatchIt
|
|
; Routine to compare and match the file names
|
|
; This routine requires that the MatchStr be lower cased.
|
|
; it trashed the contents of tempHandle and i
|
|
;
|
|
matchTemp equ tempHandle
|
|
stz <i
|
|
lda >MatchType
|
|
dec a
|
|
asl a
|
|
tax
|
|
jsr (matchTbl,x)
|
|
rts
|
|
matchTbl dc.W Exact
|
|
dc.W StartsWith
|
|
dc.W EndsWith
|
|
dc.W Contains
|
|
dc.W WildCard ; finds with certain wild card characters
|
|
;
|
|
Exact
|
|
; Test to see if the filename is an exact match of the matchstr
|
|
sep #$20
|
|
Longa Off
|
|
lda >MatchStr ; get the length of the match string
|
|
sta <i
|
|
cmp [<InputString]
|
|
beq @Cont
|
|
brl MatchFail
|
|
@cont
|
|
ldy #1
|
|
@CompLoop tyx ; make both indexs the same
|
|
lda [<InputString],y
|
|
cmp #'A' ; first see if its upper case
|
|
blt @NonAlpha ; if less than its a non-alpha compare
|
|
ora #$20 ; make it lower case always...
|
|
sta <matchTemp ; save it for a second
|
|
lda >MatchStr,x ; get the char to match
|
|
ora #$20 ; make sure its lower case
|
|
cmp <matchTemp ; see if they are the same
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NonAlpha cmp >MatchStr,x
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NextChar
|
|
iny
|
|
cpy <i ; test if we are done...
|
|
blt @compLoop
|
|
beq @compLoop
|
|
REP #$20
|
|
Longa On
|
|
clc
|
|
rts
|
|
|
|
StartsWith
|
|
; Test to see if the filename is an exact match of the matchstr
|
|
sep #$20
|
|
Longa Off
|
|
lda >MatchStr ; get the length of the match string
|
|
sta <i
|
|
cmp [<InputString]
|
|
blt @Cont
|
|
beq @Cont
|
|
brl MatchFail
|
|
@cont
|
|
ldy #1
|
|
@CompLoop tyx ; make both indexs the same
|
|
lda [<InputString],y
|
|
cmp #'A' ; first see if its upper case
|
|
blt @NonAlpha ; if less than its a non-alpha compare
|
|
ora #$20 ; make it lower case always...
|
|
sta <matchTemp ; save it for a second
|
|
lda >MatchStr,x ; get the char to match
|
|
ora #$20 ; make sure its lower case
|
|
cmp <matchTemp ; see if they are the same
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NonAlpha cmp >MatchStr,x
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NextChar
|
|
iny
|
|
cpy <i ; test if we are done...
|
|
blt @compLoop
|
|
beq @compLoop
|
|
REP #$20
|
|
Longa On
|
|
clc
|
|
rts
|
|
|
|
EndsWith
|
|
; Test to see if the filename is an exact match of the matchstr
|
|
sep #$20
|
|
Longa Off
|
|
lda >MatchStr ; get the length of the match string
|
|
sta <i
|
|
cmp [<InputString]
|
|
blt @Cont
|
|
beq @Cont
|
|
brl MatchFail
|
|
@cont ; now set up the counters for matching
|
|
lda [<inputString] ; get the length of the source str
|
|
tay ; place it in <X>
|
|
lda <i ; now get the length of the match string
|
|
tax
|
|
|
|
@CompLoop
|
|
lda >MatchStr,x ; get the last char of match string
|
|
cmp #'A' ; first see if its upper case
|
|
blt @NonAlpha ; if less than its a non-alpha compare
|
|
ora #$20 ; make it lower case always...
|
|
sta <matchTemp ; save it for a second
|
|
lda [<inputString],y ; get the char to match
|
|
ora #$20 ; make sure its lower case
|
|
cmp <matchTemp ; see if they are the same
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NonAlpha cmp [<InputString],y
|
|
beq @NextChar
|
|
brl MatchFail
|
|
|
|
@NextChar
|
|
dey ; decrement input counter
|
|
dex ; and match counter
|
|
bne @CompLoop ; if MatchCounter >0 then keep going
|
|
REP #$20
|
|
Longa On
|
|
clc ; else we are done and we found a match
|
|
rts
|
|
|
|
;
|
|
Contains
|
|
; Now see if input contains matchString
|
|
; First be sure that the Matchstr can be contained by testing the length
|
|
; NOTE: This routine requires that the matchstr be lowercased first.
|
|
;
|
|
; This routine trashes i and matchtemp
|
|
;
|
|
stz i
|
|
stz MatchTemp
|
|
stz MatchTemp+2
|
|
sep #$20
|
|
Longa Off
|
|
lda >MatchStr ; get the length of the match string
|
|
sta <i ; into i (our counter)
|
|
cmp [<InputString]
|
|
blt @Cont
|
|
beq @Cont
|
|
brl MatchFail
|
|
;
|
|
; at this point we know that it is physically possible for matchstr to fit inside
|
|
; the inputstring. Now, start testing for the match...
|
|
; MatchTemp will contain our current pointer... matchTemp+2 the size of Inputstr
|
|
;
|
|
@cont
|
|
rep #$20
|
|
longa On
|
|
lda [<InputString]
|
|
and #$00FF
|
|
sta <MatchTemp+2
|
|
ldy #0 ; init our string pointer
|
|
@FindFirst cpy <MatchTemp+2 ; see if we are done
|
|
bge @NotHere ; if so, it must not be here!
|
|
iny
|
|
lda [<InputString],y
|
|
and #$00FF ; strip the byte...
|
|
cmp #'A' ; lowercase it...
|
|
blt @FF0010
|
|
cmp #'Z'+1
|
|
bge @FF0010
|
|
ora #$0020
|
|
@FF0010 sta <MatchTemp
|
|
lda >MatchStr+1
|
|
and #$00FF
|
|
cmp <MatchTemp ; see if these are the same...
|
|
bne @FindFirst ; they are not, so continue till done
|
|
|
|
;
|
|
; If we get here then we have found the first char of matchstr in inputstr
|
|
; let's continue on...
|
|
;
|
|
; Save current value for Y first
|
|
sty <MatchTemp
|
|
|
|
; see if whats left of the input string can contain match string
|
|
lda <MatchTemp+2 ; length of inputstr
|
|
sec
|
|
sbc <MatchTemp ; see if its too long...
|
|
;
|
|
; 2/12/90 Mensch
|
|
; Fix bug here since Y was already incremented (Its based on 1 not 0) the following
|
|
; arithmetic will not work right. what we really have to do now is decrement it...
|
|
;
|
|
inc a ; adjust for a too big Y
|
|
cmp <i
|
|
bge @maybehere ; if its >= than i then it cound be here!
|
|
@NotHere
|
|
; otherwise, it can't be in this string... better button up and leave
|
|
rep #$20
|
|
longa on
|
|
sec ; signal failure
|
|
rts ; and go back...
|
|
|
|
@MaybeHere
|
|
; This routine will determine if the string is actually inside of the input
|
|
; string...
|
|
ldy <MatchTemp ; start at the beginning
|
|
phy ; save the length...
|
|
ldx #0 ; with both strings...
|
|
@FindRest cpx <i ; is x equal to the ending condition?
|
|
beq @GotIt ; if so, then I got one!
|
|
inx
|
|
lda [<InputString],y
|
|
and #$00FF ; strip the byte...
|
|
cmp #'A' ; lowercase it...
|
|
blt @FR0010
|
|
cmp #'Z'+1
|
|
bge @FR0010
|
|
ora #$0020
|
|
@FR0010 sta <MatchTemp
|
|
lda >MatchStr,x
|
|
and #$00FF
|
|
cmp <MatchTemp ; see if these are the same...
|
|
bne @tryAgain ; they are not, so back to main loop
|
|
iny
|
|
bra @FindRest
|
|
@TryAgain ply ; if we get here the string wasn't found yet
|
|
brl @FindFirst
|
|
;
|
|
; This is called when we have found the whole string ...
|
|
@GotIt
|
|
ply ; recover its location...
|
|
rep #$20
|
|
longa on
|
|
clc ; signal success
|
|
rts ; and go back...
|
|
|
|
MatchFail rep #$20
|
|
longa on
|
|
sec ; signal failure
|
|
rts ; and go back...
|
|
|
|
|
|
************************************************************
|
|
*
|
|
* WildCard
|
|
*
|
|
* This routine searches InputString for MatchStr and returns with
|
|
* the carry clear if found, set if not found...
|
|
*
|
|
* The current wild card operation is the same as Equal except that
|
|
* it also supports the following Wildcard characters:
|
|
*
|
|
* §- Match any ASCII letter (Upper or lower case)
|
|
* £- Match any numeric digit
|
|
* Å- Match any stream of data (Only one of these per find item)
|
|
*
|
|
************************************************************
|
|
WildCard
|
|
; Test to see if the filename is an exact match of the matchstr
|
|
stz i
|
|
stz MatchTemp+2
|
|
sep #$20
|
|
Longa Off
|
|
lda >MatchStr ; get the length of the match string
|
|
sta MatchTemp+2 ; save it in our special place
|
|
lda [<InputString] ; now do the input string length
|
|
sta <i
|
|
; Note no length checking here because of wild card construction...
|
|
@cont
|
|
ldy #1
|
|
ldx #1
|
|
@CompLoop ; make both indexs the same
|
|
lda >MatchStr,x ; get the next char to match
|
|
cmp #'£' ; is it match number?
|
|
beq @CompNum
|
|
cmp #'§' ; is it match Letter?
|
|
beq @CompAlpha
|
|
cmp #'Å' ; is it stream of data?
|
|
beq @CompHole
|
|
; Else just a normal compare will do...
|
|
lda [<InputString],y
|
|
cmp #'A' ; first see if its upper case
|
|
blt @CompNorm01 ; if less than its a non-alpha compare
|
|
cmp #'Z'+1 ; is it greater?
|
|
bge @CompNorm01
|
|
ora #$20 ; make it lower case always...
|
|
@CompNorm01 cmp >MatchStr,x ; get the char to match
|
|
beq @NextChar
|
|
brl @MatchFail
|
|
;
|
|
; Only test its numericness....
|
|
@CompNum lda [<InputString],y
|
|
cmp #'0'
|
|
blt @MatchFail
|
|
cmp #'9'+1
|
|
bge @MatchFail
|
|
bra @NextChar
|
|
|
|
;
|
|
; Test its alphaness...
|
|
@CompAlpha lda [<InputString],y
|
|
cmp #'A'
|
|
blt @MatchFail
|
|
cmp #'Z'+1
|
|
blt @NextChar
|
|
cmp #'a'
|
|
blt @MatchFail
|
|
cmp #'z'+1
|
|
blt @NextChar
|
|
@MatchFail brl MatchFail
|
|
;
|
|
; The match passes so far..
|
|
@NextChar
|
|
iny
|
|
inx
|
|
cpx <MatchTemp+2 ; see if we are finished..
|
|
blt @ContHC
|
|
beq @ContHC
|
|
bra @MatchGood ; else if size does not pan out then its a fail..
|
|
@ContHC cpy <i ; test if we are done...
|
|
blt @compLoop
|
|
beq @compLoop
|
|
@MatchGood REP #$20
|
|
Longa On
|
|
clc
|
|
rts
|
|
|
|
;
|
|
; This next routine will work with holes. If a whole has been found then it
|
|
; will finish finding the rest of the string starting at the back...
|
|
; NOTE:<X> contains the offset into the matchstr
|
|
; <Y> comtains the offset into the inputstring
|
|
;
|
|
@CompHole
|
|
; First see if wild card is at the end of the match string. If so then
|
|
; we have found a match!
|
|
;
|
|
cpy <MatchTemp+2
|
|
bge @MatchGood
|
|
;
|
|
; Otherwise we have a certain number of characters left in the string to find...
|
|
; we must calculate how many...
|
|
stx <MatchTemp ; save the current offset into matchstr
|
|
lda <MatchTemp+2 ; get the length of match string
|
|
sec
|
|
sbc <MatchTemp ; subtract where we are...
|
|
sta <MatchTemp ; matchTemp now cleverly contains
|
|
lda <i ; number of chars in inputstr
|
|
sec
|
|
sbc <MatchTemp
|
|
sta <MatchTemp ; save it in match temp
|
|
cpy <MatchTemp ; see if this is legal...
|
|
blt @MatchFail ; if <Y> is less than then not enough chars
|
|
ldy <MatchTemp ; restart the comparison at this point with the new offset
|
|
brl @NextChar ; and get the next character
|
|
|
|
EndP
|
|
|
|
End
|