mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-24 22:02:28 +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
14 KiB
NASM
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
|