Files
Shawn Quick dfcaae62dd Add qlink, the disk tools, and a bootable ProDOS 8 image.
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.
2026-10-16 14:41:55 -07:00

1 line
14 KiB
NASM

title 'NewControl2'
**********************************************************************
* Copyright Apple Computer, Inc. 1986-88
* All rights reserved
*
* NewControl2
*
*
* 23 Sep 88 David Good
*
* First Pass
*
* 24 Sep 88 Steven Glass
*
* Integration and first debugging.
*
* 28 Sep 88 Steven Glass
*
* Change in the way that the recsize routines can use the param
* field. If the routines are called by NewControl, param is zero.
* If the routines are called by NewControl2, param is pointer to
* template.
*
* 7 Oct 88 Steven Glass
*
* Used common load and release resource routines and don't worry
* about errors.
*
* 10 Oct 88 Steven Glass
*
* Changed the way the temporary work area was used. Using it for
* local variables was ok until I created a scroll control. So I
* now have some more data in the global data area, and all references
* to it are indirect. TemplatePtr is now at yRat since the mouse
* position is not used during new control.
*
**********************************************************************
Blanks off
String asis
print push
print off
INCLUDE 'all.macros'
Include 'Special.macros'
INCLUDE 'equates.asm'
include 'SuperEquates.asm'
IMPORT CMpop10bytes
print pop
**********************************************************************
*
* Variables used by NewControl2 and subroutines.
*
**********************************************************************
DSECT Inputs
InputRef long ;these are passed to us on the stack
InputVerb word
TheWindow long
ResultH long
TemplatePtr equ yRat ; this is not used at init time.
title 'NewControl2'
****************************************************************
*
NewControl2 PROC EXPORT
*
* This is a new way to create one or more controls. Instead of
* passing all the information on the stack we pass a reference
* to an input record and a "verb" that describes what kind of
* reference we passed
*
*
* 12/8/89 Mensch
* Fixed bug where the port was not set to the owner port before the defproc
* is being called. This causes a problem is size calculation. This will now
* Always set the port to the owners grafport since the stack frame link/unlink
* always preserves the current grafport!
*
* Inputs:
* Space For Result LONG
* OwnerPtr LONG
* InputVerb WORD
* InputRef LONG
*
* Outputs:
* Control Handle LONG
*
* External Refs:
import LoadResource
import ReleaseResource
*
* Entry Points:
* none
*
longa on ; mode
longi on
*
****************************************************************
jsr CMStartup ;link things in and start things up.
;
; Always set port to owner port! Mensch
lda TheWindow+2
pha
lda TheWindow
pha
_SetPort
ldx TheWindow+2 ;use the window pointer
lda TheWindow
jsr makeWptr ;windptr = pointer to window.
;-----------------------------------------------------------
;
; zero out the saved resourceid, savedhandle and
; the errorcode in global data.
;
lda #0
ldy #SavedRescID
@ZeroLoop sta [Data],y
iny
iny
cpy #ErrorCode+2
bcc @ZeroLoop
stzl ResultH ;zero out the returned value
lda InputVerb ;use the verb as an index into the startup
asl a ;..table. These routines convert the
tax ;..InputRef to a pointer
jmp (startupTable,x)
;-----------------------------------------------------------
;
; This is the code that is run when the input is some
; kind of resource.
;
rescStartup
ldy #SavedRescID ; save the resource id
lda InputRef
sta [data],y
iny
iny
lda InputRef+2
sta [data],y
PushLongSpace ;space for the returned handle
lda InputVerb ;check to see if we are loading a list
cmp #resourceToResource ;..resource or a template resource...
beq @multiple
PushWord #rControlTemplate
bra @single
@multiple PushWord #rControlList
@single PushZLong InputRef
jsr LoadResource ;load the resource and clobber the
PullLong InputRef ;..InputRef. (now it's a handle)
;-----------------------------------------------------------
;
; This is the code that is run when the input is some kind
; of handle. Note that the resource code falls in here.
;
handStartup
ldy #SavedHandle ; save the resource handle
lda InputRef
sta [data],y
iny
iny
lda InputRef+2
sta [data],y
ldy #4 ;lock and dereference the input handle
lda [InputRef],y ;(note: bit manipulation is legal now !)
ora #$8000
sta [InputRef],y
dey
dey
lda [InputRef],y
tax
lda [InputRef] ;store the new pointer back over the
stax InputRef ;..InputRef and fall thru to pointer
;-----------------------------------------------------------
;
; This is the code that is run when the input is some kind
; of pointer. Note that the handle and resource code fall
; in here.
;
ptrStartup
ldy #0 ;all the action routines use Y as a index
lda InputVerb ;..into the list.
asl a
tax
jmp (actionTable,x)
;-----------------------------------------------------------
;
; Make a control for each pointer in the list.
;
ptrLoop jsr FillTemplatePtr ;get the next template pointer (use Y as
bcc @Cont
brl cleanup ; if there are no more we are done.
@cont
phy ;..the index) - save the index
jsr MakeControl ;create the control using TemplatePtr
ldy #ErrorCode
lda [data],y
ply ;restore the index
cmp #0 ;check for errors
beq ptrLoop
bra cleanup
;-----------------------------------------------------------
;
; Make a control for each handle in the list.
;
handleLoop jsr FillTemplatePtr
bcs cleanup
phy
PushZLong TemplatePtr ;template pointer is a handle so save it,
jsr LockTemplatePtr ;..lock and dereference it
jsr MakeControl ;..and make the control
_HUnlock ;now unlock the handle using the stack
ldy #ErrorCode
lda [Data],y
ply
cmp #0 ;check for errors
bne cleanup
bra handleLoop ;when we are done, then goto cleanup
;-----------------------------------------------------------
;
; Make a control for each resource in the list
;
resourceLoop jsr FillTemplatePtr ;get the next resource ref.
bcs cleanup
phy ;save our index
PushWord #rControlTemplate ;Push these now for
PushZLong TemplatePtr ; ReleaseResource (below)
PushLongSpace ;space for result
PushWord #rControlTemplate ;the type of resource is "CtlTemplate"
PushZLong TemplatePtr ;this is the resource ref
jsr LoadResource
lda 1,s ;clone the handle into TemplatePtr
sta TemplatePtr
lda 3,s
sta TemplatePtr+2
jsr LockTemplatePtr ;deref and lock it
jsr MakeControl ;create the control
_HUnlock ;unlock the handle using the stack
;-----------------------------------------------------------
;
; Release the template resource
;
jsr ReleaseResource ;release the resource using the stack
ldy #ErrorCode
lda [Data],y
ply ;restore our index
cmp #0 ;check for errors
bne cleanup
bra resourceloop
;-----------------------------------------------------------
;
; Make the single control from the pointer now in InputRef
;
single movl InputRef,TemplatePtr ;copy the template pointer
jsr MakeControl ;create the control
movl ctlHand,ResultH ;..and save the handle to return.
;-----------------------------------------------------------
;
; Clean every thing up.
;
cleanup
ldy #SavedHandle+1 ;check to see if we need to unlock
lda [data],y
beq allDone ;..handle.
ldy #SavedHandle+2 ; yup, unlock it.
lda [data],y
pha
dey
dey
lda [data],y
pha
_HUnlock
ldy #SavedRescID
lda [data],y
bne @ReleaseIt
iny
iny
lda [data],y
beq allDone
@ReleaseIt
lda InputVerb ;Yep, so check the type of resource
cmp #resourceToResource ;..(template, list) and release it.
beq @multiple
PushWord #rControlTemplate
bra @single
@multiple PushWord #rControlList
@single ldy #SavedRescID+2
lda [data],y
pha
dey
dey
lda [data],y
pha
jsr ReleaseResource ; release the single or list
allDone
ldy #ErrorCode
lda [data],y
tay
brl CMPop10Bytes
;-----------------------------------------------------------
;
; Table of address of startup routines called depending on
; the input ref.
;
startupTable dc.w ptrStartup ;pointer to single
dc.w handStartup ;handle to single
dc.w rescStartup ;resource of single
dc.w ptrStartup ;pointer to list of pointers
dc.w ptrStartup ;pointer to list of handles
dc.w ptrStartup ;pointer to list of resources
dc.w handStartup ;handle to list of pointers
dc.w handStartup ;handle to list of handles
dc.w handStartup ;handle to list of resources
dc.w rescStartup ;resource to list of resources
;-----------------------------------------------------------
;
; Table of address of action routines, called depending on
; the input ref.
;
actionTable dc.w single ;pointer to single
dc.w single ;handle to single
dc.w single ;resource of single
dc.w ptrLoop ;pointer to list of pointers
dc.w handleLoop ;pointer to list of handles
dc.w resourceLoop ;pointer to list of resources
dc.w ptrLoop ;handle to list of pointers
dc.w handleLoop ;handle to list of handles
dc.w resourceLoop ;handle to list of resources
dc.w resourceLoop ;resource to list of resources
;---------------------------------------------------------------
; local routine to copy the current item from the list into
; TemplatePtr
;---------------------------------------------------------------
FillTemplatePtr lda [InputRef],y
sta TemplatePtr
iny
iny
lda [InputRef],y
sta TemplatePtr+2
iny
iny
ora TemplatePtr
beq @AllDone
clc
rts
@AllDone sec
rts
;---------------------------------------------------------------
; local routine to lock down TemplatePtr and store it back over
; itself
;---------------------------------------------------------------
LockTemplatePtr ldy #4
lda [TemplatePtr],y
ora #$8000
sta [TemplatePtr],y
dey
dey
lda [TemplatePtr],y
tax
lda [TemplatePtr]
stax TemplatePtr
rts
title 'MakeControl'
****************************************************************
*
MakeControl
*
* Local routine that does the actual work of translating a template
* into a control - this is very similar to the old NewControl.
*
*
* Inputs:
* templatePtr
* windPtr
*
* Outputs:
* new control is part of list.
*
* External Refs:
import StatTextProc
import PicProc
*
* Entry Points:
* none
*
longa on ; mode
longi on
*
****************************************************************
ldy #TemplateRecord.pCount ;check the number of parameters
lda [TemplatePtr],y
cmp #minTemplatePCount
bge @cont
lda #TooFewParmsError
ldy #ErrorCode
sta [data],y
rts
;-----------------------------------------------------------
;
; Minimum PCount is OK.
;
; Look at control type, If its custom, get the pointer to
; the custom proc into Param. If its not custom, get
; the ID of the standard proc into param.
;
@cont
lda TemplatePtr
sta param
lda TemplatePtr+2
sta param+2
clc Assume Ptr
ldy #TemplateRecord.MoreFlags
lda [TemplatePtr],y
and #FctlProcRefNotPtr
beq IsPtr
sec
IsPtr
ldy #TemplateRecord.ProcRef+2
lda [TemplatePtr],y
tax
dey
dey
lda [TemplatePtr],y
txy
ldx #recSize
bcc CallByPtr
jsr CallByThisID
bra AllocIt
CallByPtr jsr CallByThisPtr
AllocIt
;-----------------------------------------------------------
;
; Temporary kludge to keep things clean!
;
cmp #SuperCtlSize
bcs @ok
lda #superCtlSize
@ok
;-----------------------------------------------------------
;
; Allocate and deref the control handle
;
pha ;save the low word of the size
PushLongSpace ;space for returned handle.
PushAX ;size returned by the defProc
ldy #MyID ;pass the ID for the control manager
PushWord [data],y
PushWord #0 ;attributes
PushLongSpace ;space for address
_NewHandle
ldy #ErrorCode
sta [Data],y ;save the error code
PullLong ctlHand
bcsl error2
jsr dereference ;ctlPtr = (ctlHand).
pla ;get back the block size again.
;-----------------------------------------------------------
;
; Zero the memory in the control handle
;
tay ;Y is our index
lsr a ;check for odd sized block
lda #0 ;..and zero the block
bcc @loop0
shortm
dey
sta [ctlPtr],y
longm
@loop0 dey
dey
sta [ctlPtr],y
bne @loop0
;-----------------------------------------------------------
;
; The record is allocated, and zeroed. Now, hook it into
; the control list and set the fields we can set.
;
ldy #owControls ;hook the control into the head of the
lda [windPtr],y ;..window's control list
sta [ctlPtr]
lda ctlHand
sta [windPtr],y
iny
iny
lda [windPtr],y
tax
lda ctlHand+2
sta [windPtr],y
ldy #2
txa
sta [ctlPtr],y
;-----------------------------------------------------------
;
; Set Owner field
;
iny
iny
lda TheWindow
sta [<Ctlptr],y
iny
iny
lda TheWindow+2
sta [<Ctlptr],y
;-----------------------------------------------------------
;
; Set the ID field
;
ldy #TemplateRecord.ID+2 ;set the control's refCon field
lda [TemplatePtr],y
tax
dey
dey
lda [TemplatePtr],y
ldy #NewCtlRecord.ctlID
sta [ctlPtr],y
iny
iny
txa
sta [ctlPtr],y
;-----------------------------------------------------------
;
; Set the rectangle
;
ldy #TemplateRecord.Rect ;copy the rectangle into the record.
ldx #NewCtlRecord.ctlRect
@loop1 lda [TemplatePtr],y
iny
iny
phy
txy
sta [ctlPtr],y
ply
inx
inx
cpy #TemplateRecord.Rect+8
blt @loop1
;-----------------------------------------------------------
;
; Set Flag
;
ldy #TemplateRecord.Flags ;set the control's flags and the hilite
lda [TemplatePtr],y ;..field.
ldy #NewCtlRecord.ctlFlag
sta [ctlPtr],y
;-----------------------------------------------------------
;
; Set MoreFlags
;
ldy #TemplateRecord.MoreFlags ;set the control's flags and the hilite
lda [TemplatePtr],y ;..field.
ldy #NewCtlRecord.ctlMoreFlags
sta [ctlPtr],y
;-----------------------------------------------------------
;
; Set the ref con
;
ldy #TemplateRecord.RefCon+2 ;set the control's refCon field
lda [TemplatePtr],y
tax
dey
dey
lda [TemplatePtr],y
ldy #NewCtlRecord.ctlRefCon
sta [ctlPtr],y
iny
iny
txa
sta [ctlPtr],y
;-----------------------------------------------------------
;
; Set the ctlPRoc field in the record.
;
ldy #TemplateRecord.ProcRef+2
lda [TemplatePtr],y
tax
dey
dey
lda [TemplatePtr],y
ldy #NewCtlRecord.ctlProc
sta [ctlPtr],y
iny
iny
txa
ora #$8000 ;set the highest bit - indicates super
sta [ctlPtr],y ;..ctl
;-----------------------------------------------------------
;
; Call the init routine for the proc.
;
lda TemplatePtr ;pass a pointer to the template for
ldy TemplatePtr+2 ;..the defProc to do extra initialization
ldx #initCntl
jsr CMDispatch
rts
error2 pla ;cleanup the stack
rts
ENDP
END