IMD 1.17: 11/11/2014 11:25:30 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 14 OF 30  SR14q82VKXSVRDOS 0420¤m-‡SIGNAL�ONE�USER DERQS10:!‰EXIT„SUB“exit�(subroutine�exit);‰ENDééééé é=/*=/*†M68XXX.DESEM.AF=/**=/* Chain file to assemble M68XXX.DESEM.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.DESEM.LS=/*=/IFC \1ƒ=ARG�M68XXX.DESEM.LS=/ENDIF=/*/=ASM M68XXX.DESEM.SA,M68XXX.DESEM.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.UST.EQ=/*}=/*=ENDéééééé9‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.UST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.UST.EQ‰LIST‰PAGE5DESEM„IDNT‚5,1„68xxx�DIRECTIVE--DETACH�FROM�SEMAPHORE*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*"*„DESEMƒ--�REV�1.01ƒ7/01/79ƒ(HLD6)*Œ--�TRAP�1�ROUTINE*-*‡PURPOSE:ƒREQUEST�TO�DETACH�A�USER�SEMAPHORE*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS *‘A4�HAS�PARAMETER�BLOCK�ADDRESS* 0�-�SEMAPHORE�NAME* 4�-�SEMAPHORE�KEY�(NOT�USED)* 8�-�INITIAL�COUNT* 9�-�SEMAPHORE�TYPE**ŠEXIT:ƒD0�HAS�RETURN�CODE)*’D0�=�0‚GOOD�RETURN,�SEGMENT�DEALLOCATED*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE0*ŠRTCDNFND�-�7ƒENTRY�NOT�FOUND�IN�USER�SEM�TABLE*‰SECTION�LEVEL04* ‰XDEF†DESEM ‰XDEF†DESEMA‰XDEF†DSEM_SUB ‰XREF†SBDSEMX ‰XREF.S„SEMUST‰PAGE*5*ˆGet�exclusive�access�to�user�semaphore�table�(UST).* DESEM:+‰MOVE.L‚A4,A5ˆSAVE�PHYS�ADDR�OF�PARAM�BLOCK ‰IFNE„MULTPROC ‰TR0.PƒSEMUST‰ENDC  **ˆLook�for�entry�in�UST.* *‰MOVE.LƒA6,A4�TCB�ADDRESS�IN�A4�FOR�FNDSEM*‰TR0.FNDSEM‚<(A5),I>ŠARG�IS�SEMAPHORE�NAME-‰BRA.S…DESEM_10ŒFOUND�MATCHING�ENTRY�IN�TABLE **ˆDidn't�find�entry�in�UST."*ˆRelease�exclusive�access�to�UST,"*ˆand�exit�with�error�(not�found);* ‰IFNE„MULTPROC ‰TR0.PƒSEMUST‰END C *‰EXIT…RTCDNFND�ERROR�CODE�-�NO�ENTRY�FOUND  **ˆFound�entry�in�UST.*ˆDeallocate�it,&*ˆrelease�exclusive�access�to�the�UST,*ˆand�exit�(subroutine�exit);* DESEM_10:)‰BSR.S…DSEM_SUBŒDEALLOCATE�THIS�SEMAPHORE ‰IFNE„MULTPROC ‰TR0.PƒSEMUST‰ENDC !‰EXIT†SUB‘exit�(subroutine�exit);‰PAGE*#*ˆHere�to�deallocate�all�semaphores*ˆattrached�to�this�task.* +*ˆSet�A4�to�point�to�the�client�task's�tcb./*ˆCall�the�subroutine�to�detach�all�semaphores,BjK`SO*ˆand�exit�(subroutine�exit).* DESEMA: ‰MOVE.L„A6,A4 ‰BSR‡SBDSEMX ‰EXIT†SUB‰PAGE=***************************************************************(**‡Subroutine�to�deallocate�a�semaphore."**‡Called�by�both�DESEM�and�DSEMX.**=***************************************************************†FOUND�ENTRY�--�DELETE�IT* DSEM_SUB‰MOVE.L‚D0,D3‰ENTRY�NUMBER/‰MOVE.L‚D3,D1‰SEMAPHORE�ADDR�WILL�BE�IN�(A1,D3)&‰TST.WƒUSTUCNT(A1,D1)‚IS�THIS�POINTER?‰BGE.SƒDSEM_10ˆNO ‰MOVE.L‚USTSPTR(A1,D1),D3 DSEM_10: ‰CMP.Bƒ#1,USTTYPE(A1,D1)†TYPE�1?‰BNE.SƒDSEM_20�NO &‰TST.BƒUSTXCNT(A1,D1)‡YES�-�CHECK�XCNT‰BEQ.SƒDSEM_20 ‰TR0.Vƒ†SIGNAL DSEM_20:3‰TST.WƒUSTUCNT(A1,D1)‡IS�ENTRY�POINTER�OR�SEMAPHORE‰BPL.SƒDSEM_30ŽSEMAPHORE‰PAGE*9*†POINTER�ENTRY�--�CLEAR�IT�AND�DECREMENT�SEMAPHORE�COUNT* &‰CLR.LƒUSTTNAME(A1,D1)„CLEAR�TASK�NAME)‰CLR.WƒUSTUCNT(A1,D1)…CLEAR�POINTER�ENTRY‰CLR.BƒUSTUCNT(A1,D3)‰SUB.Wƒ#1,USTUCNT(A1,D3) ‰BRA…DSEM_99  *;*†SEMAPHORE�ENTRY�--�MAKE�ANOTHER�ENTRY�THE�SEMAPHORE�ENTRY* DSEM_30:‰CLR.BƒUSTUCNT(A1,D3)&‰CMP.Bƒ#3,USTTYPE(A1,D3)‡IS�IT�TYPE�3?%‰BEQ.SƒDSEM_80‘TYPE�3�IS�SPECIAL�CASE ‰SUB.W„#1,USTUCNT(A1,D3)‰BNE.SƒDSEM_40 &‰CMP.Bƒ#2,USTTYPE(A1,D3)‡IS�IT�TYPE�2?‰BNE…DSEM_96�NO�-�DONE ‰MOVE.B‚USTXCNT(A1,D3),D01‰CMP.BƒUSTSEM+1(A1,D3),D0…IS�INITIAL�COUNT�IN�SEM"‰BEQ…DSEM_96�YES�-�OK�TO�DELETE�IT '‰MOVE.W‚#$400,USTUCNT(A1,D3)…SAVE�ENTRY(‰CLR.LƒUSTTNAME(A1,D3)ˆMARK�IT�-�NO�USER ‰BRA…DSEM_99  *** DSEM_40:3‰MOVE.L‚USTSESSN(A1,D3),D7†SAVE�SESSION�FOR�COMPARE4‰MOVE.L‚USTSNAME(A1,D3),D6†SAVE�SEM�NAME�FOR�COMPARE(‰CLR.LƒD4”ENTRY�#�OF�NEW�SEMAPHORE�ENTRY (‰MOVE.W‚USTCENT(A1),D2‡CURRENT�#�ENTRIES(‰MOVE.L‚#USTENTRY,D0‰OFFSET�OF�1ST�ENTRY DSEM_50:.‰TST.WƒUSTUCNT(A1,D0)‡LOOK�FOR�POINTER�ENTRIES‰BGE.SƒDSEM_70 '‰CMP.LƒUSTSESSN(A1,D0),D7ƒSAME�SESSION?‰BNE.SƒDSEM_70 .‰CMP.LƒUSTSNAME(A1,D0),D6ƒSAME�SEMAPHORE�NAME?‰BNE.SƒDSEM_70 ‰TST.WƒD4�FIRST�ONE�FOUND?‰BEQ.SƒDSEM_60ŠYES -‰MOVE.L‚D4,USTSPTR(A1,D0)…NO�SAVE�NEW�POINTER‰BRA.SƒDSEM_70 **ˆBuild�new�pointer.* DSEM_60:‰MOVE.L‚D0,D4ŠOFFSET�VALUE*˜MOVE�SEMAPHORE%‰MOVE.W‚USTUCNT(A1,D3),USTUCNT(A1,D0)#‰MOVE.WƒUSTSEM(A1,D3),USTSEM(A1,D0)'‰MOVE.L‚USTSEM+2(A1,D3),USTSEM+2(A1,D0)%‰CLR.WƒUSTUCNT(A1,D3)„CLEAR�OLD�ENTRY DSEM_70:‰ADD.Lƒ#USTEL,D0‡NEXT�ENTRY'‰SUB.Wƒ#1,D2‡DECREMENT�COUNT�OF�ENTRIES(‰BNE…DSEM_50…GO�BACK�TO�CHECK�NEXT�ENTRY ‰BRA.SƒDSEM_96‰NO‰PAGE**†DELETE�TYPE�3�SEMAPHORE* DSEM_80:#‰TST.B‚USTSEM+1(A1,D3)†ANY�WAITERS?‰BPL.S‚DSEM_90ŽNO ,‰MOVE.L�USTSEM+2(A1,D3),A5„GET�TCB�OF�WAITER,‰ADD.W‚#RTCDNFND,TCBRTCD(A5)ŠSEND�ERROR�CODE*‰MOVE.B�NE_CC,TCBCC(A5)�AND�CONDITION�CODE0‰TR0.Vƒ†TAKE�HIM�OUT�OF�WAIT�LIST ‰BRA…DSEM_80‰PAGE*-*†FIND�ALL�SEMAPHORE�POINTERS�AND�DELETE�THEM* DSEM_90:‰MOVE.L‚USTSESSN(A1,D3),D7‰MOVE.L‚USTSNAME(A1,D3),D6‰MOVE.WƒUSTCENT(A1),D2‰MOVE.Lƒ#USTENTRY,D0 DSEM_92:‰TST.W„USTUCNT(A1,D0)‰BPL.S„DSEM_94 ‰CMP.L„USTSESSN(A1,D0),D7‰BNE.S„DSEM_94 ‰CMP.L„USTSNAME(A1,D0),D6‰BNE.S„DSEM_94 ‰CLR.W„USTUCNT(A1,D0)&‰CLR.L„USTTNAME(A1,D0)†CLEAR�TASK�NAME DSEM_94:‰ADD.L„#USTEL,D0'‰SUB.W „#1,D2…DECREMENT�COUNT�OF�ENTRIES(‰BNE†DSEM_92ƒGO�BACK�TO�CHECK�NEXT�ENTRY ‰CLR.W„USTUCNT(A1,D3)  *!*†GIVE�UP�EXCLUSIVE�ACCESS�TO�UST*DSEM_96:&‰CLR.LƒUSTTNAME(A1,D3)‡CLEAR�TASK�NAME DSEM_99:‰RTS„.ˆRETURN�TO�USERˆENDéé**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.ENV.EQ*ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.ASQ.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ˆINCLUDEƒ9995.&.UTILITY.MC*‰NOLIST‰INCLUDEƒ9995.&.ENV.EQ‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.ASQ.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.INTERRUP.MC‰INCLUDEƒ9995.&.UTILITY.MC‰LIST‰PAGE‰IFEQ‚CHIPTYPE-68000"DISPATCH�IDNT‚5,1„68000�DISPATCHER‰ENDC‰IFEQ‚CHIPTYPE-68010"DISPATCH�IDNT‚5,1„68010�DISPATCHER‰ENDC*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*************ˆ*�DISPATCH�**ˆ*************4*„DISPATCH‚READY�JOBS�-�EXEC�CODE�(NOT�A�SUBROUTINE).*‡ENTRY:�NO�PARAMETERS...CODE�ENTERED�WITH�JMP5*‡EXIT�:�STARTS�TASK�EXECUTION�OR�WAITS�FOR�INTERRUPT*2*‚USES�REGISTERS‚(DOESN'T�MATTER-NOT�A�SUBROUTINE)**‚REVISION�HISTORY:*‚DATE†IDƒCHANGEJ*‚--------‚---‚-----------------------------------------------------------E*ƒ1/28/85‚SJF‚Removed�checks�for�MMUHERE�=�0�around�calls�to�LOADMMU.*ƒ1/�8/81‚HLD6*ƒ5/18/79‚7616*ƒ3/�6/79‚GGC3*‰SECTION�LEVEL00*‰XDEF†DISPATCH‰XDEF†L1_D0_SAVE ‰XDEF†PREEMPT ‰XREF†BKG_DISPATCH ‰XREF.S„EXCSTACK‰XREF.S„KILLER‰XREF.S„LOADMMU‰XREF.S„PERTURB_FLAGS‰XREF.S„PREEMPT_FLAG‰XREF.S„READYHD‰XREF.S„RUNNER ‰XREF.S„TERM‰XREF.S„TIMEOUT‰XREF.S„TIMESLIC‰XREF.S„TRACER‰XREF.S„TRACFLAG‰PAGE**ˆperform�a�level_1�rest�save;'*�(i.e.,�save�that�portion�of�the�state/*�which�was�saved�somewhere�other�than�the�TCB,-*�during�the�level_1�partial�save�in�the�TCB,**�and�thus�completing�a�level_1�full�save)*ˆready�the�task;*ˆand�perform�a�dispatch;* L1_D0_SAVE:5‰MOVE.L„D0,TCBD0(A6)ˆsave�D0,�before�doing�full�save; 0‰SAVE_STATEŠL1_FULLƒperform�a�level_1�full�save;  *.*ˆGot�preempted�out�of�dispatcher�-�try�again.* PREEMPT:3‰TR0.READY�(A6)�MAKE�THIS�GUY�READY,�AND�TRY�AGAIN.‰PAGE DISPATCH:[_dhl\tN|&‰MOVE.L„EXCSTACK,A7‰RESTORE�EXEC�STACK  DISP_10:#‰ENABLE_INTERRUPTS�ALLOW�INTERRUPTS5‰LEA‡READYHD-TCBREADY,A6�PREPARE�TO�SEARCH�READY�LIST)‰DISABLE_INTERRUPTSŒDisable�(interrupts);  DISP_20:#‰MOVE.L„A6,A1�SAVE�PREVIOUS�POINTER/‰MOVE.L„TCBREADY(A1),D0…NEXT�TASK�ON�READY�LIST"‰BEQ‡DISP_10�BRANCH�IF�NONE�EXISTS  *-*ˆDetermine�that�task�is�not�in�a�wait�state.* ‰MOVE.L„D0,A6�A6=TCB�POINTER(‰MOVE.B„TCBSTATE(A6),D0…CHECK�TASK�STATE&‰BNE‡DISP_20�BRANCH�IF�TASK�IS�WAITING  **ˆTake�task�off�ready�list,(*ˆand�establish�him�as�the�running�task.* 8‰MOVE.L„TCBREADY(A6),TCBREADY(A1)…REMOVE�FROM�READY�LIST6‰BCLR†#TSK2NRDY,TCBSTAT2(A6)ˆCLEAR�'ON�READY�LIST'�BIT(‰MOVE.L„A6,RUNNER•ESTABLISH�RUNNING�TASK  **ˆRestore�the�RTE�frame*ˆto�the�exec�stack.*  0‰MOVE.L„TCBPCLO(A6),-(A7)�restore�(pc_lo�&�vor);-‰MOVE.L„TCBSR(A6),-(A7)�restore�(sr�&�pc_hi);  **ˆReset�(preempt_flag);*ˆEnable�(timeslicing);* '‰SFˆPREEMPT_FL AGˆCLEAR�I/O�MESSAGE�FLAG:‰MOVE.W„TIMESLIC,TIMEOUT„TICSK�TILL�PROCESSOR�RELINQUISHED  *+*ˆDecode�the�dispatch�state�within�the�tcb.* 3*STATE_MASK‰EQU‡1<…Convert�address�to�physical&‰BRA.S…DISP_EV1ŒBranch�if�good�address ‰NOP›else+‰ADD.L…D7,TCBUSP(A6)Œrestore�stack�address,.‰MOVE.W„#$8099,D7�and�call�exec_abort�($8099);‰TR0.EXABRT�(A6)  **ˆNow�set�up�the�user�stack.* DISP_EV1:$‰ADD.L…D7,D6™USER�STACK�PHYS�ADDRESS%‰MOVE.L„D6,A4™USER�S TACK�PHYS�ADDRESS)‰MOVE.W„TCBSR(A6),-6(A4)ŽSR�TO�USER�STACK)‰MOVE.L„TCBPC(A6),-4(A4)ŽPC�TO�USER�STACK:‰BTST†#ASQSKDIS,ASQSTMD2(A5)ˆARE�REGISTERS�TO�GO�ON�STACK?‰BNE.S…DISP_EV2–BRANCH�IF�NO -‰MOVEM.LƒTCBD0(A6),D0-D7/A0-A3‰GET�D0�THRU�A3*‰MOVEM.LƒD0-D7/A0-A3,-66(A4)‹TO�USER�STACK*‰MOVEM.LƒTCBA0+16(A6),D0-D2ŒGET�A4�THRU�A6$‰MOVEM.LƒD0-D2,-18(A4)‘TO�USER�STACK  *+*ˆPlace�the�ASR�address�on�the�super�stack,*ˆand�go�to�dispatch�the�task.* DISP_EV2:%‰MOVE.L„ASQXFR(A5),D0‡GET�ASR�ADDRESS1‰MOVE.L„D0,2(A7)ŒSAVE�ON�SUPER�STACK�FOR�DISPATCH‰MOVE.L„D0,TCBPC(A6)ˆAND�IN�TCB%*¦(This�is�neccessary�for�the�case�in$*¦which�this�task�will�get�preempted$*¦out�of�the�dispatcher,�by�a�higher!*¦priority�task.‚This�instruction&*¦will�allow�the�dispatcher�to�"retry"%*¦this�dispatch,�at�some�later�date.) $‰BRA‡DISP_MMUŒCONTINUE�WITH�DISPATCH‰PAGE*1*ˆDispatch�the�task�to�the�place�within�the�exec,!*ˆwhere�he�was�when�we�froze�him.)*ˆ(Usually�due�to�waiting�on�a�semaphore,&*ˆor�waiting�on�an�exception�monitor.)* *%*ˆFirst,�load�the�MMU�to�recreate�the#*ˆenvironment,�prior�to�the�freeze.* DISP_EXEC:%‰MOVE.L„TCBTST(A6),A5‡GET�TST�ADDRESS‰BSR‡LOADMMU�GO�LOAD�THE�MMU  ‰TCBSTK¢RESTORE�EXEC�STACK#‰ENABLE_INTERRUPTS—ALLOW�INTERRUPTS8‰MOVEM.LƒTCBXREGS(A6),D0-D7/A0-A6†RESTORE�EXEC�REGISTERS.‰MOVE.B„D0,TCBRPRI(A6)�RESTORE�USER'S�PRIORITY‰RTS¥AND�BACK�TO�EXEC‰PAGE*+*ˆStop�pending�-�Transfer�to�abort�routine.* DISP_TERM:#‰ENABLE_INTERRUPTS�ALLOW�INTERRUPTS 2‰PUSH.L„A6’Make�stack�look�like�result�of�trap�#1.‰BRA‡TERM�GO�TO�TERM�ROUTINE‰ENDééééé=/*=/*†M68XXX.DSEGX.AF=/**=/* Chain file to assemble M68XXX.DSEGX.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.DSEGX.LS=/*=/IFC \1ƒ=ARG�M68XXX.DSEGX.LS=/ENDIF=/*/=ASM M68XXX.DSEGX.SA,M68XXX.DSEGX.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.SEG.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.GST.EQ=/*}=/*=ENDéé ééé鄉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.GST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.SEG.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.GST.EQ‰LIST‰PAGE4DSEGX„IDNT‚5,1ƒ68xxx�TRAP�0--DEALLOCATE�ALL�SEGMENTS*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*„DSEGXƒ--�REV�1.01ƒ10/08/79‚(HLD6)*Œ--�TRAP�0�ROUTINE*1*…PURPOSE:‚DEALLOCATE�ALL�SEGMENTS�DEFINED�IN�TST*'*‰ENTRY:‚A4�HAS�REQUESTOR'S�TCB�ADDRESS*0*ŠEXIT:‚ALL�ENTRIES�IN�TST�FOR�THIS�TASK�DELETED* *–01234567*„REGISTERS�USED:�D�***‚*** *”A�***�E*ES*‰SECTION�LEVEL03*0‰XDEF„DSEGXŠENTRY--EXEC--DEALLOCATE�ALL�SEGMENTS2‰XDEF„SBDSEGXˆENTRY--EXEC--DEALLOCATE�ALL�SEGMENTS ‰XREF„DESEG_SUB ‰XREF„KILLER‰XREF.S‚GSTBEG‰PAGE*3*ˆGet�exclusive�access�to�task�segment�table�(TST).* SBDSEGX:DSEGX:!‰TST.LƒTCBTST(A4)…IS�THERE�A�TST?‰BEQ.SƒDSEGX_40‡NO ‰IFNE„MULTPROC‰TR0.PƒTCBTSTSM(A4)‰ENDC $‰MOVE.L‚TCBTST(A4),A5„ADDRESS�OF�TST  **ˆFind�segment�to�de-allocate.* ‰CLR.L„D51‰MOVE.WƒTSTLATTR(A5),D5‰OFFSET�TO�LAST�ATTR�ENTRY DSEGX_10:.‰BTST„#SEGAUSED,TSTAATTR(A5,D5)ƒIS�ENTRY�USED?‰BEQ.S„DSEGX_30“BRANCH�IF�NO  *(*ˆTransfer�to�normal�segdeal�subroutine.* ˆCLR.L†D49ˆBTST‡#TSKILAST,TCBATTI(A4)‰IS�THIS�LAST�TASK�IN�SESSION? (ˆIF‚ƒTHEN.S“IF�LAST�TASK�IN�SESSION,3ˆBSET‡#SGPBORMV,D4�THEN�SET�REMOVE�PERM�STATUS�BIT.ˆENDI ˆBSRˆDESEG_SUB•call�deseg_sub;ALˆPAGE*/*ˆSee�if�there�are�any�more�segments�to�delete.* DSEGX_30:!‰SUB.L„#8,D5ŠOFFSET�TO�NEXT�ENTRY-‰CMP.W„#TSTMMU,D5…DECREMENT�COUNT�OF�SEGMENTS*‰BGE†DSEGX_10ˆBRANCH�BACK�FOR�NEXT�SEGMENT  **ˆAll�segments�deleted."*ˆRelease�exclusive�access�to�TST.* ‰IFNE„MULTPROC3‰TR0.VƒTCBTSTSM(A4)‚GIVE�UP�EXCLUSIVE�ACCESS�TO�TST‰ENDC  *!*ˆCheck�for�last�task�in�session.* DSEGX_40:�n–Q9‰BTSTƒ#TSKILAST,TCBATTI(A4)ƒIS�THIS�LAST�TASK�IN�SESSION?&‰BEQ.S‚DSEGX_99ˆBRANCH�IF�NO�--�RETURN‰PAGE**ˆLast�task�in�session.5*ˆGet�exclusive�access�to�global�segment�table�(GST).* ‰IFNE„MULTPROC)‰TR0.PƒSEMGST†GET�EXCLUSIVE�ACCESS�TO�GST‰ENDC  **ˆSearch�global�segment�table.* -‰MOVE.L‚GSTBEG,A1�PNTR�TO�GLOBOL�SYMBOL�TABLE'‰LEA…GSTENTRY(A1),A5‡FIRST�ENTRY�IN�GST,‰MOVE.W‚GSTLENT(A1),D7ˆNUMBER�ENTRIES�IN�GST‰BEQ.SƒDSEGX_70ŽTABLE�IS�EMPTY /‰MOVE.L‚TCBSESSN (A4),D6‡GET�SESSION�FOR�COMPARE  **ˆCheck�one�GST�entry.* DSEGX_50:‰TST.WƒGSTCNT(A5)ŒIS�ENTRY�USED‰BEQ.SƒDSEGX_60ŽBRANCH�IF�NO ,‰CMP.LƒGSTSESSN(A5),D6‡COMPARE�SESSION�CODES"‰BNE.SƒDSEGX_60ŒBRANCH�IF�NO�MATCH #‰BCLR„#15,GSTCNT(A5)†CLEAR�PERM�BIT%‰TST.WƒGSTCNT(A5)‡ENTRY�STILL�IN�USE?‰BNE.SƒDSEGX_60ˆBRANCH�IF�YES‰PAGE*,*ˆFree�pages�belonging�to�permanent�segment.* #SPSEGMK�EQU…1<ˆBRA.S†DSEGX_60 ˆBSR‡KILLER  *,*ˆSee�if�there�are�any�more�entries�to�check*ˆin�the�global�segment�table.* DSEGX_60:#‰ADD.Lƒ#GSTEL,A5�INCR�TO�NEXT�ENTRY'‰SUB.Wƒ#1,D7†DECREMENT�COUNT�OF�ENTRIES-‰BNE…DSEGX_50„BRANCH�BACK�TO�CHECK�NEXT�ENTRY  *"*ˆRelease�exclusive�access�to�GST.* DSEGX_70:‰IFNE„MULTPROC-‰TR0.VƒSEMGST‰GIVE�UP�EXCLUSIVE�ACCESS�TO�GST‰ENDC DSEGX_99 ‰RTS’RETURN‰ENDé=/*=/*†M68XXX.DSEMX.AF=/**=/* Chain file to assemble M68XXX.DSEMX.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.DSEMX.LS=/*=/IFC \1ƒ=ARG�M68XXX.DSEMX.LS=/ENDIF=/*/=ASM M68XXX.DSEMX.SA,M68XXX.DSEMX.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.UST.EQ=/*}=/*=ENDééééé鞉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.UST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.UST.EQ‰LIST‰PAGE7DSEMX„IDNT‚5,1„68xxx�TRAP�0--DETACH�FROM �ALL�SEMAPHORES*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*"*„DSEMXƒ--�REV�1.01ƒ7/01/79ƒ(HLD6)*Œ--�TRAP�0�ROUTINE*%*…DETACH�ALL�SEMAPHORES�FOR�THIS�TASK*ˆSECTION�LEVEL04* ‰XDEF†SBDSEMX ‰XREF†DSEM_SUB ‰XREF.S„SEMUST‰PAGE*9*ˆCheck�to�see�if�this�task�is�attached�to�any�semaphore.* SBDSEMX::‰BTST†#TSKIUSEM,TCBATTI(A4)‰Is�task�attached�to�semaphore. ‰BEQ.S…DSEMX_99–No,�just�return.   **ˆGet�exclusive�access�to�UST.* ‰IFNE†MULTPROC ‰TR0.P…SEMUST‰ENDC  *&*ˆFind�one�entry�in�UST�for�this�task.* DSEMX_10: ‰TR0.FNDSEMƒ0-‰BRA.S…DSEMX_20–Found�one,�go�detach�from�it.  *"*ˆRelease�exclusive�access�to�UST, *ˆand�return.* ‰IFNE†MULTPROC ‰TR0.V…SEMUST‰ENDC DSEMX_99:%‰RTS›Return,�all�semaphores�detached.  */*ˆCall�subroutine�to�detach�from�one�semaphore,*ˆand�try�again.* DSEMX_20: ‰BSR‡DSEM_SUB ‰BRA‡DSEMX_10‰ENDééé§Q=/*=/*†M68XXX.DSERVE.AF=/*+=/* Chain file to assemble M68XXX.DSERVE.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.DSERVE.LS=/*=/IFC \1ƒ=ARG�M68XXX.DSERVE.LS=/ENDIF=/*1=ASM M68XXX.DSERVE.SA,M68XXX.DSERVE.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TIOT.EQ=/*}=/*=ENDéééééé °‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TIOT.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TIOT.EQ‰LIST‰PAGE;DSERVE�IDNT�5,1‚68xxx�DIRECTIVE--DEALLOCATE�SERVER�FUNCTION*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*$*„DSERVE‚--�REV�3.00‚12/01/81‚(HLD6)*�REV�2.00ƒ6/25/79‚(HLD6)*š2/08/81‚(HLD6)*Œ--�TRAP�1�ROUTINE*%*…PURPOSE:‚DEALLOCATE�SERVER�FUNCTION*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS+*‘A0�BITS�0-3�=�TRAP�INSTRUCTION�IDENTIFIER**ŠEXIT:ƒD0�HAS�RETURN�CODE*’D0�=�0‚GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*4*ŠRTCDNFND�-�7ƒSPECIFIED�TRAP�NOT�ASSIGNED�TO�CALLER*‰SECTION�LEVEL04* ‰XDEF„DSERVE‰XDEF„DSERV_SUB ‰XREF.S‚TCBHD ‰XREF.S‚TIAT ‰XREF.S‚TIOT‰PAGEDSERVE:‰MOVE.L‚A0,D2‰SAVE�TRAP�NUMBER  **ˆGet�exclusive�access�to�TIOT.* ‰IFNE„MULTPROC‰TR0.PƒSEMTIOT‰ENDC  *&*ˆCheck�to�see�if�requestor�is�server.* "‰AND.Lƒ#$0F,D2�ISOLATE�TRAP�NUMBER‰LEA…TIAT,A2�ADDRESS�OF�TIAT+‰CMP.Bƒ#TIATUSER,0(A2,D2)„IS�TRAP�ASSIGNED?‰BNE.SƒDSERV_ERR�NO ‰MOVE.L‚D2,D1‘MOVE�TRAP�#�TO�D1'‰MULU„#TIOTEL,D1ŒCALCULATE�ENTRY�OFFSET‰LEA…TIOT,A1�START�OF�TIOT*‰CMP.LƒTIOTTCB(A1,D1),A6…IS�TASK�THE�SAME?&‰BNE.SƒDSERV_ERR�BRANCH�IF�NO�-�ERROR. (‰BSR.S…DSERV_SUB‹CALL�DSERVE�SUBROUTINE. ‰IFNE„MULTPROC‰TR0.VƒSEMTIOT‰ENDC ‰EXIT†SUB DSERV_ERR:‰IFNE„MULTPROC‰TR0.VƒSEMTIOT‰ENDC !‰EXIT„RTCDNFNDŽRETURN�(ERROR_07);‰PAGE=***************************************************************-**‡Subroutine�to�de-allocate�server�function.**‡Called�by�DSERVE�and�DSRVX.**=**************************************************************3*‡REQUESTOR�IS�SERVER�-�LOOK�FOR�ANYONE�WAITING�FOR"*�ACKNOWLEDGEMENT�FROM�THIS�SERVER* *'*ˆGet�exclusive�access�to�tcb�all�list.* DSERV_SUB:‰IFNE„MULTPROC¹jÂ7.‰TR0.PƒSEMTCBŠGET�EXCLUSIVE�ACCESS�TO�TCB�LIST‰ENDC !‰MOVE.L‚TCBHD,A3‘1ST�TCB�IN�CHAIN DSERV_10:-‰BTSTƒ#TSKSAKWT,TCBSTATE(A3)„IS�TASK�WAITING?‰BEQ.SƒDSERV_20‘BRANCH�IF�NO ,‰CMP.BƒTCBUTRP(A3),D2‹WAITING�FOR�THIS�TRAP?‰BNE.SƒDSERV_20‘BRANCH�IF�NO .‰BCLRƒ#TSK2ACK2,TCBSTAT2(A3)„CLEAR�2ND�ACK�BIT)‰BCLRƒ#TSKSAKWT,TCBSTATE(A3)„STOP�WAITING-‰MOVE.L‚#RTCDDIRN,TCBD0(A3)†RETURN�ERROR�CODE‰LSL.W‚#3,D2•SHIFT�TRAP�#-‰MOVE.B‚D2,TCBD0(A3)�PUT�TRAP�#�IN�BITS�27-304‰CLR.B�TCBCC(A3)�CLEAR�CONDITION�CODE�FOR�BAD�RETURN‰LSR.W‚#3,D2•RESTORE�TRAP�#‰TR0.READY‚(A3)’REACTIVATE�TASK DSERV_20:'‰MOVE.L‚TCBALL(A3),A3ŒNEXT�TCB�IN�CHAIN%‰MOVE.L‚A3,D0”IS�THERE�ANOTHER�ENTRY?‰BNE…DSERV_10‘BRANCH�IF�YES  *+*ˆRelease�exclusive�access�to�tcb�all�list.* ‰IFNE„MULTPROC2‰TR0.VƒSEMTCB†RELEASE�EXCLUSIVE�ACCESS�TO�TCB�LIST‰ENDC‰PAGE**ˆDeallocate�server�function.* %‰CLR.Bƒ0(A2,D2)ŠCLEAR�TIAT�ASSIGNMENT%‰CLR.LƒTIOTTCB(A1,D1)„CLEAR�TASK�NAME+‰CLR.LƒTIOTADDR(A1,D1)ƒCLEAR�INTERRUPT�ADDR#‰CLR.WƒTIOTSTAT(A1,D1)ƒCLEAR�STATUS DSERV_30:+‰BTST„#14,TIOTSEM(A1,D1)�ANY�USERS�WAITING?‰BEQ.SƒDSERV_99ŠBRANCH�IF�NO -‰TR0.Vƒ‚RESTART�WAITING�USERS%‰BRA…DSERV_30ŠLOOP�BACK�TO�TEST�AGAIN  DSERV_99:‰RTS‰END éé=/*=/*†M68XXX.DSRVX.AF=/**=/* Chain file to assemble M68XXX.DSRVX.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.DSRVX.LS=/*=/IFC \1ƒ=ARG�M68XXX.DSRVX.LS=/ENDIF=/*/=ASM M68XXX.DSRVX.SA,M68XXX.DSRVX.RO,\1;MRZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TIOT.EQ=/*}=/*=ENDééééééʉPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TIOT.EQE*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TIOT.EQ‰LIST‰PAGE7DSRVX…IDNT�5,1‚68xxx�TRAP�0--DEALLOCATE�SERVER�FUNCTION*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*"*„DSRVXƒ--�REV�1.00ƒ7/02/79‚(HLD6)*Œ--�TRAP�0�ROUTINE*%*…PURPOSE:‚DEALLOCATE�SERVER�FUNCTION*'*‰ENTRY:‚A4�HAS�REQUESTOR'S�TCB�ADDRESS*1*ŠEXIT:‚ALL�ENTRIES�IN�TIOT�FOR�THIS�TASK�DELETED* *–01234567*„REGISTERS�USED:�D�*** *”A�***�E�ES*‰SECTION�LEVEL04* ‰XDEF„SBDSRVX ‰XREF„DSERV_SUB ‰XREF.S‚SEMTIOT ‰XREF.S‚TIAT ‰XREF.S‚TIOT‰PAGESBDSRVX:%‰LEA…TIAT,A2ˆASSIGNMENT�TABLE�ADDRESS ‰LEA…TIOT,A1ˆOWNER�TABLE�ADDRESS&‰MOVE.L‚#2,D2ŠSTART�SEARCH�WITH�TRAP�2  **ˆGet�exclusive�access�to�TIOT.* ‰IFNE„MULTPROC‰TR0.PƒSEMTIOT‰ENDC  *$*ˆLook�for�TIOT�entry�for�this�task.* DSRVX_10:+‰CMP.Bƒ#TIATUSER,0(A2,D2)„IS�TRAP�ASSIGNED?‰BNE.SƒDSRVX_20‹NO ‰MOVE.L‚D2,D1†PUT�TRAP�#�IN�D1'‰MULU„#TIOTEL,D1…CALCULATE�ENTRY�OFFSET*‰CMP.LƒTIOTTCB(A1,D1),A4�IS�TASK�THE�SAME?‰BEQ.SƒDSRVX_30‡BRANCH�IF�YES DSRVX_20:#‰ADD.Lƒ#1,D2‡INCREMENT�TO�NEXT�TRAP"‰CMP.Lƒ#16,D 2†HAVE�WE�CHECKED�ALL?!‰BLT.SƒDSRVX_10ƒGO�CHECK�NEXT�ONE  *#*ˆRelease�exclusive�access�to�TIOT.* ‰IFNE„MULTPROC/‰TR0.VƒSEMTIOT†GIVE�UP�EXCLUSIVE�ACCESS�TO�TIOT‰ENDC ‰RTS“RETURN�TO�CALLER  *$*ˆTransfer�to�normal�DSERVE�routine.* DSRVX_30:ˆBSR‡DSERV_SUB ˆBRA‡DSRVX_10ˆENDéÓ^=/*=/*†M68XXX.EQDQ.AF=/*)=/* Chain file to assemble M68XXX.EQDQ.SA=/*:=/* If no output argument is specified for the listing the-=/* chain file will default to M68XXX.EQDQ.LS=/*=/IFC \1ƒ=ARG�M68XXX.EQDQ.LS=/ENDIF=/*-=ASM M68XXX.EQDQ.SA,M68XXX.EQDQ.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.ASQ.EQ=/*ƒ9995.&.TIOT.EQ=/*ƒ9995.&.SRVR.EQ=/*}=/*=ENDéééééé܉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.ASQ.EQ*ˆINCLUDEƒ9995.&.TIOT.EQ*ˆINCLUDEƒ9995.&.SRVR.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.ASQ.EQ‰INCLUDEƒ9995.&.TIOT.EQ‰INCLUDEƒ9995.&.SRVR.EQ‰LIST‰PAGE+EQDQ„IDNT�5,1‚68xxx�TRAP�0--ENQUEUE/DEQUEUE*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*!*†EQDQƒ--�REV�3.00ƒ6/25/79‚(HLD6)*›2/20/81‚(HLD6)*š11/22/81‚(HLD6)*�--�TYPE�2�USER�TRAP�ROUTINE:*†EXEQDQ�--�TRAP�0�ROUTINE�TO�SEND�FINAL�MESSAGE�TO�SERVER*$*…PURPOSE:‚ENQUEUE/DEQUEUE�USER�TRAP4*�TRAP�IN�REQUESTING�TASK�IS�TO�BE�HANDLED�BY�SERVER&*�PLACE�TYPE�7�MESSAGE�IN�SERVER'S�A SQ*'*‰ENTRY:‚A4�HAS�REQUESTOR'S�TCB�ADDRESS*‘D7�=�TRAP�NUMBER%*‘A0�AND�D0�ARE�REQUESTOR'S�A0�AND�D0*0*ŠEXIT:ƒRETURN�TO�REQUESTOR�DETERMINED�BY�SERVER1*’ERROR�RETURN�(NO�SERVER)�-�CARRY�BIT�SET�IN�CCR*‰SECTION�LEVEL00* ‰XDEF…EQDQ ‰XDEF…EXEQDQ‰XDEF…SBEXEQDQ ‰XREF.SƒTIOT‰PAGE SBEXEQDQ�DS.W„0•SUBROUTINE�ENTRY/EXEQDQƒLEA…TIOT,A2�ENTER�HERE�FOR�FINAL�MESSAGE)‰BSET„#TYP7TTRM,D7ŠSET�FINAL�MESSAGE�FLAG+‰BSET„#TYP7TTRM,TCBUTRP(A4)�SET�IN�TCB�ALSO9‰BTST„#TSKILAST,TCBATTI(A4)�IS�THIS�LAST�TASK�IN�SESSION?‰BEQ.SƒEQDQBOTHŽBRANCH�IF�NO %‰BSET„#TYP7TLST,D7ŠSET�LAST�TASK�FLAG)‰BRA.SƒEQDQBOTHŽBRANCH�TO�MESSAGE�ROUTINE  *!*‹ENTRY�FOR�NORMAL�TRAP�EXECUTION* EQDQ:‰MOVE.L‚D7,D1‘TRAP�NUMBER‰MULU„#TIOTEL,D1ŒOFFSET�TO�TIOT&‰LEA…TIOT,A2�START�OF�TRAP�OWNER�TABLE‰MOVE.L‚A6,A4‘CALLER'S�TCB'‰MOVE.B‚D7,TCBUTRP(A4)ˆSAVE�TRAP�NUMBER  **ƒGET�SERVER'S�TCB* EQDQBOTH:&‰MOVE.L‚TIOTTCB(A2,D1),A5…SERVER'S�TCB$‰CMP.LƒA6,A5‘IS�SERVER�CALLING�SELF?"‰BEQ…EQDQERR�BRANCH�IF�YES�-�ERROR 4‰BTST„#TSKASYST,TCBATTR(A5)�IS�SERVER�A�SYSTEM�TASK?‰IF��THEN.S�BRANCH�IF�YES,ŒMOVE.L‚TCBSESSN(A4),D0„CALLER'S�SESSION�NO.0ŒCMP.LƒTCBSESSN(A5),D0„IS�CALLER'S�SESSION�NO.�=*©SERVER'S�SESSION�NO.�?åVîKö1ŒBNE…EQDQERRŒERROR�IF�NOT�EQUAL‰ENDI *!*†BUILD�MESSAGE�TO�SEND�TO�SERVER* '‰MOVE.L‚#$1C870000,D2‰MESG�LENGTH,�TYPE5‰MOVE.W‚TIOTADDR(A2,D1),D2„INTERRUPT�ADDR�(UPPER�1/2)7‰MOVE.L‚TIOTADDR+2(A2,D1),D3‚INTERRUPT�ADDR�(LOWER�1/2)‰MOVE.W‚D7,D3‘TRAP�NUMBER 4‰BTST„#TSKASYST,TCBATTR(A4)�IS�CALLER�A�SYSTEM�TASK?‰BEQ.SƒEQDQ1A�BRANCH�IF�NO+‰BSET„#TYP7TSYS,D3ŠYES�-�SET�BIT�FOR�SERVER  EQDQ1A:8‰BTSTWƒ#TSKARTIM,TCBATTR(A4)�IS�CALLER�A�REAL�TIME�TASK?‰BEQ.SƒEQDQ1A_1ŽBRANCH�IF�NO +‰BSET„#TYP7TRTT,D3ŠYES�-�SET�BIT�FOR�SERVER  EQDQ1A_1:.‰LSL.Wƒ#8,D3‘MOVE�TRAP�#�TO�UPPER�BYTE�OF�WORD‰MOVE.B‚TCBCPRI(A4),D3ˆPRIORITY‰MOVE.L‚A4,D4‘TCB�ADDRESS$‰MOVE.L‚TCBSESSN(A4),D5‡SESSION�CODE"‰MOVE.L‚TCBUSER(A4),D6ˆUSER�NUMBER*‰MOVE.W‚TCBD0(A4),D6ŠUSER'S�D0�(UPPER�1/2),‰MOVE.L‚TCBD0+2(A4),D7ˆUSER'S�D0�(LOWER�1/2)*‰MOVE.W‚TCBA0(A4),D7ŠUSER'S�A0�(UPPER�1/2),‰MOVE.L‚TCBA0+2(A4),D0ˆUSER'S�A0�(LOWER�1/2)1‰MOVE.W‚#T7STNORQ<<8,D0‡SET�PB�STAT�TO�NO�REQUEST8‰BTST„#TIOTSPBO,TIOTSTAT(A2,D1)‚WAS�PARAMETER�BLOCK�REQ?‰BEQ.S„EQDQ1B�BRANCH�IF�NO ‰CLR.W„D0“CLEAR�PB�STATUS1‰MOVE.BƒTIOTPBSZ(A2,D1),D0ƒPUT�PB�SIZE�IN�MESSAGE  *B*‚IF�THIS�IS�TERM�MESSAGE�-�REPLACE�CONTENTS�OF�D0�WITH�ABORT�CODE* EQDQ1B:+ˆBTSTƒ#TYP7TTRM+8,D3ŠIS�THIS�A�TERM�MESSAGEˆBEQ.S‚EQDQ1C’BRANCH�IF�NO >ˆMOVE.W�TCBABORT(A4),D6‰REPLACE�D0�(UPPER�1/2)�WITH�ABORT�CODE7ˆMOVE.L�TCBATTR(A4),D7ŠREPLACE�D0�(LOWER�1/2)�WITH�ATTR7ˆMOVE.W�TCBATSK(A4),D7ŠREPLACE�A0�(UPPER�1/2)�WITH�ATSKˆSWAPƒD0;ˆMOVE.W�TCBATSK+2(A4),D0ˆREPLACE�A0�(LOWER�1/2)�WITH�ATSK+2ˆSWAPƒD0 EQDQ1C:-ˆMOVE.L�D0,A1“MOVE�LAST�PART�OF�MESSAGE�TO�A1  *,*…CHANGE�INTERRUPT�ADDRESS�IF�SERVER�HAS�ONE* .ˆTST.LƒTIOTADDR(A2,D1)‡WAS�INTERRUPT�ADDR�=�0?ˆBNE.SƒEQDQ2‘BRANCH�IF�NO &ˆMOVE.L‚TCBASQ(A5),D0‰TEST�ASQ�ADDRESSˆBEQ.SƒEQDQER2�BRANCH�IF�NO�ASQ ˆMOVE.L‚D0,A3‘ASQ�ADDRESS3ˆMOVE.W‚ASQASR(A3),D2‰INTERRUPT�ADDRESS�(UPPER�1/2)ˆSWAP„D35ˆMOVE.W‚ASQASR+2(A3),D3‡INTERRUPT�ADDRESS�(LOWER�1/2)ˆSWAP„D3  **…WAIT�UNTIL�SERVER�IS�READY* EQDQ2:ˆTR0.Pƒ-ˆTST.LƒTIOTTCB(A2,D1)ˆIS�SERVER�STILL�ACTIVE?ˆBEQ.SƒEQDQER2�BRANCH�IF�NO &ˆMOVEM.L�D1/A2/A4,-(A7)ˆSAVE�REGISTERSˆTR0.QEVNTTƒ(A5)�SEND�MESSAGE ˆBRA.SƒEQDQ3  **…ASQ�FULL�-�REJECT�REQUEST* )ˆMOVEM.L�(A7)+,D1/A2/A4ˆRESTORE�REGISTERS*ˆTR0.Vƒ„SIGNAL�SEMAPHORE EQDQER2:*ˆMOVE.B‚TCBUTRP(A4),D7ˆRESTORE�TRAP�NUMBER EQDQERR:)ˆBTSTƒ#TYP7TTRM,D7‹IS�THIS�FINAL�MESSA GE? ˆBNE.S‚EQDQRTN�YES�-�JUST�RETURN  !ˆEXITƒTRAPERR�TRAPPING�ERROR�EXIT  *+*„SET�WAIT�FOR�ACKNOWLEDGE�STATE�AND�RETURN* EQDQ3:)‡MOVEM.L�(A7)+,D1/A2/A4‰RESTORE�REGISTERS4‡AND.Bƒ#$0F,TCBUTRP(A4)‡CLEAR�EXTRA�BITS�FROM�TRAP�#0‡BSET„#TIOTSMSG,TIOTSTAT(A2,D1)�SET�MESSAGE�FLAG6‡ADD.Wƒ#1,TIOTMCNT(A2,D1)…INCREMENT�MESSAGE�SENT�COUNT-‡BSET„#TSKSAKWT,TCBSTATE(A4)�SET�WAIT�FOR�ACK EQDQRTN: ‡RTSœRETURN‡ENDéééé=/*=/*†M68XXX.EXABRT.AF=/*+=/* Chain file to assemble M68XXX.EXABRT.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.EXABRT.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXABRT.LS=/ENDIF=/*1=ASM M68XXX.EXABRT.SA,M68XXX.EXABRT.RO,\1;MRZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDééééééþ‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE(EXABRTƒIDNTƒ5,1„68xxx�TRAP�0--ABORT�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ *********************ˆ*�EXABRT†2.00�**ˆ*�HLD6„03/24/81�**ˆ*********************5*„EXABRTƒEXEC�ROUTINE„ABORTS�USER�TASK�FROM�EXEC�MODE9*‰ENTRY:�A0�POINTS�TO�TASK�CONTROL�BLOCK�OF�TASK�TO�ABORT*�D7�CONTAINS�ABORT�CODE*�A6�IS�ADDRESS�OF�RUNNING�TCB**‰EXIT�:�RTS�WITH�NO�PARAMETERS*�IF�A0=A6�--�NO�RETURN* *’01234567*�USES�REGISTERS�D�*†**�A�P*ŠSECTION�LEVEL00* ˆXDEF‡EXABRTˆXDEF‡SBEXABRT ˆXREF‡TERMˆPAGEASTATMSK�EQU…$FFFF-1<*�Added�SIX_TO_FOUR_WORD_FRAME�code�to�handle�68020�exceptions%*�which�throw�six�words�on�the�stack.*‰11/27/84ƒSJF=*�Added�conditional�assembly�code�to�handle�68020�versions�of0*�bus�error,�address�error,�and�trace�exception.**‰SECTION�LEVEL00* ‰XDEF†TRPVCT2 ‰XDEF†TRPVCT3 ‰XDEF†TRPVCT4 ‰XDEF†TRPVCT5 ‰XDEF†TRPVCT6 ‰XDEF†TRPVCT7 ‰XDEF†TRPVCT8 ‰XDEF†TRPVCT9 ‰XDEF†TRPVCTA ‰XDEF†TRPVCTB ‰XDEF†TRPVCTC ‰XDEF†TRPVCTD ‰XDEF†TRPVCTE ‰XDEF†TRPVCTF +‰XDEF†BERR1ŒReferenced�by�M68010.AUTOVCT.SA L*�NOTE:‚BERR1�and�BERR2�(defined�later�if�operating�on�68020)�are�referencedJ*ƒin�the�AUTOVCT�module.‚These�labels�represent�the�first�two�instructionsL*ƒthat�are�executed�following�a�bus�error.‚At�label�BERR2�we�mask�interruptsH*ƒto�level�7.‚It�is�important�that�on�a�bus�error,�we�do�not�execute�anyK*ƒother�instructions�besides�those�at�BERR1�and�BERR2�before�interrupts�areI*ƒmasked.‚AUTOVCT�must�be�able�to�determine�whether�an�interrupt�occurredK*ƒduring�bus�error�processing�before�the�interrupts�are�masked�and�comparesH*ƒthe�address�on�the�stack�against�the�addresses�of�BERR1�and�BERR2.‚SeeL*ƒdocumentation�in�AUTOVCT�for�further�information�on�bus�error�handling�for*ƒVME12X�machines. ‰XDEF†CKEXMON‰XDEF†PROGINT2‰XDEF†PROGINT3‰XDEF†PROGINT4‰XDEF†PROGINT5‰XDEF†PROGINT6‰XDEF†PROGINT7‰XDEF†PROGINT8‰XDEF†PROGINT9‰XDEF†PROGINTA‰XDEF†PROGINTB ‰XREF†ISRERRé ‰XREF†KILLER‰XREF†MMUFAULT ‰XREF†SVXSTAK ‰XREF†TRACER ‰XREF†MMUHERE ‰XREF†TTB_01 ‰XREF†TTE_01 ‰XREF.S„EXCSTACK‰XREF.S„TRACFLAG‰XREF.S„PREEMPT_FLAG‰PAGEO********************************************************************************Í*A*ˆThis�is�a�secondary�vector�table�for�program�generated�traps.ˆ*?*ˆIt�is�required�to�support�the�68000,�because�the�68000�doesŠ*0*ˆnot�support�the�VOR�(vector�offset�register.™**Í*O*******************************************************************************  TRAPVCT‚BSR.S…TRAPX ‰BSR.S…TRAPXTRPVCT2‚BSR.S…TRAPXTRPVCT3‚BSR.S…TRAPXTRPVCT4‚BSR.S…TRAPXTRPVCT5‚BSR.S…TRAPXTRPVCT6‚BSR.S…TRAPXTRPVCT7‚BSR.S…TRAPXTRPVCT8‚BSR.S…TRAPXTRPVCT9‚BSR.S…TRAPXTRPVCTA‚BSR.S…TRAPXTRPVCTB‚BSR.S…TRAPXTRPVCTC‚BSR.S…TRAPXTRPVCTD‚BSR.S…TRAPXTRPVCTE‚BSR.S…TRAPXTRPVCTF‚BSR.S…TRAPX‰NOP‰PAGEO********************************************************************************Í**…TRAP�HANDLER�FOR�USER�TRAPS­**…TRAPS�2�THRU�F�COME�HERE°**Í*;*…ENTRY:ƒLOCATION�OF�SECONDARY�TRAP�VECTOR�SAVED�ON�STACK�**Í**…EXIT�:ƒD7�=�TRAP�NUMBER¯*)*ŽIF�SERVER�EXISTS�-�GO�TO�ERDQ�ROUTINEš*8*ŽIF�NO�SERVER,�RETURN�TO�CALLER�WITH�CARRY�SET�IN�CCR‹**Í*6*�USES�REGISTERS�(ALL�USER�REGISTERS�SAVED�ON�STACK)š**Í*O*******************************************************************************‰PAGE**ˆTrap�exception�occurred.*ˆPsuedo�vector�on�stack.* TRAPX: ‰TESTIM„4(‰BEQ.S…TRAPX1ŽBRANCH�IF�NORMAL�USER�TRAP *‰BTST†#SRMODE,4(A7)‡WAS�TRAP�IN�SUPR�MODE?‰BEQ‡PRGINTTEŒBRANCH�IF�NO ‰BSR‡KILLER  **ˆTrap�exception�occurred*ˆin�normal�user�mode.* TRAPX1:(‰SAVE_STATEƒEXCEPTIONˆSave�user's�state. /‰BTST†#TRCFTRAP,TR  ACFLAG‚SHOULD�TRAP�BE�TRACED?‰BEQ.S…TRAPX2ŽBRANCH�IF�NO ‰PUSH.W„SR’SAVE�SR�FOR�TRACE‰BSR‡TRACERŽBUILD�TRACE�ENTRY ‰DC.W†$AA12‰ADD.L…#2,A7�RESTORE�A7  *&*ˆGet�pointer�to�trap�exception�table,&*ˆand�go�to�generic�exception�handler.* TRAPX2:*‰LEA‡TRAPXTBL(PC),A5…POINTER�TO�PARAMETERS‰BRA‡UX  TRAPXTBL:(‰DC.L†TRAPVCT+2‹PSEUDO-VECTOR�BASE�+�1*2$‰DC.W†TSKITVCTŒVECTOR-TYPE�ATTRIBUTE#‰DC.W†TCBTVECTŒVECTOR�TABLE�POINTER‰DC.W†2“STARTING�BIT�NUMBER‰PAGEO********************************************************************************Í*F*ˆThis�is�a�secondary�vector�table�for�program�generated�exceptions.ƒ*?*ˆIt�is�required�to�support�the�68000,�because�the�68000�doesŠ*0*ˆnot�support�the�VOR�(vector�offset�register.™**Í*O*******************************************************************************  PROGINTƒEQU…*+BERR1…EQU…*ŠReferenced�by�M68010.AUTOVCT.SA8PROGINT2‚BSR.SƒPRGINTY„BUS�ERROR‡--�BIT�16�OF�EXMON�MASK/PROGINT3‚BSR.SƒPRGINTZZƒADDRESS�ERRORƒ--�BIT�170PROGINT4‚BSR.SƒPRGINTX„ILLEGAL�INSTRCT�--�BIT�18 ŠIFEQƒCHIPTYPE-68020;PROGINT5‚BSR.SƒSIX_TO_FOUR_WORD_FRAME„ZERO�DIVIDE…--�BIT�19?PROGINT6‚BSR.SƒSIX_TO_FOUR_WORD_FRAME„CHK�INSTRUCTION�--�BIT�20;PROGINT7‚BSR.SƒSIX_TO_FOUR_WORD_FRAME„TRAPV�INSTR…--�BIT�21ŠENDC ŠIFNEƒCHIPTYPE-68020ééé,PROGINT5‚BSR.SƒPRGINTX„ZERO�DIVIDE…--�BIT�190PROGINT6‚BSR.SƒPRGINTX„CHK�INSTRUCTION�--�BIT�20,PROGINT7‚BSR.SƒPRGINTX„TRAPV�INSTR…--�BIT�21ŠENDC /PROGINT8‚BSR.SƒPRGINTX„PRIV�VIOLATION‚--�BIT�22*PROGINTA‚BSR.SƒPRGINTX„LINE�1010‡--�BIT�23*PROGINTB‚BSR.SƒPRGINTX„LINE�1111‡--�BIT�24ŠNOPŠNOP&PROGINT9‚BSR.SƒPRGINT9„TRACE�INTERRUPTŠNOP PRGINTX: ŠBRA…PRGINTXC PRGINTZZ: ŠBRA…PRGINTZ  PRGINT9: ŠBRA…PRGINT9C ŠPAGEO********************************************************************************‰SIX_TO_FOUR_WORD_FRAME*=*‰This�logic�is�only�used�on�the�68020.‚Some�exceptions�which@*‰threw�four�words�on�the�stack�in�the�68000�and�68010�now�throw=*‰six�words�on�the�stack.‚Our�solution�(for�now)�is�to�simply>*‰discard�the�extra�information�given�by�the�68020�and�to�make,*‰the�new�stack�frame�look�like�the�old�one.* *‰PC�from�BSR*‰SR¤PC�from�BSR*‰PC¤SR*‰VOR’---------->†PC#*‰Instruction�addr–VOR�for�a�TRAP�1*>*‰All�the�exceptions�which�come�here�used�to�go�to�PRGINTX,�so%*‰that's�where�we�go�when�we're�done.*O******************************************************************************* SIX_TO_FOUR_WORD_FRAME: 4ŠMOVEƒ#$0084,$E(SP)†Make�the�VOR�look�like�a�TRAP�1.;ŠMOVEƒ$8(SP),$C(SP)†Move�the�top�10�bytes�of�the�stack�down>ŠMOVE.L�$4(SP),$8(SP)†4�bytes,�and�add�4�to�the�stack�pointer.ŠMOVE.L�(SP)+,(SP)‰* é  é)ŠBRA„PRGINTXC‹Now�go�where�we�used�to�go. ŠPAGEO********************************************************************************Í*)*…INTERRUPT�HANDLER�FOR�USER�INTERRUPTS£**Í*@*…ENTRY:ƒLOCATION�OF�SECONDARY�INTERRUPT�VECTOR�SAVED�ON�STACKŠ**Í**…EXIT�:ƒD7�=�PRGINT�NUMBER­**Í*6*�USES�REGISTERS�(ALL�USER�REGISTERS�SAVED�ON�STACK)š**Í*O*******************************************************************************‰PAGE**ˆHere�for�bus�error.*!*�if�(processor�=�68010)�then�do;&*’if�(exception�occurred�in�user�mode)&*’then�check�for�MMU�descriptor�fault;2*’make�stack�look�like�the�68000�long�stack�frame;*�end;**�if�(processor�=�68020)�then/*’if�this�is�a�short�bus�error�stack�frame�then4*—convert�a�68020�short�BE�frame�to�a�68000�BE�frame*’elseéééé4*—convert�a�68020�long‚BE�frame�to�a�68000�BE�frame.*)*ˆ(Note:‚If�the�MMUFAULT�module�detects�a*�segment�descriptor�error,'*�it�will�load�the�required�descriptor,*�and�return�to�the�user�code.*�It�will�not�RTS�here.)* PRGINTY:‰IFEQ†CHIPTYPE-68010+‰XDEF†BERR2�Referenced�by�M68010.AUTOVCT.SA9BERR2„ORˆ#$0700,SR‹Mask�interrupts�during�bus�error�proc.,‰BTST†#5,4(A7)ŒDid�error�occur�in�user�mode?‰IF‚‚THEN.S(‰TST.L…MMUHERE�Do�we�have�an�MMU�(68451)‰IF‚‚THEN.SŽIF�yes�THEN�...‰MOVE.L„A0,-(A7)‰MOVE.L„MMUHERE,A09‰BCLR†#7,$2D(A0)ŠDid�we�have�an�MMU�fault?�(And�clear�it)‰MOVE.L„(A7)+,A0‰IF‚‚THEN.SŽIF�yes�THEN�...(‰BSR‡MMUFAULTŒAttempt�MMU�fault�handling9‰MOVE.L„A0,-(A7)ŒIF�we�come�back�then�it�wasn't�seg�fault‰MOVE.L„MMUHERE,A0)‰BSET†#7,$2D(A0)ŠClear�the�MMU�fault�bit.‰MOVE.L„(A7)+,A0‰ENDI‰ENDI‰ENDI ‰IFNE†ALTINT,‰CLR_ALT_MODE’Clear�alternate�bus�error�mode1‰TEST_BUS_ERROR�If�valid�bus�or�parity�error�THEN‰IF��THEN.S(‰TST.L‚MMUHERE�Do�we�have�an�MMU�(68451)‰IF��THEN.S�IF�yes�THEN�...‰MOVE.L‚A0,-(A7)‰MOVE.L‚MMUHERE,A0$‰BCLR„#7,$2D(A0)ŒClear�MMU�fault�bit‰MOVE.L‚(A7)+,A0‰ENDI 7‰IF�ƒTHEN.SŽIF�we�did�not�have�an�MMU�fault�THEN...+‰ADDQ.L„#4,A7�Bypass�return�stuff�on�stack.‰RTE›Benign�bus�error.‰ENDI ‰ENDI 3‰CLR_BUS_ERROR‘Clear�associated�bits�in�module�stat‰ENDC *2*ˆMake�stack�look�like�the�68000�long�stack�frame.* ‰MOVE.W„#$0084,60(A7)‡VOR‰MOVE.L„6(A7),56(A7)ˆPC‰MOVE.W„4(A7),54(A7)ˆSR#‰MOVE.W„28(A7),52(A7)‡Inst�Register'‰MOVE.L„14(A7),48(A7)‡Address�attempted‰MOVE.W„12(A7),46(A7)‡Other)‰MOVE.L„(A7),42(A7)‰Pseudo�vector�address!‰LEA‡42(A7),A7‹Remove�extra�stuff‰ENDC *D*‚If�this�is�a�68020,�there�ar  e�two�types�of�bus�error�stack�frames.D*‚Whichever�this�is,�convert�it�to�the�equivalent�68000�stack�frame.*(ŠIFEQƒCHIPTYPE-68020…If�this�is�a�68020, ?ŠMOVEƒ6+4(SP),-(SP)†Isolate�the�format�code�of�the�stack�frame;1ŠAND„#VORFMT_MSK,(SP)ƒif�it�is�the�short�version,(ŠIF‚(SP)+��#VORFMT_SHORT_BERR�THEN.S *D*„Turn�a�68020�short�bus�error�stack�frame�into�a�68000�stack�frame.*"ŠMOVE„#$0084,$1E+4(SP)….�Move�VOR, ŠMOVE.L‚$2+4(SP),$1A+4(SP)ƒ.�PC,ŠMOVE„$0+4(SP),$18+4(SP)ƒ.�SR,<ŠMOVE†#$0000,$16+4(SP)ƒ.�Opcode�(there�isn't�one,�since�this)*§.�is�a�between-instructions�exception),-ŠMOVE.L�$10+4(SP),$12+4(SP)ƒ.�Errant�address,/ŠMOVE„$A+4(SP),$10+4(SP)ƒ.�Special�Status�Word,9ŠMOVE.L†(SP),$C+4(SP)„.�and�the�PC�pushed�by�BSR�PRGINTY. 8ŠLEA…$C+4(SP),SPŠ.�Now�point�SP�to�the�68000-like�frame. %ŠELSE.S”Else�(it's�the�long�version), *C*„Turn�a�68020�long�bus�error�stack�frame�into�a�68000�stack�frame.*#*§.�An�extra�4�bytes�on�stack�frame"ŠMOVE„#$0084,$5A+4(SP)†.�Move�VOR, ŠMOVE.L‚$2+4(SP),$56+4(SP)„.�PC,ŠMOVE„$0+4(SP),$54+4(SP)„.�SR,<ŠMOVE†#$0000,$52+4(SP)„.�Opcode�(we�can't�tell�for�sure�what'*§.�the�opcode�was,�due�to�pipelining),-ŠMOVE.L�$10+4(SP),$4E+4(SP)„.�Errant�address,/ŠMOVE„$A+4(SP),$4C+4(SP)„.�Special�Status�Word,:ŠMOVE.L†(SP),$48+4(SP)„.�and�the�PC�pushed�by�BSR�PRGINTY. 9ŠLEA…$48+4(SP),SPŠ.�Now�point�SP�to�the�68000-like�frame. ŠENDI ŠENDC 7* The stack now appears as it would if we were a 68000./*‰(A7)„Return�address�(from�BSR�PRGINTY)…(Long)%*‰4(A7)ƒR/W,�I/N�Function�code�(Word)'*‰6(A7)ƒAttempted�access�addressŽ(Long)$*‰$A(A7)‚Instruction�register’(Word)*‰$C(A7)‚Status�register—(Word)*‰$E(A7)‚Program�counter—(Long)‰PAGE  ***ˆDecode�the�status�register�on�the�stack,-*ˆto�determine�the�policy�for�this�bus�error.* *�if�(supervisor_bit�(sr)�=�set)*�then�go�to�super_be;#*�else�if�(interrupt_mask�(sr)�=�0)*�then�go�to�prgint_x0;*�else�go�to�prgint_ae;* 6‰BTST†#SRMODE,12(A7)†Was�bus�error�in�suprevisor�mode?‰BNE.S…SUPRBEŽBranch�if�yes. -‰TESTIM„12’Was�bus�error�in�normal�user�mode?‰BEQ‡PRGINTX0ŒBranch�if�yes. 1‰BRA‡PRGINTAEŒGo�to�handle�bus�error�in�user�ISR.‰PAGE*!*ˆThis�is�the�module�for�handling"*ˆbus�errors�from�supervisor�mode.* SUPRBE:<‰CMP.W…#'BE',18+VORLNGTH(A7)„EXEC�ROUTINE�ABLE�TO�HANDLE�IT?%‰BNE.S…CHECK_TRUST_TABLEˆBRANCH�IF�NO ‰MOVE.W„$C(A7),SR�Restore�SR.‰ADD.L…#20+VORLNGTH,A7ŠREMOVE�ERROR�FROM�STACK‰RTS RETURN�TO�ERROR�CODE‰PAGE*0*ˆThis�is�the�module�for�checking�for�bus�errors1*ˆor�address�errors�that�were�caused�by�executing-*ˆa�portion�of�trusted�code.‚(Trusted�code�is0*ˆcode�that�uses�some�parameter�that�a�real-time/*ˆtask�has�passed�to�the�exec,�without�checking0*ˆthat�parameter,�and�hence�the�name�"trusted".)*/*ˆThis�trust�table�represents�a�reversal�in�the.*ˆprevious�security�policy�of�RMS.‚Previously,1*ˆRMS�would�validate�all�parameters�before�taking/*ˆany�action.‚This�new�policy�says�to�trust�the4*ˆreal-time�tasks�to�give�us�the�correct�parameters,2*ˆand�to�perform�post-catastrophy�recovery,�if�the*ˆparameter�was�bad.*  *5*ˆThis�is�the�macro�for�defining�a�trust�table�entry.6*ˆIt�creates�an�entry�in�the�trust�table�consisting�of4*ˆa�longword�address�of�the�beginning�of�the�trusted3*ˆcode,�and�a�longword�address�of�the�ending�of�the4*ˆtrusted�code,�plus�six�bytes.‚(The�extra�six�bytes4*ˆaccounts�for�the�possible�six�byte�pre-fetch�queue*ˆon�the�68010.)* TT_ENTRY MACRO‰DC.L†\1 ‰DC.L†\2+6‰ENDM TT_BEGƒEQU‡0 TT_ENDƒEQU‡4 TT_LENƒEQU‡8  **ˆHere�is�the�trust�table.* TRUST_TABLE:‰TT_ENTRY‚TTB_01,TTE_01END_TRUST_TABLE:‰PAGE***ˆFinally,�here�is�the�code�to�support�the*ˆtrust�table�policy.* * *ˆtt_ptr�<==�addr�(trust_table);*ˆdo�while�(tt_ptr�<>�tt_end);*�tt_beg�<==�tt_ptr+;*�tt_end�<==�tt_ptr+;*�if"*�(fault_addr�(stack)�>=�tt_beg)�& *�(fault_addr�(stack)�<=�tt_  end)*�then�exit�(bad_target_task);*ˆend;*ˆcall�killer;*  CHECK_TRUST_TABLE:'‰MOVEM.LƒA0-A1/D0,-(A7)‹save�registers;6‰LEA‡TRUST_TABLE(PC),A0‡tt_ptr�<==�addr�(trust_table);‰LEA‡END_TRUST_TABLE(PC),A1:‰MOVE.L„4+4+4+$E(A7),D0Šfault_addr�<==�fault_addr�(stack); *¦do�while�(tt_ptr�<>�tt_end);TT_LOOP:‰CMP.L…TT_BEG(A0),D0Œif0‰BLO.S…TT_NEXT’(fault_addr�>=�tt_beg�(tt_ptr))�& 4‰CMP.L…TT_END(A0),D0Œ(fault_addr�<=�tt_end�(tt_ptr))‰BHI.S…TT_NEXT +‰EXIT†RTCDTASK‘then�exit�(bad_target_task); TT_NEXT:‰ADD.L…#TT_LEN,A0 ‰CMP.L…A0,A1‰BNE‡TT_LOOP�end; *‰MOVEM.Lƒ(A7)+,A0-A1/D0†restore�registers;‰BSR‡KILLERŽcall�killer;‰PAGE**ˆHere�for�an�address�error.**‰If�(processor�=�68010)�then9*Œconvert�68010�address�error�stack�frame�to�68000�frame.**‰If�(processor�=�68020)�then9*Œconvert�68020�address�error�stack�frame�to�68000�frame.* PRGINTZ:‰IFEQ†CHIPTYPE-68010‰MOVE.W„#$0084,60(A7)‡VOR‰MOVE.L„6(A7),56(A7)ˆPC‰MOVE.W„4(A7),54(A7)ˆSR#‰MOVE.W„28(A7),52(A7)‡Inst�Register'‰MOVE.L„14(A7),48(A7)‡Address�attempted‰MOVE.W„12(A7),46(A7)‡Other)‰MOVE.L„(A7),42(A7)‰Pseudo�vector�address!‰LEA‡42(A7),A7‹Remove�extra�stuff‰ENDC *H*‚If�this�is�a�68020,�turn�the�68020�address�error�stack�frame�(which�isK*‚the�same�as�a�68020�long�bus�error�stack�frame)�into�a�68000�stack�frame.*ŠIFEQƒCHIPTYPE-68020 ŠMOVE„#$0084,$5A+4(SP)…Move�VOR,ŠMOVE.L‚$2+4(SP),$56+4(SP)ƒPC,ŠMOVE„$0+4(SP),$54+4(SP)ƒSR,:ŠMOVE†#$0000,$52+4(SP)ƒOpcode�(we�can't�tell�for�sure�what%*§the�opcode�was,�due�to�pipelining),+ŠMOVE.L�$10+4(SP),$4E+4(SP)ƒErrant�address,-ŠMOVE„$A+4(SP),$4C+4(SP)ƒSpecial�Status�Word,8ŠMOVE.L†(SP),$48+4(SP)ƒand�the�PC�pushed�by�BSR�PRGINTZ. 7ŠLEA…$48+4(SP),SP‰Now�point�SP�to�the�68000-like�frame. ŠENDC  *"*ˆNow,�decode�the�sr�on�the�stack,&*ˆto�determine�the�appropriate�policy,"*ˆfor�handling�this�address�error.*0*�if�(adress�error�occurred�in�normal�user�mode)*�then�go�to�prgint_x0;'*�else�if�(supervisor_bit�(sr)�=�reset)*�then�go�to�prgint_ae;*�else�go�to�check_trust_table;*  ,‰TESTIM„12’Did�AE�occur�in�normal�user�mod�?‰BEQ.S…PRGINTX0ŒBranch�if�yes. 5‰BTST†#SRMODE,12(A7)†Did�AE�occur�in�supervisor�mode?5‰BEQ‡PRGINTAEŒBranch�if�yes.‚(Handle�AE�in�user�ISR.) 1‰BRA.S…CHECK_TRUST_TABLEƒGo�to�check_trust_table.‰PAGE**ˆHere�for�a�trace�interrupt.*ˆDecode�the�sr�on�the�stack,!*ˆto�determine�the�proper�policy,$*ˆfor�handling�this�trace�interrupt.**�if�(processor�=�68020)�then1*�convert�68020�trace�stack�frame�to�68000�frame.3*�if�(trace�interrupt�occurred�in�normal�user�mode)*�then�go�to�prgint_x0;7*�else�if�(trace�interrupt�occurred�in�supervisor�mode)*�then�go�to�super_trace;3*�else�ignore�this�trace�interrupt�from�a�user�ISR;  PRGINT9C: *D*‚First,�if�this�is�a�68020,�change�the�68020�trace�stack�frame�into*‚a�68000/68010�stack�frame.*(ŠIFEQƒCHIPTYPE-68020…If�this�is�a�68020, <ŠMOVEƒ#$0084,10+4(SP)„Put�down�a�TRAP�#1�VOR�so�that�when�we*§RTE�we'll�only�take�8�bytes.#ŠMOVE.L�2+4(SP),6+4(SP)„Move�the�PC*ŠMOVEƒ0+4(SP),4+4(SP)„and�SR�down�4�bytes.:ŠMOVE.L„(SP),4(SP)†Move�the�PC�pushed�by�the�BSR�PRGINT99. 6ŠADD.L„#4,SPŒMake�the�SP�point�to�the�new�stack�frame. ŠENDC *#*‚Decode�the�various�possibilities.*.‰TESTIM„4“Did�trace�occur�in�normal�user�mode?‰BEQ.S…PRGINTX0ŒBranch�if�yes. 7‰BTST†#SRMODE,4(A7)‡Did�trace�occur�in�supervisor�mode?‰BNE‡SUPRTRC�Branch�if�yes. 2‰ADD.L…#4,A7�Ignore�trace�interrupt�from�user�ISR..‰BCLR†#TRMODE,(A7)ˆClear�trace�mode�bit�in�sr.‰RTE›Return�to�user�ISR.‰PAGE* *ˆHere�for�all�other�exceptions.*ˆDecode�the�sr�on�the�stack,!*ˆto�determine�the�proper�policy,*ˆfor�this�exception.*-*�if�(exception�occurred�in�normal�user�mode)*�then�go�to�prgint_x0;**�else�if�(exception�occurred�in�user�ISR)*�then�go�to�prgint_ie;.*�else�(exception�occurred�in�supervisor  �mode)*�so�call�killer;*  PRGINTXC:2‰TESTIM„4“Did�exception�occur�in�normal�user�mode?‰BEQ.S…PRGINTX0ŒBranch�if�yes. 4‰BTST†#SRMODE,4(A7)‡Did�exception�occur�in�user�ISR?‰BEQ‡PRGINTIEŒBranch�if�yes. 4‰BSR‡KILLERŽCrash�system�on�exception�in�super�mode.‰PAGE*/*ˆHere�for�most�exceptions�in�normal�user�mode.*"*�save�the�state�of�the�user�task;*�if�(trace�exception�=�set)*�then�trace�this�exception;/*�get�a�pointer�to�the�program�exception�table;)*�and�go�to�the�generic�exception�module;*  **ˆSave�user's�state.* PRGINTX0:(‰SAVE_STATEƒEXCEPTIONˆSave�user's�state.  **ˆTrace�exception�if�required.* 4‰BTST†#TRCFEXCP,TRACFLAG‚Should�exception�be�traced.‰BEQ.S…PRGINTX1ŒBranch�if�no. ‰PUSH.W„SR’SAVE�SR�FOR�TRACE ‰BSR‡TRACER ‰DC.W†$AA11‰ADD.L…#2,A7�RESTORE�A7  */*ˆGet�a�pointer�to�the�program�exception�table,)*ˆand�go�to�the�generic�exception�module.* PRGINTX1:)‰LEA‡PRGITBL(PC),A5�POINTER�TO�PARAMETERS ‰BRA.S…UX  PRGITBL:*‰DC.L†PROGINT-30”PSEUDO-VECTOR�BASE�-�15*2$‰DC.W†TSKIEVCT–VECTOR-TYPE�ATTRIBUTE#‰DC.W†TCBEVECT–VECTOR�TABLE�POINTER‰DC.W†16œSTARTING�BIT�NUMBER‰PAGE*"*ˆTake�action�for�user�exceptions.*‰SECTION�LEVEL00  ‰XREF.S„MACSTRC‰XREF.S„RUNNER ‰XREF.S„TIAT ‰XREF†EQDQ  *'*ˆThis�is�the�generic�exception�module.&*ˆIt�handles�most�exceptions�and�traps$*ˆthat�occurred�in�normal�user�mode.*  **ˆCompute�exception�number.* UX:#‰POP.L…D7’PC�SAVED�BY�PSEUDO-VECTOR)‰SUB.L…(A5),D7�PSEUDO-VECTOR�DISPLACEMENT"‰LSR.L…#1,D7�EXMON�MASK�BIT�NUMBER  **ˆIs�it�a�trace�exception?* ‰CMP.B…#24,D7ŽL1111�BIT�NUMBER‰BGT‡PRGINTT�BRANCH�IF�TRACE  **ˆDoes�user�have�vector�table?* )‰MOVE.W„4(A5),D1ŒGET�ATTRIBUTE�BIT�NUMBER%‰MOVE.W„TCBATTR(A6),D2†GET�ATTRIBUTES(‰BTST†D1,D2�USER�HAVE�THIS�VECTOR�TABLE?‰BEQ.S…UX5‘BRANCH�IF�NO  **ˆUser�has�vector�table.*ˆHas�he�claimed�this�vector?* 0‰MOVE.W„6(A5),D1ŒVECTOR�POINTER�TCB�DISPLACEMENT0‰MOVE.L„0(A6,D1),D6‰VECTOR�TABLE�LOGICAL�ADDRESS‰MOVE.L„D7,D1�VECTOR�NUMBER3‰SUB.W…8(A5),D1ŒMINUS�STARTING�NUMBER�FOR�THIS�TYPE‰LSL.L…#2,D1�TIMES�4,‰ADD.L…D1,D6�SPECIFIC�VECTOR�LOGICAL�ADDRESS‰TR0.LOGPHY‚,,#4!‰BRA.S…UX1‘BRANCH�IF�GOOD�ADDRESS ‰NOP›NO�GOOD‰BRA.S™UX5�IGNORE�BAD�VECTOR  **ˆUser�has�claimed�this�vector.*ˆIs�vector�present?* UX1:%‰MOVE.L„D6,A1�VECTOR�PHYSICAL�ADDRESS‰TST.L„(A1)‘IS�VECTOR�PRESENT? ‰BEQ.S„UX5’BRANCH�IF�NOT�PRESENT  **ˆUser�has�claimed�this�vector,*ˆand�vector�is�present.'*ˆMove�exception�frame�to�user's�stack.* %‰MOVE.L„EXCSTACK,D5‰TOP�OF�EXEC�STACK5‰SUB.L…#2+4,D5�Adjust�for�A6�and�VOR�(or�pseudo�VOR).)‰SUB.L…A7,D5�MINUS�CURRENT�STACK�=�LENGTH‰MOVE.L„USP,A0 ‰MOVE.L„A0,D6�USER�STACK�POINTER+‰SUB.L…D5,D6�MINUS�LENGTH�=�START�OF�WINDOW‰TR0.LOGPHY‚"‰BRA.S…UX3‘BRANCH�IF�USER�STACK�OK ‰NOP›NO�GOOD‰BRA.S™UX5�IGNORE�BAD�STACK  **ˆEnough�room�on�user's�stack.*ˆNow,�update�USP,*ˆand�prepare�for�move.* UX3:*‰MOVE.L„D6,A4�PHYSICAL�STACK�START�ADDRESS‰MOVE.L„D3,A0�SAVE�NEW�USP‰MOVE.L„A0,USP%‰MOVE.L„EXCSTACK,D3‰Top�of�exec�stack*‰SUB‡#2,D3�Adjust�for�VOR�(or�pseudo�VOR).  *!*ˆMove�the�exception�stack�frame.* ‰POP.L…A0’Save�user's�A6. UX4:2‰MOVE.W„(A7)+,(A4)+‰MOVE�SUPER�STACK�TO�USER�STACK‰CMP.L…D3,A7�END�OF�STACK?!‰BNE.S…UX4‘BRANCH�IF�MORE�TO�MOVE  **ˆException�frame�moved.A*ˆSet�the�stack�up�to�cause�us�to�return�to�the�exception�handler%*ˆaddress,�and�go�to�check�for�EXMON.* 2‰PUSH.L„(A1)�Push�the�PC�of�his�exception�handler,.‰PUSH.W„-6(A4)‹and�his�SR�onto�the�exec�stack. 0‰PUSH.L„A0�Put�back�his�A6�like�we�had�on�entry.(‰MOVE.W„#1,D6�FLAG--USER�HAS�OWN�ROUTINE‰BRA.S…UX6‘GO�TO�EXMON�TEST  *'*ˆCheck�for�bus�error�or�address�error.* UX5:/‰CLR.L…D6’FLAG--USER�NOT�HANDLING�OW  N�EXCEPTION‰CMP.B…#16,D7ŽBUS�ERROR�NUMBER?‰BLT.S…UX6‘BRANCH�IF�NEITHER #‰CMP.B…#17,D7ŽADDRESS�ERROR�NUMBER?‰BGT.S…UX6‘BRANCH�IF�NEITHER ‰POP.L…A0’Temporary�save�A6/‰POP.L…TCBBERR(A6)‰Save�Bus�error/Address�error!‰POP.L…TCBBERR+4(A6)‡Info.�in�TCB‰PUSH.L„A0’Restore�A6  *$*ˆShould�we�send�a�message�to�EXMON.* UX6:0‰BTST†#TSKIEXM,TCBATTI(A6)ŠDOES�TASK�HAVE�EXMON?‰BEQ.S…UX7›BRANCH�IF�NO &‰MOVE.L„TCBEMMSK(A6),D1�GET�EXMON�MASK(‰BTST†D7,D1™IS�THIS�EXCEPTION�MONITORED?‰BEQ.S…UX7›BRANCH�IF�NO **ˆSend�a�message�to�EXMON, *ˆand�EXIT.* "‰BSR‡CKEXMON—GO�SEND�EXMON�MESSAGE)‰CMP.B…#15,D7˜IS�THIS�A�TRAP�INSTRUCTION?‰EXIT.GTƒEXCEPT˜BRANCH�IF�NO  *"*ˆLook�for�type�2�trap�assignment.* UX7: ‰TST.B…D6’USER�HANDLING�HIMSELF?!‰EXIT.NEƒEXCEPTŽBRANCH�OUT�IF�YES )‰CMP.B…#15,D7ŽIS�THIS�A�TRAP�INSTRUCTION?‰BGT.S…UXDF�BRANCH�IF�NO .‰LEA‡TIAT,A1�TRAP�INSTRUCTION�ASSIGNMENT�TABLE/‰CMP.B…#2,0(A1,D7)‰2�MEANS�SERVER�HAS�THIS�TRAP$‰EXIT.NEƒTRAPERR�EXIT�TRAPPING�ERROR  **ˆGo�to�EQGQ�on�way�to�server.* #‰BSR‡EQDQ�Send�a�message�to�server.2‰EXIT†TERM�Exit,�leaving�this�task�off�ready�list.  ‰PAGE*)*ˆTake�default�action�for�user�exception.* UXDF:‰TST.W…D6’IS�USER�HANDLING�IT?‰EXIT.NEƒEXCEPTŽBRANCH�IF�YES (‰TR0.EXABRT�(A6)�ABORT�TASK�--�NO�RETURN‰PAGE*)*ˆThis�is�the�module�to�handle�exceptions8*ˆwhich�occurred�within�user�interrupt�service�routines.*ˆIt�has�three�entry�points:*2*�1.)‚PRGINTTE�-�for�trap�exceptions�in�user�ISRs,8*�2.)‚PRGINTAE�-�for�bus�or�address�errors�in�user�ISRs,7*�3.)‚PRGINTIT�-�for�all�other�exceptions�in�user�ISRs.* PRGINTTE:.‰POP.L…D0•D0�<--�2�*�TRAP�#�which�was�executed7‰PEA‡TRAPVCT+2(PC)ŠPC�stacked�by�the�BSR�in�the�TRAPVCT2‰SUB.L…(A7)+,D0�table,�minus�2�to�point�to�the�BSR#*«instruction,�minus�the�address�of*«the�beginning�of�the�table.‰BRA‡ISRERRˆGO�TO�ERROR�ROUTINE    *%*ˆBus�error�or�address�error�occurred$*ˆin�user�interrupt�service�routine.* PRGINTAE:‰POP.L…D0’ADDR�OF�PSEUDO�VECTOR‰ADD.L…#8,A7�SKIP�EXTRA�INFO‰BRA.S…PRGINTI1    *,*ˆOther�exception�(not�bus�or�address�error)-*ˆoccurred�in�user�interrupt�service�routine.* PRGINTIE:‰POP.L…D0’ADDR�OF�PSEUDO�VECTOR  PRGINTI1:)‰SUB.L…#PROGINT-30,D0†GET�(EXCEPTION�#)*2 ˆBRA‡ISRERR‰PAGE**ˆThis�is�the�module"*ˆfor�processing�trace�exceptions,*ˆfrom�normal�user�mode�code.* PRGINTT:2‰MOVE.L„#TEMTRAC,D7‰PUT�'TRACE�1�INSTR'�CODE�IN�D7%‰MOVE.L„TCBEMMSK(A6),D2…GET�XMON�MASK/‰BTST†#TEMVCHG,D2‰VALUE�CHANGE�TRACE�REQUESTED?‰BNE.S…PRGINTT1ŒBRANCH�IF�YES '‰BTST†#TEMTRAC,D2‰TRACE�1�INSTRUCTION�?‰BNE.S…PRGINTT9ŒBRANCH�IF�YES !‰BTST†#TEMMCNT,D2‰MAX�COUNT�SET�?‰BNE.S…PRGINTT6ŒBRANCH�IF�YES /‰MOVEM.LƒTCBD0(A6),D0-D7/A0-A5‰RELOAD�REGISTERS ‰POP.L…A6)‰BRA‡GMACSBUG–GO�TO�MACSBUG�TRACE�ROUTINE‰PAGE*/*ˆValue�change,�or�value�equal�trace�requested.* PRGINTT1:*‰TR0.LOGPHY‚,TCBEVLOC(A6),#4‰BRA.S…PRGINTT2ŒBRANCH�IF�FOUND ‰NOP-‰BRA.S…PRGINTT5ŒBAD�ADDR�-�TREAT�AS�NO�CHANGE  PRGINTT2:2‰MOVE.L„#TEMVCHG,D7‰MOVE�'VALUE�CHANGE'�CODE�TO�D7*‰MOVE.L„D6,A0�PHYSICAL�ADDR�OF�VALUE�IN�A0#‰MOVE.L„(A0),D3�CURRENT�VALUE�TO�D3,‰MOVE.L„TCBEVALU(A6),D4…EXPECTED�VALUE�TO�D4$‰EOR.L…D3,D4�CLEAR�ALL�MATCHING�BITS#‰BTST†#TEMVEQU,D2‰IS�THIS�V=�TRACE?‰BNE.S…PRGINTT3ŒBRANCH�IF�YES‰PAGE**ˆValue�change�trace�requested.* )‰AND.L…TCBEVMSK(A6),D4…HAS�VALUE�CHANGED?‰BEQ.S…PRGINTT5ŒBRANCH�IF�NO *‰MOVE.L„D3,TCBEVALU(A6)…SAVE�CHANGED�VALUE(‰BRA.S…PRGINTT9ŒGO�SEND�MESSAGE�TO�EXMON  **ˆValue�equal�trace�requested.* PRGINTT3:)‰ADD.L…#1,D7�PUT�'VALUE�EQUAL'�CODE�IN�D73‰AND.L…TCBEVMSK(A6),D4…IS�CURR�VALUE�=�TO�EXPECTED?‰BEQ.S…PRGINTT9ŒBRANCH�IF�YES  *"*ˆCheck�maximum�instruction�count.* PRGINTT5:&‰BTST†#TEMMCNT,D2‰WAS�MAX�COUNT�GIVEN?‰EXIT.EQƒE  XCEPTŽBRANCH�IF�NO‰PAGE*$*ˆMaximum�instruction�count�was�set.* PRGINTT6:1‰ADD.W…#1,TCBECNT(A6)†ADD�1�TO�UPPER�1/2�OF�COUNT+‰MOVE.L„TCBECNT(A6),D0†MOVE�LOWER�1/2�TO�D0%‰CMP.W…TCBECNT(A6),D0†#�INSTR�=�MAX�?#‰EXIT.HIƒEXCEPTŽBRANCH�IF�NOT�EQUAL /‰MOVE.L„#TEMMCNT,D7‰PUT�'�MAX�COUNT'�CODE�IN�D7  **ˆSend�message�to�EXMON.* PRGINTT9:.‰BSR.S…CKEXMON�BRANCH�TO�EXMON�MESSAGE�ROUTINE ‰EXIT†EXCEPT‰PAGE*!*ˆThis�is�the�module�for�handling(*ˆtrace�exceptions�from�supervisor�mode.* SUPRTRC: ‰MOVE.L„D1,(A7)’SAVE�D1�ON�STACK‰PUSH.L„A6—SAVE�A6�ON�STACK)‰MOVE.L„RUNNER,A6�GET�TCB�OF�RUNNING�TASK‰CMP.L…#0,A6”DOES�TASK�EXIST?'‰BEQ.S…SUPRTR4’BRANCH�IF�NO�-�NOT�EXMON B‰BTST†#SRMODE,4+4+SR_LEN+PC_LEN+VORLNGTH(A7)�2ND�RTN�IN�USER�MODE?'‰BNE.S…SUPRTR4’BRANCH�IF�NO�-�NOT�EXMON 6‰BTST†#TSKIEXM,TCBATTI(A6)…IS�TASK�CONNECTED�TO�EXMON?'‰BEQ.S…SUPRTR4’BRANCH�IF�NO�-�NOT�EXMON -‰MOVE.B„TCBEMMSK(A6),D1ŠLOOK�AT�EXMON�OPTIONS‰AND.B…#$38,D1’WAS�TRACE�SET?'‰BEQ.S…SUPRTR4’BRANCH�IF�NO�-�NOT�EXMON -‰BSET†#TRMODE,TCBEMMSK(A6)…REMEMBER�TRACE�BIT‰POP.L…A6—RESTORE�A6‰POP.L…D1—RESTORE�D18‰BCLR†#TRMODE,SR_LEN+PC_LEN+VORLNGTH(A7)ˆCLEAR�TRACE�BIT!‰STˆPREEMPT_FLAG�FORCE�A�PREEMPT.&‰RTE RETURN�-�EXMON�IGNORES�SUPR�TRACE  *"*ˆTrace�bit�on�in�supervisor�mode,**ˆand�EXMON�not�monitoring�this�condition.* SUPRTR4:‰POP.L…A6’RESTORE�A6‰POP.L…D1’RESTORE�D1  GMACSBUG:&‰PUSH.L„MACSTRC�SET�UP�MACSBUG�ADDRESS‰RTS›EXIT�TO�BUG‰PAGE*&*ˆSubroutine�to�send�message�to�EXMON,.*ˆand�to�put�running�task�into�the�WAIT�state.*  CKEXMON:%‰BSR‡SVXSTAK�SAVE�STACK�AND�REGISTERS  **ˆSend�message�to�EXMON.* CKEXMSG:-‰MOVE.L„#$0C080000,D2‡MESSAGE�LENGTH�AND�TYPE,‰MOVE.W„TCBNAME(A6),D2†1ST�HALF�OF�TASK�NAME@‰MOVE.L„TCBNAME+2(A6),D3„2ND�HALF�OF�TASK�NAME,1ST�HALF�OF�SESSN-‰MOVE.L„TCBSESSN+2(A6),D4ƒ2ND�HALF�OF�SESSION‰MOVE.W„D7,D4�TYPE�OF�INTERRUPT ‰LSL.W…#8,D4�MOVE�IT�TO�2ND�BYTE.‰MOVE.B„#3,D4�3=MESSAGE�IS�RESULT�OF�INTERRUPT '‰TR0.QEVNTN‚TCBEXM(A6)ˆSEND�THE�MESSAGE&‰BRA.S…CKEXWAITŒBRANCH�IF�MESSAGE�SENT  **ˆERROR�-�message�not�sent.* 1‰BCLR†#TSKIEXM,TCBATTI(A6)ŠDETACH�TASK�FROM�EXMON3‰MOVEM.LƒTCBXREGS(A6),D0-D7/A0-A6†RESTORE�REGISTERS8‰BCLR†#TSK2RTEX,TCBSTAT2(A6)ˆCLEAR�'RETURN�TO�EXEC'�FLAG'‰MOVE.B„D0,TCBRPRI(A6)�RESTORE�PRIORITY ‰RTS¥RETURN.‰PAGE**ˆPlace�task�into�the*ˆ'waiting�for�command'�state.* CKEXWAIT:;‰BSET†#TSKSWTEM,TCBSTATE(A6)ˆSet�the�'wait�for�command'�bit+‰ADD.L…#4,SP™Pop�subroutine�return�address, "‰EXIT†DISPATCH–and�go�to�dispatch;   ‰ENDééééé  é**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.ENV.EQ*ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.ASQ.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ˆINCLUDEƒ9995.&.UTILITY.MC*‰NOLIST‰INCLUDEƒ9995.&.ENV.EQ‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.ASQ.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.INTERRUP.MC‰INCLUDEƒ9995.&.UTILITY.MC‰LIST‰PAGE‰IFEQ‚CHIPTYPE-68000EXIT…IDNT‚5,1„68000�EXIT�MODULE‰ENDC‰IFEQ‚CHIPTYPE-68010EXIT…IDNT‚5,1„68010�EXIT�MODULE‰ENDC‰SECTIONƒLEVEL00 ‰XREF†BKG_DISPATCH‰XREF†DISPATCH‰XREF†L1_D0_SAVE ‰XREF†PREEMPT ‰XREF.S„EXCSTACK‰XREF.S„RUNNER‰XREF.S„PERTURB_FLAGS‰XREF.S„PREEMPT_FLAG‰PAGE‰XDEF†EXIT_D0SUB7‰XDEF†EXIT_SUBŒExit�for�subroutine�class�of�directives.4‰XDEF†EXIT_EXCEPT‰Exit�for�exception�handler�module.)*¦Exits�for�postempt�class�of�directives.-‰XDEF†EXIT_POST�temporary�postempt�directive;-‰XDEF†EXIT_TERM�permanent�postempt�directive; &*¦Exits�for�preempting�a�running�task,*¦to�go�to�his�own�asr:$‰XDEF†EXIT_ASR‘clear�D0�&�go�to�asr;-‰XDEF†EXIT_D0ASR�get�D0�from�tcb�&�go�to�asr;*«(used�by�rtevent); ,‰XDEF†EXIT_TRAPERRˆExit�for�trapping�errors.4‰XDEF†EXIT_ERRŒExit�for�error�case,�when�D0�contains&*§error�number.‚(Special�case�for�CMR.%*§because�drivers�return�error�number *§in�D0)�.) 4‰XDEF†ERROR_01ŒExit�for�error�with�return�code�=�01.4‰XDEF†ERROR_02ŒExit�for�error�with�return�code�=�02.4‰XDEF†ERROR_03ŒExit�for�error�with�return�code�=�03.4‰XDEF†ERROR_04ŒExit�for�error�with�return�code�=�04.4‰XDEF†ERROR_05ŒExit�for�error�with�return�code�=�05.4‰XDEF†ERROR_06ŒExit�for�error�with�return�code�=�06.4‰XDEF†ERROR_07ŒExit�for�error�with�return�code�=�07.4‰XDEF†ERROR_08ŒExit�for�error�with�return�code�=�08.4‰XDEF†ERROR_09ŒExit�for�error�with�return�code�=�09.4‰XDEF†ERROR_10ŒExit�for�error�with�return�code�=�10.4‰XDEF†ERROR_11ŒExit�for�error�with�return�code�=�11.™G¢CªD²Fºu 4‰XDEF†ERROR_12ŒExit�for�error�with�return�code�=�12.4‰XDEF†ERROR_13ŒExit�for�error�with�return�code�=�13.4‰XDEF†ERROR_14ŒExit�for�error�with�return�code�=�14.4‰XDEF†ERROR_15ŒExit�for�error�with�return�code�=�15.4‰XDEF†ERROR_16ŒExit�for�error�with�return�code�=�16.‰PAGE***ˆThis�is�the�exit�routine�for�the�typical+*ˆsubroutine�call�to�the�exec.‚A�subroutine,*ˆcall�to�the�exec�is�a�call�which�just�asks(*ˆthe�exec�to�do�something�for�the�task,+*ˆand�expects�the�exec�to�return�control�to *ˆthe�task.*(*ˆThere�are,�however,�certain�conditions(*ˆwhich�might�occur�within�the�exec�that'*ˆcould�perturb�this�natural�subroutine*ˆentry/exit�mechanism.*&*ˆSpecifically,�a�higher�priority�task*ˆcould�have�been�made�ready,!*ˆeither�by�the�trap�#1�directive*ˆrequested�by�the�client�task,%*ˆor�by�a�trap�#0�directive�requested"*ˆby�an�interrupt�service�routine. *ˆThis�class�of�perturbations�is&*ˆcalled�a�preempt,�is�detected�by�the#*ˆready�module,�and�is�signalled�by*ˆsetting�the�preempt_flag.*#*ˆAnother�class�of�perturbations�is*ˆthe�background�perturbation.%*ˆIt�is�caused�by�a�interrupt�service *ˆroutine�requesting�the�exec�to*ˆschedule�a�background�job,�is%*ˆdetected�by�the�schedule�background%*ˆmodule,�and�is�signalled�by�setting*ˆthe�bkg_flag.*$*ˆCollectively,�the�two�perturbation$*ˆflags�(blg_flag,�preempt_flag)�are"*ˆrefered�to�as�the�perturb_flags. *ˆThey�are�located�in�the�system(*ˆparameter�area�(SYSPAR),�and�organized%*ˆas�two�consecutive�b  ytes�in�memory,+*ˆsuitable�for�access�as�one�word�variable.)*ˆThe�bkg_flag�is�in�the�high�order�byte,)*ˆso�as�to�allow�the�TST.W�instruction�to *ˆdetermine:*'*�1.)‚at�least�one�of�the�perturb_flags*’are�set�(CC�=�NE);*$*�2.)‚the�bkg_flag�is�set�(CC�=�MI);*‰PAGE EXIT_EXCEPT: EXIT_D0SUB: ‰MOVE.L„TCBD0(A6),D0ˆRestore�D0,%‰BRA.S…EXIT_TEST‹and�go�to�EXIT_TEST.  EXIT_SUB:2‰MOVEQ.Lƒ#0,D0�Set�D0�<==�0,�to�indicate�no_error.  EXIT_TEST:4‰DISABLE_INTERRUPTSŒfreeze�(perturbation�detectors);5‰TST.W…PERTURB_FLAGS‡if�either�perturbation�occurred,*‰BNE.S…GOT_PERTURB‰then�go�to�got_perturb;  EXIT_RTE:-‰MOVEM.LƒTCBD1(A6),D1-D7/A0-A5‰else�perform�a"‰POP.L…A6œlevel_1�partial�restore,‰RTE¥and�return�to�the�task;‰PAGE*+*ˆThis�is�where�we�decode�the�perturbation,%*ˆand�perform�the�appropriate�action,'*ˆaccording�to�the�following�algorithm:**#*�release�(perturbation�detectors);*�if�(bkg_flag�=�set)�then�do;!*’call�dispatch_background_work);2*’go�to�exit_10;Œ/*�try�again�to�return�to�user�*/*�end; *�else�do;*’perform�a�level_1�full�save;*’go�to�re_dispatch;*�end;*  GOT_PERTURB: '‰BPL.L…L1_D0_SAVEŠif�(bkg_flag�=�reset)*§then�go�to�l1_d0_save; *§else�do;2‰BSR.L…BKG_DISPATCH�call�dispatch�background�work;-‰TST.B…PREEMPT_FLAG�if�(preempt_flag�=�reset))‰BEQ.S…EXIT_RTE‘then�return�to�user�code;3‰BRA.L…L1_D0_SAVE�else�save�the�state�of�this�task,*°and�do�a�dispatch;‰PAGE*"*ˆHere�is�the�exit�routine�for�the*ˆpostempt�class�of�directives."*ˆA�postempt�directive�is�one�that"*ˆtypically�will�take�the�task�out*ˆof�execution.‚Therefore,�the$*ˆpostempt�exit�routine�will�perform$*ˆa�level_1�full�save,�and�go�to�the"*ˆdispatcher.‚(Note�that�since�the!*ˆrunning�task�is�already�off�the$*ˆready�list,�this�exit�routine�will *ˆleave�him�off�the�ready�list.)*$*ˆNow,�if�a�postempt�class�directive**ˆdetects�an�error�that�will�not�allow�the)*ˆexec�to�take�the�task�out�of�execution,'*ˆit�must�inform�the�task�of�the�error,#*ˆand�return�control�to�it.‚This�is%*ˆhandled�by�the�error�exit�routines.*+*ˆOne�last�point.‚There�are�two�sub-classes(*ˆwithin�the�postempt�class;�a�temporary-*ˆpostempt�subclass,�and�a�permenent�postempt+*ˆsubclass.‚The�temporary�subclass�consists0*ˆof�those�directives�such�as�delay,�wait,�etc.,0*ˆwhich�expect�to�be�brought�back�into�execution)*ˆby�the�exec�at�some�later�time;‚whereas.*ˆthe�permenent�subclass�consists�of�those�two/*ˆdirectives,�term,�abort,�which�cause�the�task.*ˆto�be�permenently�prohibited�from�executing..*ˆSince�the�temporary�subclass�will�eventually1*ˆexecute,�we�must�save�a�D0�of�zero,�to�indicate3*ˆto�the�task�that�the�temporary�postempt�directive2*ˆdid�indeed�execute�properly;‚whereas�in�the�case1*ˆof�the�permenent�postempt�directive,�we�wish�to0*ˆpreserve�the�initial�state�of�D0,�for�possible*ˆpost-processing�prognosis.*‰PAGE EXIT_POST: EXIT_ASR:/‰CLR.L…TCBD0(A6)‹D0�<==�0�to�indicate�no_error;  EXIT_TERM: EXIT_D0ASR:5‰SAVE_STATE‚L1_FULL‹save�the�full�state�of�this�task,#‰BRA.L…DISPATCHŒand�go�to�dispatch;‰PAGE* *ˆHere�are�the�two�exit�routines"*ˆfor�preempting�the�running�task,*ˆto�go�to�his�ASR.**ˆExit_asr�is�the�normal�case.!*ˆIt�is�used�when�a�task�executes#*ˆsome�directive�call�which�results *ˆin�the�task�getting�dispatched$*ˆto�it's�ASR�(ex.�wtevent,�setasq)."*ˆSince�the�directive�call�worked, *ˆtherefore,�we�need�to�clear�D0&*ˆwithin�the�tcb�to�indicate�no�error,&*ˆbefore�sending�the�task�to�it's�ASR.&*ˆTherefore,�upon�return�from�the�ASR,'*ˆthe�instruction�immediately�after�the"*ˆoriginal�directive�call�will�see#*ˆD0�=�0,�indicating�a�good�status.*(*ˆNow,�exit_d0_asr�is�the�abnormal�case.+*ˆIt�occurs�when�a�task�executes�a�rtevent,&*ˆwith�the�enable_asr�option�selected,(*ˆand�there�is�an�event�within�it's�ASQ.&*ˆIn�this�case�we�must�not�perturb�the#*ˆvalue�of�D0�within�the�tcb,�asdwe$*ˆmust�save�the�previous�value�of�D0**ˆ for�the�eventual�return�to�non-ASR�code.*‰PAGE*%*ˆThese�are�the�various�exit�routines%*ˆfor�the�different�error�conditions."*ˆThey�just�set�D0�<==�error�code,'*ˆand�jump�to�the�generic�error�handler2*ˆwhich�will�set�the�condition�codes�on�the�stack,(*ˆand�format�D0�for�the�exec�error�code.*ˆ(i.e.,�D0�<==�$08DDEEEE;*�where:*’$08ƒ:=�code�for�exec�error;*’$DDƒ:=�directive�number;*’$EEEE�:=�specific�error�code;*ˆ)*  ERROR_01:‰MOVEQ.Lƒ#01,D0‰BRA.S…ERROR_XX  ERROR_02:‰MOVEQ.Lƒ#02,D0‰BRA.S…ERROR_XX  ERROR_03:‰MOVEQ.Lƒ#03,D0‰BRA.S…ERROR_XX  ERROR_04:‰MOVEQ.Lƒ#04,D0‰BRA.S…ERROR_XX  ERROR_05:‰MOVEQ.Lƒ#05,D0‰BRA.S…ERROR_XX  ERROR_06:‰MOVEQ.Lƒ#06,D0‰BRA.S…ERROR_XX  ERROR_07:‰MOVEQ.Lƒ#07,D0‰BRA.S…ERROR_XX  ERROR_08:‰MOVEQ.Lƒ#08,D0‰BRA.S…ERROR_XX  ERROR_09:‰MOVEQ.Lƒ#09,D0‰BRA.S…ERROR_XX  ERROR_10:‰MOVEQ.Lƒ#10,D0‰BRA.S…ERROR_XX  ERROR_11:‰MOVEQ.Lƒ#11,D0‰BRA.S…ERROR_XX  ERROR_12:‰MOVEQ.Lƒ#12,D0‰BRA.S…ERROR_XX  ERROR_13:‰MOVEQ.Lƒ#13,D0‰BRA.S…ERROR_XX  ERROR_14:‰MOVEQ.Lƒ#14,D0‰BRA.S…ERROR_XX  ERROR_15:‰MOVEQ.Lƒ#15,D0‰BRA.S…ERROR_XX  ERROR_16:‰MOVEQ.Lƒ#16,D0‰BRA.S…ERROR_XX ‰PAGE*$*ˆThis�is�the�generic�error�handler..*ˆ(It�is�also�the�error�handler�for�CMR�errors%*ˆwhich�return�the�error�code�in�D0.)*#*ˆIt�resets�the�super�stack�pointer**ˆto�the�beginning�of�the�RTE�stack�frame.)*ˆ(In�case�we�jumped�here�from�some�other)*ˆlevel�on�the�stack.‚i.e.,�from�a�nested(*ˆsubroutine.)‚Then�we�set�the�condition(*ˆcodes�on�the�super�stack�to�not_equal.**ˆFinally,�we�format�the�error�code�in�D0,*ˆand�go�to�EXIT_TEST.*3*ˆA�special�trap�error�handler�entry,�EXIT_TRAPERR,/*ˆis�added�here�to�set�the�return�code�and�trap,*ˆnumber,�and�reset�the�super�stack�pointer.* EXIT_TRAPERR:%‰MOVE.W„D0,TCBD0(A6)ˆDIRECTIVE�NUMBER)‰MOVE.W„#RTCDDIRN,TCBD0+2(A6)‚RETURN�CODE)‰LSL.L…#3,D7�SHIFT�TRAP�NUMBER�TO�GO�INTO‰MOVE.B„D7,TCBD0(A6)ˆBITS�27-30&‰BRA.S…EXIT_UNSTACKˆPOP�STACK�AND�EXIT  ERROR_XX: EXIT_ERR: ‰SWAP†D0’SET�UP�D0:‰MOVE.W„#$0800,D0�$8000EEEE;!‰MOVE.B„TCBD0+3(A6),D0‹$80DDEEEE;‰SWAP†D0’WHERE:*«$80ƒ:=�code�for�exec�error;*«$DDƒ:=�directive�number;*«$EEEE�:=�error�code; EXIT_UNSTACK:4‰MOVE.L„EXCSTACK,A0‰Get�a�pointer�to�the�exec�stack.)‰SUB.L…#2+4+2,A0‹Skip�over�the�RTE�frame.‰SUB.L…#4,A0�Skip�over�A6.-‰MOVE.L„A0,A7�Update�the�super�stack�pointer. <‰MOVE.B„#NE_CC,4+COND_CODE(A7)ƒForce�the�condition�code�byte*«within�the�RTE�frame�to�.  ‰BRA‡EXIT_TEST‰ENDééééé éé=/*=/*†M68XXX.EXMMSK.AF=/*+=/* Chain file to assemble M68XXX.EXMMSK.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.EXMMSK.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXMMSK.LS=/ENDIF=/*1=ASM M68XXX.EXMMSK.SA,M68XXX.EXMMSK.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDééééééÊ 'M68XXX EXMMSK SAßß8qqEXMON AFèèqqEXMON SAññ ˆqqEXMONVR AFqqEXMONVR SA  5qqEXQEVENTAFqqEXQEVENTSA1ZqqEXRQPA AFVVqqEXRQPA SA__+¤qqFNDGSEG AF��qqFNDGSEG SA™™ ‘qqFNDTSEG AFªªqqFNDTSEG SA³³MqqFNDUSEM AF¼¼qqFNDUSEM SAÅÅ ¨qqGETTCB AFÖÖqqGETTCB SAßß¿qqGTDTIM AFøøqqGTDTIM SA>qqGTTASKIDAF  qq‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE;EXMMSK‚IDNT‚5,1�68xxx�DIRECTIVE- -SET�EXCEPTION�MONITOR�MASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*******************,*‡*‚E�X�M�M�S�K„*ƒSET�EXCEPTION�MONITOR�MASK*‡*‚REV�1.00ƒHLD6**‡*‚08/06/79‡**‡**********************‹ENTRY:�A6�HAS�ADDR�OF�TCB*—0�-�TASK�NAME�OF�TARGET�TASK*—4�-�SESSION�CODE *—8�-�MASK*’A5�HAS�TARGET�TCB�ADDRESS**‹EXIT�:�D0�HAS�RETURN�CODE*’D0�=�0„GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST***‰SECTION�LEVEL04* ‰XDEF„EXMMSK‰PAGE**ˆSet�exception�monitor�mask.* EXMMSK:1‰MOVE.B„TCBEMMSK(A5),D0…SAVE�1ST�BYTE�OF�OLD�MASK6‰MOVE.L„8(A4),TCBEMMSK(A5)‚MOVE�ENTIRE�NEW�MASK�TO�TCB.‰AND.B…#$38,D0�SAVE�EXEC�OPTIONS�FROM�OLD�MASK;‰AND.B…#$07,TCBEMMSK(A5)ƒCLEAR�EXEC�OPTION�AREA�IN�NEW�MASK1‰OR.B†D0,TCBEMMSK(A5)…RESTORE�EXEC�OPTIONS�TO�TCB!‰EXIT†SUB‘exit�(subroutine�exit);‰ENDééé×9=/*=/*†M68XXX.EXMON.AF=/**=/* Chain file to assemble M68XXX.EXMON.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.EXMON.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXMON.LS=/ENDIF=/*/=ASM M68XXX.EXMON.SA,M68XXX.EXMON.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééééé à‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE;EXMON„IDNTƒ5,1„68xxx�DIRECTIVE--ATTACH�TO�EXCEPTION�MONITOR*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*******************+*‡*‚E�X�M�O�N†*ƒATTACH�TO�EXCEPTION�MONITOR*‡*‚REV�2.00‡**‡*‚03/23/81‚HLD6�**‡**********************‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A4�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�TASK�NAME�OF�TARGET�TASK*—4�-�SESSION�CODE$*—8�-�TASK�NAME�OF�EXCEPTION�MONITOR*–12�-�SESSION�CODE*’A5�HAS�TARGET�TCB�ADDRESS**‹EXIT�:�D0�HAS�RETURN�CODE*’D0�=�0„GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST.*ŠRTCDTFUL�-�5ƒASQ�IS�FULL�-�OR�IS�NOT�ENABLED;*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�TARGET�ATTACHED�TO�EXMON#*ŠRTCDNFND�-�7ƒEXMON�TASK�NOT�FOUND3*ŠRTCDALOW�-�9ƒTARGET�IS�SYSTEM�TASK�OR�NOT�DORMANT***‰SECTION�LEVEL04* ‰XDEF„EXMON‰PAGEEXMON:‰MOVE.L„A5,A2�SAVE�TARGET�TASK  *!*‡FIND�EXCEPTION�MONITOR�TASK�TCB* ‰TR0.GTXTCB‚8(A4),12(A4)‰BRA.S…EXMON2ŽOK�-�FOUND�TCB ‰EXIT†RTCDNFND  EXMON2:$‰MOVE.L„A0,A5�SAVE�EXMON�TCB�ADDRESS  **†CHECK�FOR�VALID�TASKS* EXMON3::‰BTST†#TSKIEXM,TCBATTI(A2)…DOES�TARGET�ALREADY�HAVE�EXMO�?3‰EXIT.NEƒRTCDDPRQ‘TARGET�ALREADY�ATTACHED�TO�EXMON. ,‰CMP.L…A2,A5”ARE�TARGET�AND�EXMON�SAME�TASK?%‰BEQ.S…EXMONE3’BRANCH�TO�ERROR�IF�YES ‰CMP.L…A2,A6”IS�TARGET�=�CALLER?‰BEQ.S…EXMON5“BRANCH�IF�YES 8‰BTST†#TSKSDORM,TCBSTATE(A2)ƒNO�-�TARGET�MUST�BE�DORMANT-‰BEQ.S…EXMONE3’BRANCH�TO�ERROR�IF�NOT�DORMANT EXMON5:4‰BTST†#TSKASYST,TCBATTR(A6)„IS�CALLER�A�SYSTEM�TASK?‰BNE.S…EXMON6“BRANCH�IF�YES 4‰BTST†#TSKASYST,TCBATTR(A2)„IS�TARGET�A�SYSTEM�TASK?2‰BNE.S…EXMONE3’REJECT�USER�REQ�TO�MONITOR�SYS�TASK EXMON6:é^ò+‰MOVE.L„TCBSESSN(A5),A09‰CMP.L…TCBSESSN(A2),A0ŠARE�TARGET�AND�EXMON�SAME�SESSION?‰BEQ.S…EXMON7“SAME�SESSION�OK 3‰BTST†#TSKASYST,TCBATTR(A5)„IS�EXMON�A�SYSTEM�TASK?‰BNE.S…EXMON7“BRANCH�IF�YES EXMONE3:*‰EXIT†RTCDALOW‘ERROR�-�INVALID�TARGET�TASK  * *…BUILD�MESSAGE�TO�SEND�TO�EXMON* EXMON7:(‰MOVE.L„#$C080000,D2�MSG�LENGTH�AND�TYPE.‰MOVE.W„TCBNAME(A2),D2‹FIRST�HALF�OF�TASK�NAME<‰MOVE.L„TCBNAME+2(A2),D3‰2ND�HALF�OF�NAME,�1ST�HALF�OF�SESSN-‰MOVE.L„TCBSESSN+2(A2),D4ˆ2ND�HALF�OF�SESSION4‰MOVE.W„#$0001,D4�0001�MEANS�MSG�IS�RESULT�OF�ATTACH‰TR0.QEVNTT‚(A5)“GO�TO�QEVENT ‰BRA.S…EXMON8 %‰EXIT†RTCDTFUL‘COULD�NOT�SEND�MESSAGE  *"*…SET�TARGET�'WAITING�FOR�COMMAND'* EXMON8:;‰BSET†#TSKIEXMT,TCBATTI(A5)„GIVE�EXMON�TASK�EXMON�ATTRIBUTE9‰BSET†#TSKIEXM,TCBATTI(A2)…SET�TARGET�'ATTACHED�TO�EXMON'=‰BSET†#TSKSWTEM,TCBSTATE(A2)ƒSET�TARGET�'WAITING�FOR�COMMAND'?‰MOVE.L„TCBNAME(A5),TCBEXM(A2)ƒSAVE�NAME�OF�EXMON�IN�TARGET�TCB9‰MOVE.L„TCBSESSN(A5),TCBEXMS(A2)�SAVE�SESSN�IN�TARGET�TCB ‰CMP.L…A2,A6”IS�CALLER�=�TARGET? &‰EXIT.EQƒPOSTEMPT‘yes�exit�(postempt); ‰EXIT†SUB–no�exit�(subroutine);‰ENDé éé=/*=/*†M68XXX.EXMONVR.AF=/*,=/* Chain file to assemble M68XXX.EXMONVR.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.EXMONVR.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXMONVR.LS=/ENDIF=/*3=ASM M68XXX.EXMONVR.SA,M68XXX.EXMONVR.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDééééééú‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST9EXMONVR‚IDNT„5,1ƒ68xxx�SUBROUTINE--VALIDATE�EXMON�REQUEST*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*+*ˆSUBROUTINE�USED�BY�RSTATE,�PSTATE,�REXMON**ˆVALIDATE�REQUEST*‰SECTION�LEVEL04* ‰XDEF�EXMONVR‰PAGEEXMONVR:6‰BTST†#TSKIEXM,TCBATTI(A5)ŠIS�TARGET�ATTACHED�TO�EXMON"‰BEQ.S…EXMONVRE–BRANCH�IF�NO�EXMON %‰MOVE.L„TCBEXM(A5),D0‘EXMON�TASK�NAME2‰CMP.L…TCBNAME(A6),D0�IS�CALLER�THIS�TASK'S�EXMON?‰BNE.S…EXMONVRE–BRANCH�IF�NO $‰MOVE.L„TCBEXMS(A5),D0�EXMON�SESSION3‰CMP.L…TCBSESSN(A6),D0�DOES�CALLER'S�SESSION�MATCH?‰BNE.S…EXMONVRE–BRANCH�IF�NO  **ˆCheck�buffer�address.*  ‰TR0.LOGPHY‚,8(A3)‰RTS¥GOOD�RETURN ‰NOP%*ˆADD.Lƒ#4,A7›SKIP�SUBROUTINE�RETURN.‰EXIT„RTCDADR1˜exit�(error_12); EXMONVRE:%*ˆADD.Lƒ#4,A7›SKIP�SUBROUTINE�RETURN.‰EXIT„RTCDSTAT˜exit�(error_10);‰END ééé6=/*=/*†M68XXX.EXQEVENT.AF=/*-=/* Chain file to assemble M68XXX.EXQEVENT.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.EXQEVENT.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXQEVENT.LS=/ENDIF=/*5=ASM M68XXX.EXQEVENT.SA,M68XXX.EXQEVENT.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.ASQ.EQ=/*ƒ9995.&.ASQ.MC=/*}=/*=ENDéééééé +EXQEVENTƒIDNT‚5,1ƒ68xxx�TRAP�0--QUEUE�EVENTO*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***B***…FILE:‚EXQEVENT�-�TRAP�0�HANDLER�-�QUEUE�AN�EVENT�TO�A�TASK‰******É***D***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000.‡***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***E***…FUNCTION:‚Queues�an�event�from�the�registers�to�a�target�task†******É******…NOTES:¾******É***E***…REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆ.�******‡A:ƒ. ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ. ******É******É******…ENTRY�CONDITIONS:³******É***<***‰QEVNTN�-�ENTRY:�A0�POINTS�TO�TASK�NAME,�SESSION�CODEŒ******É***/***‰QEVNTT�-�ENTRY:�A0�POINTS�TO�TARGET�TCB™******É***:***‰QEVNTI�-�ENTRY:�A0�POINTS�TO�TARGET�TCB,�CALLER�ISŽ*******šEXTERNAL�INTERRUPT�SERVICE�ROUTINE�******É***E***ƒALL�ENTRY�POINTS�:‚D2�THRU�D7�CONTAIN�EVENT�TO�BE�PLACED�IN�Qˆ***6***—A1�AND�A2�HAVE�CONTINUATION�OF�EVENT�IF�NEEDED„******É******É***-***…EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:Ÿ******É******‹TO�PC�--�SUCCESSFUL«******‹TO�PC+2�--�FAILED­******É******É***O*******************************************************************************O*******************************************************************************O*^*****************************************************************************‰PAGE*,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------)*…08/30/84‚MSLŒRe-wrote�as�state�machine.(*…06/25/84‚SPTŒPerformance�enhancements..*…10/05/83‚SJFŒSaved�D4�around�call�to�ASRINT.*…11/06/81‚HLD6 *…08/20/79‚HLD6‹Initial�writing.* * *‚XDEF's.*‰XDEF†EXQEVNTI‰XDEF†EXQEVNTN‰XDEF†EXQEVNTT<i&w.[6h>pF ‰XDEF†SBQEVNTI‰XDEF†SBQEVNTN‰XDEF†SBQEVNTT * *‚XREF's. ‰XREF.S„APPEND_PB‰XREF.S„GTASQBUF‰XREF.S„I_DISP_ASR‰XREF.S„KILLER‰XREF.S„READY_ASR **‚Included�files:**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.ASQ.EQ*ˆINCLUDEƒ9995.&.ASQ.MC*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.ASQ.EQ‰INCLUDEƒ9995.&.ASQ.MC‰LIST*‰SECTION�LEVEL01‰PAGE#*exqevntn: proc (msg_regs, pb_ptr);  &*„dcl�msg_regs�longword�(D2-D7/A1-A2);*„dcl�pb_ptr�longword�(A0);  *ˆsession�<==�session�(pb_ptr);!*ˆtaskname�<==�taskname�(pb_ptr);1*ˆtarget_tcb_ptr�<==�getxtcb�(taskname,�session); *ˆif�(worked)*ˆthen�go�to�exqevasq;*ˆelse�return�(error);* SBQEVNTN: EXQEVNTN:*$*†ENTER�WITH�TASKNAME�SESSION�NUMBER*.‰MOVE.L„4(A0),D1Œsession�<==�session�(pb_ptr);/‰MOVE.L„(A0),A0�taskname�<==�taskname�(pb_ptr); ‰TR0.GTXTCB*¦target_tcb_ptr�<==*­getxtcb�(taskname,session);‰BRA.S…EXQEVASQŒif�(worked)*¦then�go�to�exqevasq; EXQEVER1:#‰ADD.L…#2,(A7)�else�return�(error);‰RTS‰PAGE,*exqevnti: entry (msg_regs, target_tcb_ptr);,*exqebntt: entry (msg_regs, target_tcb_ptr);  &*„dcl�msg_regs�longword�(D2-D7/A1-A2);#*„dcl�target_tcb_ptr�longword�(A0);  !*ˆif�((target_tcb_ptr)�<>�'!TCB')*ˆthen�return�(error); *ˆelse�do;*�A5�<==�target_tcb_ptr; *�asq_ptr�<==�tcb_asq�(asq_ptr);*�if�(asq_ptr�<>�0)*�then�go�to�exqevent;*�else�return�(error);*ˆend;** EXQEVNTI: SBQEVNTI: SBQEVNTT: EXQEVNTT:2‰CMP.L…#'!TCB',(A0)ˆif�((target_tcb_ptr�<>�'!TCB')"‰BNE‡EXQEVER1Œthen�return�(error); *¦else�do; EXQEVASQ:$‰MOVE.L„A0,A5“A5�<==�target_tcb_ptr;:‰MOVE.L„TCBASQ(A5),A4‹asq_ptr�<==�tcb_asq�(target_tcb_pt);‰MOVE.L„A4,D0“if�(asq_ptr�=�0);"‰BEQ‡EXQEVER1�then�return�(error);*ªelse�go�to�exqevent;*¦end;‰PAGE$*exqevent: proc (msg_regs, tcb_ptr);    *ˆmsg_len�<==�len�(msg_regs);*ˆif*ˆ(msg_len�=�0)*ˆthen�go�to�error�(); *ˆelse�do;*�set�(tmsg_flag); *�freeze�(asq); *�do�case�(asq_state,�asq_mode); *ˆend;  *end exqevent;‰PAGE*ˆmsg_len�<==�len�(msg_regs);*ˆif�(msg_len�=�0)*ˆthen�go�to�error�(); EXQEVENT:$‰MOVE.L„D2,D0�msg_len�<==�len�(msg);‰ROL.L…#8,D0�if‰AND.L…#$FF,D0�(msg_len�=�0)$‰BEQ.S…EXQEVER1Œthen�go�to�error�();  *ˆelse�do;*�set�(tmsg_flag);*�freeze�(asq);"*�do�case�(asq_state,�as_sw_mode);*ˆend; ‰FREEZE_ASQ”freeze_asq 9‰MOVE.W„ASQSTATE(A4),D1…do�case�(asq_sta te,�asq_sw_mode);‰MOVE.W„EXQEV_TBL(PC,D1.W),A0‰JMP‡EXQEV_TBL(PC,A0.W)‰PAGE EXQEV_TBL: ‰DC.W†RQ_DIS00-EXQEV_TBL‰DC.W†RQ_DIS01-EXQEV_TBL‰DC.W†RQ_DIS10-EXQEV_TBL‰DC.W†RQ_DIS11-EXQEV_TBL ‰DC.W†Q_EN_00-EXQEV_TBL‰DC.W†Q_EN_01-EXQEV_TBL‰DC.W†Q_EN_10-EXQEV_TBL‰DC.W†Q_EN_11-EXQEV_TBL ‰DC.W†R_EN_00-EXQEV_TBL‰DC.W†R_EN_01-EXQEV_TBL‰DC.W†R_EN_10-EXQEV_TBL‰DC.W†R_EN_11-EXQEV_TBL ‰DC.W†RQ_EN_00-EXQEV_TBL‰DC.W†RQ_EN_01-EXQEV_TBL‰DC.W†RQ_EN_10-EXQEV_TBL‰DC.W†RQ_EN_11-EXQEV_TBL ‰DC.W†WT_EN_00-EXQEV_TBL‰DC.W†WT_EN_01-EXQEV_TBL‰DC.W†WT_EN_10-EXQEV_TBL‰DC.W†WT_EN_11-EXQEV_TBL ‰DC.W†GT_EN_00-EXQEV_TBL‰DC.W†GT_EN_01-EXQEV_TBL‰DC.W†GT_EN_10-EXQEV_TBL‰DC.W†GT_EN_11-EXQEV_TBL‰PAGE RQ_DIS00: RQ_DIS01: RQ_DIS10: RQ_DIS11: R_EN_00:R_EN_01:R_EN_10:R_EN_11: EXQEVERR:‰RELEASE_ASQ–release�(asq);.‰ADD.L…#2,2(A7)Œpc�(stack)�<==�pc�(stack)�+�2; ‰RTS›return;    RQ_EN_00: RQ_EN_10: WT_EN_00: WT_EN_10: GT_EN_00: GT_EN_10:‰RELEASE_ASQ–release�(asq);‰BSR‡KILLERŽcall�(killer);    Q_EN_00:Q_EN_01:Q_EN_10:Q_EN_11:‰BSR‡GTASQBUFŒcall�get_asq_buf;‰BRA.S…EXQEV_20Œif�(error)!‰BRA.S…EXQEVERRŒthen�go�to�error; EXQEV_20: *¦else�do;,‰BCLR†#ASQMTBIT,ASQSWMD2(A4)ƒreset�(asq_mt);‰RELEASE_ASQ˜release_asq;‰BSR‡R_IMPORT‘call�r_import; ‰RTS return;*¦end;    GT_EN_01: *ˆdest_ptr�<==�A0_buf�(asq_ptr);*ˆgo�to�exqev_30 6‰MOVE.L„ASQA0BUF(A4),A0…dest_ptr�<==�A0_buf�(asq_ptr);‰BRA.S…EXQEV_30Œgo�to�exqev_30; GT_EN_11: !*ˆdest_ptr�<==�def_buf�(asq_ptr); 6‰MOVE.L„ASQDBUF(A4),A0†dest_ptr�<==�def_buf�(asq_ptr); EXQEV_30:4‰AND.B…#SWMD_MASK,D1‡asq_state�(asq_ptr)�<==�asq_en;‰OR.B†#Q_EN,D1‰MOVE.W„D1,ASQSTATE(A4)‰RELEASE_ASQ“release�(asq); ‰BSR‡RS_BYPASS‹call�rs_bypass;‰E_CHK_PB–check�(append_pb);%‰TR0.RYGET�(A5)�call�ready�(tcb_ptr); ‰RTS›return;    =*„NOTE:‚We�may�want�to�bring�the�following�two�cases�together*‹to�save�space. RQ_EN_01:‰BSR‡GTASQBUFŒcall�get_asq_buf;‰BRA.S…EXQEV_40Œif�(error)$‰BRA.S…EXQEVERRŒthen�go�to�error�(); EXQEV_40: *¦else�do;"‰AND.B…#DBUF_EN,D1Žreset�(asq_mt);.‰OR.B†#Q_EN,D1‘asq_state�(asq_ptr)�<==�asq_en;‰MOVE.W„D1,ASQSTATE(A4)‰RELEASE_ASQ˜release_asq;‰BSR‡RA_IMPORT�call�ra_import; ‰BSR‡I_DISP_ASR�call�i_disp_asr; ‰RTS return;*¦end; WT_EN_01:‰BSR‡GTASQBUFŒcall�get_asq_buf;‰BRA.S…EXQEV_50Œif�(error)"‰BRA‡EXQEVERRŒthen�go�to�error�(); EXQEV_50: *¦else�do;"‰AND.B…#DBUF_EN,D1Žreset�(asq_mt);.‰OR.B†#Q_EN,D1‘asq_state�(asq_ptr)�<==�asq_en;‰MOVE.W„D1,ASQSTATE(A4)‰RELEASE_ASQ˜release_asq; ‰BSR.S…RA_IMPORT�call�ra_import;‰BSR‡READY_ASR�call�i_disp_asr; ‰RTS return;*¦end;    RQ_EN_11:4‰AND.B…#SWMD_MASK,D1‡asq_state�(asq_ptr)�<==�asq_en;‰OR.B†#Q_EN,D1‰MOVE.W„D1,ASQSTATE(A4)‰RELEASE_ASQ–release_asq; 7‰MOVE.L„ASQDBUF(A4),A0†dest_ptr�<==�asq_dbuf�(asq_ptr); ‰BSR.S…RA_BYPASS‹call�ra_bypass;‰E_CHK_PB–check�(append_pb); ‰BSR‡I_DISP_ASRŠcall�i_disp_asr; ‰RTS›return;    WT_EN_11:4‰AND.B…#SWMD_MASK,D1‡asq_state�(asq_ptr)�<==�asq_en;‰OR.B†#Q_EN,D1‰MOVE.W„D1,ASQSTATE(A4)‰RELEASE_ASQ–release_asq; 7‰MOVE.L„ASQDBUF(A4),A0†dest_ptr�<==�asq_dbuf�(asq_ptr); ‰BSR.S…RA_BYPASS‹call�ra_bypass;‰E_CHK_PB–check�(append_pb);‰BSR‡READY_ASR‹call�ready_asr; ‰RTS›return;‰PAGE.*ra_import: proc (msg_regs dest_ptr, msg_len);  '*„dcl‚msg_regs�byte�(32)�(D2-D7/A1-A2);*„dcl‚dest_ptr�longword�(A0);*„dcl‚msg_len�word�(D0);  *ˆif�(bit_7�(msg_code)�=�set)0*ˆthen�asq_xfr�(asq_ptr)�<==�alt_asr_addr�(msg);/*ˆelse�asq_xfr�(asq_ptr)�<==�asq_asr�(asq_ptr);*ˆgo�to�r_import;  /*ra_bypass: entry (msg_regs dest_ptr, msg_len);  *ˆreset�(bit_7�(code));*ˆif�(bit_7�was�set)�then�do;)*�asq_xfr�(asq_ptr)�<==�asr_vector�(msg);*�squeeze�(msg);*ˆend;/*ˆelse�asq_xfr�(asq_ptr)�<==�asq_asr�(asq_ptr);*ˆgo�t o�r_import;  0*rs_bypass: entry (msg_regs, dest_ptr, msg_len);  *ˆreset�(bit_7�(code));*ˆif�(bit_7�was�set)*ˆthen�squeeze�(msg);*ˆgo�to�r_import;  /*r_import: entry (msg_regs, dest_buf, msg_len);  /*ˆmsg_len�<==�msg_len�*�len�(entry�(move_tbl));#*ˆA1�<==�addr�(move_tbl�+�msg_len); *ˆjmp�(A1);‰PAGE/*ra_import: entry (msg_regs dest_ptr, msg_len);  '*„dcl‚msg_regs�byte�(32)�(D2-D7/A1-A2);*„dcl‚dest_ptr�longword�(A0);*„dcl‚msg_len�word�(D0);  *ˆif�(bit_7�(msg_code)�=�set)0*ˆthen�asq_xfr�(asq_ptr)�<==�alt_asr_addr�(msg);/*ˆelse�asq_xfr�(asq_ptr)�<==�asq_asr�(asq_ptr);*ˆgo�to�r_import;  RA_IMPORT: ‰BTST†#23,D2‰BEQ.S…USE_DEF_VECT ‰MOVE.L„D3,D1 ‰MOVE.W„D2,D1‰SWAP†D1‰MOVE.L„D1,ASQXFR(A4)‰BRA.S…R_IMPORT  ‰PAGE/*ra_bypass: entry (msg_regs dest_ptr, msg_len);  *ˆreset�(bit_7�(code));*ˆif�(bit_7�was�set)�then�do;)*�asq_xfr�(asq_ptr)�<==�asr_vector�(msg);*�squeeze�(msg);*ˆend;/*ˆelse�asq_xfr�(asq_ptr)�<==�asq_asr�(asq_ptr);*ˆgo�to�r_import;  RA_BYPASS: ‰BCLR†#23,D2‰BEQ.S…USE_DEF_VECT ‰MOVE.L„D3,D1 ‰MOVE.W„D2,D1‰SWAP†D1‰MOVE.L„D1,ASQXFR(A4)‰BRA.S…SQUEEZE_MSG  USE_DEF_VECT:‰MOVE.L„ASQASR(A4),ASQXFR(A4)‰BRA.S…R_IMPORT‰PAGE0*rs_bypass: entry (msg_regs, dest_ptr, msg_len);  *ˆreset�(bit_7�(code));*ˆif�(bit_7�was�set)*ˆthen�squeeze�(msg);*ˆgo�to�r_import;   RS_BYPASS:$‰BCLR.L„#23,D2Žreset�(bit_7�(code));+‰BEQ.S…R_IMPORTŒif�(bit_7�was�set)�then�do; SQUEEZE_MSG:%‰SUB.W…#4,D0”msg_len�<==�msg_len�-�4;1‰SUB.L…#$04000000,D2Œlen�(msg)�<==�len�(msg)�-�4; ‰MOVE.W„D3,D2”squeeze�(msg); ‰MOVE.L„D4,D3 ‰MOVE.L„D5,D4 ‰MOVE.L„D6,D5 ‰MOVE.L„D7,D6 ‰MOVE.L„A1,D7‰MOVE.L„A2,A1�end;*¦go�to�r_import;‰PAGE/*r_import: entry (msg_regs, dest_buf, msg_len);  '*„dcl‚msg_regs�byte�(32)�(D2-D7/A1-A2);*„dcl‚dest_ptr�longword�(A0);*„dcl‚msg_len�word�(D0);  /*ˆmsg_len�<==�msg_len�*�len�(entry�(move_tbl));#*ˆA1�<==�addr�(move_tbl�+�msg_len); *ˆjmp�(A1);   R_IMPORT:3‰LSL.W…#2,D0�len�<==�len�*�len�(entry�in�move_tbl);*¦(Len�=�offset�(move_tbl);)*‰JMP‡MOVE_TBL(PC,D0.W)ƒjmp�move_tbl�(len);‰PAGE*A* The move routines make use of the MOVEM instruction to speed up?*ˆthe�transfer.‚The�NOP�instructions�are�inserted�to�adjust�the(*ˆthe�length�of�all�routines�to�be�same.* *ˆWARNING:6*’DO�NOT�REMOVE�THE�NOP�INSTRUCTIONS�IN�THE�MOVERS!!!!1*’THEY�ADJUST�THE�ROUTINE�OFFSETS�TO�BE�THE�SAME.*,MOVE_TBL�EQU‡*-8‘INVALID�TO�MOVE�ZERO�BYTES.MOVE2‰BRA.S…MOVEFIX‰NOP‰NOP‰NOPMOVE4‰MOVE.L„D2,(A0) ‰BRA.S…MOVEX‰NOP‰NOPMOVE6‰MOVE.L„D2,(A0)‰MOVE.L„D3,-(A7)‰BRA.S…MOVEFIX‰NOPMOVE8‰MOVEM.LƒD2-D3,(A0) ‰BRA.S…MOVEX‰NOPMOVE10‰MOVEM.LƒD2-D3,(A0)‰MOVE.L„D4,-(A7)‰BRA.S…MOVEFIXMOVE12‰MOVEM.LƒD2-D4,(A0) ‰BRA.S…MOVEX‰NOPMOVE14‰MOVEM.LƒD2-D4,(A0)‰MOVE.L„D5,-(A7)‰BRA.S…MOVEFIXMOVE16‰MOVEM.LƒD2-D5,(A0) ‰BRA.S…MOVEX‰NOPMOVE18‰MOVEM.LƒD2-D5,(A0)‰MOVE.L„D6,-(A7)‰BRA.S…MOVEFIXMOVE20‰MOVEM.LƒD2-D6,(A0) ‰BRA.S…MOVEX‰NOPMOVE22‰MOVEM.LƒD2-D6,(A0)‰MOVE.L„D7,-(A7)‰BRA.S…MOVEFIXMOVE24‰MOVEM.LƒD2-D7,(A0) ‰BRA.S…MOVEX‰NOPMOVE26‰MOVEM.LƒD2-D7,(A0)‰MOVE.L„A1,-(A7)‰BRA.S…MOVEFIXMOVE28‰MOVEM.LƒD2-D7/A1,(A0) ‰BRA.S…MOVEX‰NOPMOVE30‰MOVEM.LƒD2-D7/A1,(A0)‰MOVE.L„A2,-(A7)‰BRA.S…MOVEFIXMOVE32‰MOVEM.LƒD2-D7/A1-A2,(A0) ‰BRA.S…MOVEX MOVEFIX:*‰LSR.W…#2,D0�move�the�word�from�the�stack,2‰MOVE.W„(A7),-2(A0,D0.W)„to�the�end�of�the�buffer. -‰ADD.L…D0,A0�dest_ptr�<==�dest_ptr�+�msg_len;‰ADDQ.L„#4,A7�clean�up�stack; ‰RTS›return; MOVEX:-‰LSR.W…#2,D0�dest_ptr�<==�dest_ptr�+�msg_len; ‰ADD.L…D0,A0 ‰RTS›return;‰END éééééé=/*=/*†M68XXX.EXRQPA.AF=/*+=/* Chain file to assemble M68XXX.EXRQPA.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.EXRQPA.LS=/*=/IFC \1ƒ=ARG�M68XXX.EXRQPA.LS=/ENDIF=/*1=ASM M68XXX.EXRQPA.SA,M68XXX.EXRQPA.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDééééééNŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.INTERRUP.M CŠLISTŠPAGEDEXRQPA„IDNTƒ5,1‡68xxx�TRAP�0--REQUEST�PERIODIC�ACTIVATION�OF�PROCESS*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�EXRQPAƒ3.10„**ˆ*’**ˆ*�HLD6ƒ02/08/82‚**ˆ**********************…REQUEST�PERIODIC�ACTIVATION*:*ˆENTRY�REGISTERS:‚A0ˆAddress�of�procedure�to�be�activated'*šA1ˆActivation�interval�(Milliseconds)0*šD1‚Bit�15=0‚Request�for�new�periodic�actvation,*žBit�15=1‚Cancel�periodic�actvation�request$*žBit�14=0‚Request�single�activation(*žBit�14=1‚Request�continuous�activation&*žBit�13=1‚(only�used�of�NOT�a�cancel)*ªDo�not�cancel�an�existing*ªrequest�with�the�same�ID�when*ªinserting�this�new�request.+*žBit�13=0‚Cancel�existing�request�with�the*ªsame�ID�before�inserting�this*ªnew�request.‚If�this�option!*ªis�used,�only�the�first�request *ªwith�a�matching�ID�is�removed.(*žBits�7-0‚Interrupt�level�of�activation*šD2ˆRequest�ID*>*ˆRETURN�REGISTERS:�D0�and�D1�Destroyed�-�All�others�preserved*0*ˆPC�ON�RETURN:…PC�unchanged�-�Successful�return$*šPC=PC+2†-�Unable�to�accept�request*ŠSECTION�LEVEL00* ŠXDEFƒEXRQPA ŠXDEFƒSBRQPA ŠXDEFƒPAT_SCHED_NEW_NODEŠXDEFƒPAT_DEL_NODEŠXDEFƒPAT_1ST_NODE_DELŠXDEFƒPAT_RM_1ST_NODEŠXDEFƒPAT_MID_NODE_DEL** SYSPAR parameters* ŠXREF.S�NSEŠXREF.S�PATBEGŠXREF.S�TIME_LEFT 3* IF this is NOT a cancel request (bit 15 = 0) THEN >*ƒIF�cancel�before�insert�option�IS�selected�(bit�13�=�0)�THEN-*†remove�node�from�PAT�list�with�matching�ID.*ƒENDI *ƒPlace�rquest�into�PAT�list. * ELSE*ƒcancel�request.  SBRQPA:EXRQPA:*ŠMOVE.W�SR,-(A7)‹Save�for�unmasking�later.>ŠMOVEM.L�D2-D3/A1-A4,-(A7)�There�are�the�registers�I�must�save ,SRSTACKƒSET„(2*4)+(4*4)ˆDepth�to�SR�on�stack WW`XhTpBxC€%ŠMOVE.L�A1,D0ŽRequested�time�interval6ŠMOVE.L�PATBEG,A1ŠAddress�of�Periodic�Activation�Table ŠTST.W‚D1ŠIF��THEN.S  *B*�This�is�an�insert�request.‚If�the�cancel�before�insert�option�is5*ƒselected�(bit�13=0)�then�cancel�this�request�first.* �BTST‚#13,D1�IF��THEN.S�BSR.S‚PAT_CAN_REQUEST�ENDI *A* Try to get a node from the free list and schedule this routine.* �DISABLE_INTERRUPTS…Mask +�MOVE.L„PATFHDR(A1),D3‚Free�PAT�node�header�IF��THEN.S�MOVE.W�SRSTACK(A7),SR‚Unmask>�ADD.L‚#2,SRSTACK+2(A7)�No�free�entry�so�bias�return�addr�by�2 �BRA„EXRQ2RŠGo�make�error�return �ELSE.S�MOVE.L�D3,A2‡New�entry�address;�MOVE.L�PATNEXT(A2),PATFHDR(A1)�Remove�entry�from�free�list�MOVE.W�SRSTACK(A7),SR‚Unmask  *=* A2 points to free node, plug node with required information* $�CLR.L‚PATTCB(A2)‰Mark�as�Exec�entry(�BCLRƒ#31,D0�Insure�interval�is�positive&�MOVE.L�D0,PATINTV(A2)…Set�up�interval  *D* Note: PATDELTA will be computed and inserted by PAT_SCHED_NEW_NODE* ,�MOVE.L�A0,PATASR(A2)†Exec�procedure�address$�MOVE.L�D2,PATARID(A2)…Activation�ID�CLR.W‚PATOPT(A2)‰Clear�option-�BTSTƒ#PATOINTV,D1‡Should�continuation�be�set �IF��THEN.S*“BSET‚#PATOINTV,PATOPT(A2)�Yes�-�so�set�it�ENDI #�LSL.W‚#8,D1ŽJustify�priority�level5�OR.Wƒ#$FFFF-$0700,D1„Add�all�bits�outside�of�i-level(�MOVE.W�D1,PATILVL(A2)…Set�into�PAT�node  ** Put entry into active list* .�MOVE.L�D0,D2Žms�from�now�for�SCHED�subroutine�DISABLE_INTERRUPTSˆmask-�BSR„PAT_SCHED_NEW_NODE�Schedule�the�new�node '�MOVE.W�SRSTACK(A7),SR…Allow�interrupts�BRA„EXRQ2R�Go�exit �ENDIŠENDI  *;* This is a cancel request, find node on list and delete it* PAT_CAN:ŠBSR.S‚PAT_CAN_REQUEST ŠBRA„EXRQ2R‰PAGE*=* Subroutine cancels the request for the 1st EXEC node on theG*ƒPAT�list�that�matches�the�ID�in�D2.‚Node�is�removed�from�active�list, 4*ƒPAT_DELTA�and�TIME_LEFT�(if�1st�node)�are�updated.**ƒAll�registers�preserved.* PAT_CAN_REQUEST:ŠMOVEM.L�D3-D4/A2-A4,-(A7) FSRSTACKƒSET„SRSTACK+(5*4)+4„Add�more�registers,�and�subroutine�return. 'ŠLEA„PATHDR(A1),A2†Start�of�ACTIVE�list2ŠMOVE.L�A2,A3ŽA3�will�trail�A2�as‚we�scan�the�list#ŠDISABLE_INTERRUPTSˆMask�interrupts6ŠMOVE.L�PATNEXT(A3),A2…A2�points�to�first�node�on�list  *<* If PATTCB = 0 then this is an Exec node - see if IDs match* 9ŠIF.L�PATTCB(A2)��#0�AND.L�PATARID(A2)��D2�THEN.S1�MOVE.L�PATNEXT(A2),PATNEXT(A3)�Unlink�this�entry?�MOVE.L�PATNEXT(A2),A4‚Point�to�new�first�node,�(prev�2nd�node)1�MOVE.L�PATDELTA(A4),D4�Delta�of�removed�1st�node�ADD.L‚D4,TIME_LEFT �ADD.L‚D4,NSE$�BCLRƒ#31,NSE‰Insure�positive�number�MOVE.W�SRSTACK(A7),SR‚Unmask(�BRA.S‚EXRQ2.1‰Exit�if�we�found�an�entry ŠENDI  *+* First node wasn't it, walk list for match* +ŠMOVE.L�A2,A3ŽA3�points�to�1st�node�on�list4ŠMOVE.L�PATNEXT(A3),D3…D3�points�to�2nd�node�on�list ŠWHILE��DO.S/�MOVE.L�D3,A2‹A2�-->�node,�A3�-->�previous�node 9�IF.L‚PATTCB(A2)��#0�AND.L�PATARID(A2)��D2�THEN.S,�MOVE.L�PATNEXT(A2),PATNEXT(A3)�Unlink�entry3�MOVE.L�PATNEXT(A2),A4�Point�A4�to�next�node�if�any �IF�A4��#0�THEN.S4“MOVE.L�PATDELTA(A2),D4‚There�was�a�next�node�so�...4“ADD.L‚D4,PATDELTA(A4)‚...�update�delta�of�that�node�ENDI �MOVE.W�SRSTACK(A7),SR�Unmask#�BRA.S‚EXRQ2.1†Branch�on�found�node �ELSE.S�MOVE.L�A2,A3ˆA3�-->�this�node/�MOVE.L�PATNEXT(A2),D3‚D3�-->�next�node,�if�any�ENDI ŠENDW *ŠBRA.S�EXRQ2.R�Branch�if�nothing�to�cancel  ** Free the entry* EXRQ2.1:ŠPAT_FREE_NODE�Put�on�free�list EXRQ2.R:ŠMOVEM.L�(A7)+,D3-D4/A2-A4+ŠRTS—Return�from�PAT_CAN_REQUEST�subroutine #* End of PAT_CAN_REQUEST subroutine  EXRQ2R::ŠMOVEM.L�(A7)+,D2-D3/A1-A4�Return�from�this�entire�routine#ŠMOVE.W�(A7)+,SR‹Lose�SR�from�stackŠRTSŠPAGEC*------------------------------------------------------------------ *SubroutinePAT_SCHED_NEW_NODE: *�Entry:‚A1�points�to�PAT�header%*‰A2�points�to�node�we�wish�to�insert:*‰D2�contains�the�interval�in�ms�until�the�node�is�to�fire>*ŒNOTE:�Interrupts�MUST�be�inhibited�when�calling�this�routine**�Exit:ƒD0�destroyed*‰D1�destroyed*‰A3�destroyed*‰A4�destroyed#*ŒCheck�two�exit�points�for�details 1ŠMOVE.L�PATHDR(A1),A3†point�to�current�first�node$ŠMOVE.L�D2,D1Žinterval�(ms�from�now)4ŠSUB.L‚TIME_LEFT,D1‡D1=interval�-�original_time_leftŠIF��THEN.S*$*œThis�is�the�case�where�the�node�we)*œschedule�is�the�first�node�in�the�list.*œThe�formulas�we�use�are:**žnew_time_left�=�interval1*žprev_1st_node_delta�=�orig_time_left�-�interval0*žnew_NSE�=�orig_NSE�-�orig_time_left�+�interval*"�MOVE.L�D2,TIME_LEFT„New�time_left �ADD.L‚D1,NSE$�BCLRƒ#31,NSE‰Insure�positive�number �NEG.L‚D19�MOVE.L�D1,PATDELTA(A3)�Previous�1st�node's�updated�delta?�MOVE.L�A3,PATNEXT(A2)‚Link�previous�first�node�to�new�1st�node7�MOVE.L�A2,PATHDR(A1)ƒLink�new�first�node�to�PAT�header  *!* After inserting new first node:"*‰A2�points�to�newly�inserted�node3*‰A3�points�to�following�node�(previous�first�node)5*‰D1�contains�delta�of�following�node�(previous�node)* ŠELSE.S.*œThis�is�the�case�where�we�are�not�scheduling.*œthe�first�node�on�the�list�but�must�walk�the-*œlist�to�determine�the�spot�in�time�sequence%*œwhere�the�new�node�is�to�be�linked.**œA1�points�to�PAT�header%*œA2�points�to�node�we�wish�to�insert/*œA3�points�to�first�node�currently�on�PAT�list2*œD2�contains�the�interval�in�ms�until�the�node�is *¡to�fire A�MOVE.L�PATNEXT(A3),A4�A4�leads�A3�by�pointing�to�the�'next'�node�SUB.L‚PATDELTA(A4),D1�WHILE��DO.S.�MOVE.L�A4,A3ˆHaven't�found�place�yet�-�so�...3�MOVE.L�PATNEXT(A3),A4‚Advance�to�next�node�on�list�SUB.L‚PATDELTA(A4),D1�ENDW * Insert middle node:0*œWe�currently�bracket�the�place�in�the�PAT�list /*œwhere�we�need�to�link�the�new�node.‚A3�points3*œto�the�previous�node,�A4�points�to�the�next�node.+*œWe�must�link�the�node�pointed�at�by�A2�in*œbetween�these�two�nodes.MID_NODE!�MOVE.L�PATDELTA(A4),PATDELTA(A2)�ADD.L‚D1,PATDELTA(A2) �NEG.L‚D1�MOVE.L�D1,PATDELTA(A4);�MOVE.L�PATNEXT(A3),PATNEXT(A2)�Point�new�node�to�next�node6�MOVE.L�A2,PATNEXT(A3)‚Point�previous�node�to�new�nodeŠENDI*!* After inserting new middle node(*‰A2�points�to�inserted�node�(unchanged)*‰A3�points�to�previous�node*‰A4�points�to�following�node%*‰D1�contains�delta�of�following�node* SCHED_RTS RTS * Subroutine PAT_DEL_NODE: *�Entry:‚A1…points�to�PAT�header"*‰A2…points�to�entry�to�be�removed<*‰A3…If�node�we�want�to�delete�is�middle�node�then�A3�points*’to�node�just�prior.2*�Exit:ƒA2…points�to�entry�following�removed�entry*‰A3…destroyed-*‰D0…contains�DELTA�of�PAT�entry�just�removed 8ŠMOVE.L�PATHDR(A1),-(A7)‡Pointer�to�1st�item�in�PAT�listAŠIF.L�A2��(A7)+�THEN.S…IF�we're�deleting�the�1st�item�then...�BSR.S‚PAT_1ST_NODE_DELŠELSE.S7�BSR.S‚PAT_MID_NODE_DEL„Delete�item�other�than�1st�itemŠENDIŠRTS * SubroutinePAT_1ST_NODE_DEL: *�Entry:‚A1…points�to�PAT�header"*‰A2…points�to�entry�to�be�removed2*�Exit:ƒA2…points�to�entry�following�removed�entry-*‰D0…contains�DELTA�of�current�1st�PAT�entry. +ŠMOVE.L�PATNEXT(A2),PATHDR(A1)�Unlink�entry1ŠPAT_FREE_NODE�put�the�node�back�on�the�free�list;ŠMOVE.L�PATHDR(A1),A2†set�A2�to�point�to�first�item�on�list>ŠMOVE.L�PATDELTA(A2),D0„Update�SYSPAR's�time�left�and�next�...3ŠADD.L‚D0,TIME_LEFT‡...�significant�event�parameter ŠADD.L‚D0,NSE$ŠBCLRƒ#31,NSEŒInsure�positive�numberŠRTS * SubroutinePAT_MID_NODE_DEL: *�Entry:‚A1…points�to�PAT�header"*‰A2…points�to�entry�to�be�removed4*‰A3…points�to�node�just�prior�to�node�to�be�removed2*�Exit:ƒA2…points�to�entry�following�removed�entry-*‰D0…contains�DELTA�of�PAT�entry�just�removed 1ŠMOVE.L�PATNEXT(A2),PATNEXT(A3)�Unlink�this�entry"ŠPAT_FREE_NODE�Return�to�free�pool5ŠMOVE.L�PATDELTA(A2),D0„Delta�of�node�we�just�removed/ŠMOVE.L�PATNEXT(A3),A2…Point�to�following�entry5ŠADD.L‚D0,PATDELTA(A2)„Update�delta�of�following�nodeŠRTS * SubroutinePAT_RM_1ST_NODE: G*�Removes�first�PAT�node.‚Does�not�place�on�free�queue.‚Updates�NSE�andE*ƒTIME_LEFT�accordingly.‚Absolute�time�that�node�was�to�fire�(NSE)�is5*ƒplaced�into�the�PATDELTA�field�of�the�removed�node. *�Entry:‚A1…points�to�PAT�header"*‰A2…points�to�entry�to�be�removed4*�This�routine�must�be�called�with�interrupts�masked1*�Exit:ƒA2…A2�points�to�removed�entry�(unchanged)*‰A3…points�to�new�1st�node-*‰D0…contains�DELTA�of�current�1st�PAT�entry. +ŠMOVE.L�PATNEXT(A2),PATHDR(A1)�Unlink�entry.ŠMOVE.L�PATHDR(A1),A3ŠPoint�A3�to�new�1st�nodeŠMOVE.L�PATDELTA(A3),D06ŠADD.L‚D0,TIME_LEFT‡Bump�TIME_LEFT�and�NSE�by�delta�ofŠADD.L‚D0,NSE�new�first�node$ŠBCLRƒ#31,NSEŒInsure�positive�numberŠRTS ŠENDéééé =/*=/*†M68XXX.FNDGSEG.AF=/*,=/* Chain file to assemble M68XXX.FNDGSEG.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.FNDGSEG.LS=/*=/IFC \1ƒ=ARG�M68XXX.FNDGSEG.LS=/ENDIF=/*3=ASM M68XXX.FNDGSEG.SA,M68XXX.FNDGSEG.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.GST.EQ=/*}=/*=ENDééééé鈉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.GST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.GST.EQ‰LIST‰PAGE?FNDGSEG‚IDNT‚5,1‚68xxx�TRAP�0--FIND�SEGMENT�IN�GLOBAL�SEG�TABLE*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*$*†FNDGSEG‚--‚REV�1.01‚4/10/79ƒ(HLD6)**ˆPURPOSE:‚FIND�GLOBAL�SEGMENT4*�LOOKS�IN�GLOBAL�SEGMENT�TABLE�FOR�CALLER'S�SEGMENT6*�IF�FOUND�-�RETURNS�POINTER�TO�GST�ENTRY�FOR�MATCHING *›SEGMENT7*�IF�NOT�FOUND�-�RETURNS�POINTER�TO�UNUSED�ENTRY�IN�GST!*ŸPOINTER�=�0�IF�NO�ROOM�IN�TABLE**ˆENTRY:�A0�=�SEGMENT�NAME'*�D1�=�SEGMENT�ATTRIBUTES�(NOT�CHANGED)!*�D2�=�SESSION�CODE�(NOT�CHANGED)*3*ˆEXIT:‚RTS„A0�=�POINTER�TO�MATCHING�ENTRY�IN�TABLE-*�RTS+2‚A0�=�POINTER�TO�UNUSED�ENTRY�IN�TABLE&*–D0�=�UPDATED�COUNT�OF�ENTRIES�IN�GST,*›(REPLACES�GSTLENT�IF�UNUSED�ENTRY�IS�USED)+*’OR‚A0�=�0�IF�NO�SPACE�IS�AVAILABLE�IN�GST***ˆREGISTERS�USED:‚01234567*—D�*****—A�******ˆCODE�IS�RE-ENTRANT*ˆNO�SUBROUTINES�CALLED$*ˆGST�TABLE�CHECKED�BUT�NOT�MODIFIED**‰SECTION�LEVEL02* ‰XDEF„FNDGSEG‰XDEF„SBFNDGSG ‰XREF.S‚GSTBEG‰PAGE SBFNDGSG:FNDGSEG: ‰CLR.L…D3 ‰CLR.L…D0,‰MOVE.L„GSTBEG,A1‹PTR�TO�GLOBAL�SYMBOL�TABLE‰MOVE.L„A1,D0�DOES�TABLE�EXIST?‰BEQ.S…FNDGNOR�BRANCH�IF�NO '‰LEA‡GSTENTRY(A1),A2…FIRST�ENTRY�IN�GST,‰MOVE.W„GSTLENT(A1),D0†NUMBER�ENTRIES�IN�GST‰BEQ.S…FNDGSXX�TABLE�IS�EMPTY +‰SUB.L…A3,A3�CLEAR�PNTR�TO�1ST�UNUSED�ENTRY  **ˆCHECK�ONE�GST�ENTRY* FNDGSG1:‰TST.W…GSTCNT(A2)ŠIS�ENTRY�USED‰BNE.S…FNDGSG2�YES *‰CMP.L…#0,A3�DO�WE�HAVE�PNTR�TO�1ST�UNUSED‰BNE.S…FNDGSG3�YES ‰MOVE.L„A2,A3�SAVE�1ST�UNUSED ‰BRA.S…FNDGSG3 FNDGSG2:&‰CMP.L…GSTNAME(A2),A0†DO�NAMES�COMPARE‰BNE.S…FNDGSG3�NO ,‰CMP.L…GSTSESSN(A2),D2…COMPARE�SESSION�CODES‰BEQ.S…FNDGSX2�SAME�-�EXIT ,‰BTST†#SEGAGLBL,GSTATTR(A2)�IS�ENTRY�GLOBAL?‰BEQ.S…FNDGSG3�NO ‘_š3%‰BTST†#SEGAGLBL,D1ˆCALLER�SAY�GLOBAL?‰BNE.S…FNDGSX2�YES�-�EXIT #‰BTST†#SEGASHR,D1‰CALLER�SAY�LOCAL?‰BNE.S…FNDGSG3�YES ‰MOVE.L„A2,D3�SAVE�POINTER FNDGSG3:#‰ADD.L…#GSTEL,A2‹INCR�TO�NEXT�ENTRY'‰SUB.W…#1,D0�DECREMENT�COUNT�OF�ENTRIES ‰BNE‡FNDGSG1�GO�CHECK�NEXT�ENTRY ‰TST.L…D3’WAS�POINTER�SAVED?‰BNE.S…FNDGSX3�YES�-�USE�IT  *'*ˆALL�ENTRIES�CHECKED�--�NO�MATCH�FOUND* (‰MOVE.W„GSTLENT(A1),D0†CURRENT�#�ENTRIES ‰MOVE.L„A3,A0$‰CMP.L…#0,A3�WAS�UNUSED�ENTRY�FOUND?‰BNE.S…FNDGSX1�YES FNDGSXX:‰MOVE.L„A2,A0�GET�NEXT�ENTRY(‰CMP.W…GSTMENT(A1),D0†COMPARE�WITH�MAX�#&‰BLT.S…FNDGSX0�BRANCH�IF�ROOM�IN�TABLE FNDGNOR:(‰SUB.L…A0,A0�NO�ROOM,CLEAR�A0�FOR�RETURN FNDGSX0: ‰ADD.L…#1,D0�INCREMENT�#�ENTRIES FNDGSX1:‰ADD.L…#2,(A7)�RETURN�TO�PC+2‰RTS  FNDGSX2:(‰MOVE.L„A2,A0�RETURN�ADDR�OF�ENTRY�FOUND‰RTS  FNDGSX3:)‰MOVE.L„D3,A0�RETURN�ADDR�OF�GLOBAL�ENTRY‰RTS‰ENDéééé=/*=/*†M68XXX.FNDTSEG.AF=/*,=/* Chain file to assemble M68XXX.FNDTSEG.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.FNDTSEG.LS=/*=/IFC \1ƒ=ARG�M68XXX.FNDTSEG.LS=/ENDIF=/*3=ASM M68XXX.FNDTSEG.SA,M68XXX.FNDTSEG.RO,\1;MRZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*}=/*=ENDéééé é颉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰LIST‰PAGEAFNDTSEG‚IDNTƒ5,1‚68xxx�TRAP�0--FIND�SEGMENT�IN�TASK�SEGMENT�TABLE*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�FNDTSEG…1.00�**ˆ*’**ˆ*�7616�04/23/79„**ˆ*********************…FIND�SEGMENT�NAME�IN�TST *ˆ7616,�ESQ*$*�ENTRY‚A0„POINTS�TO�TST�(PRESERVED)*ˆD7„DESIRED�SEGMENT�NAME**�EXITƒPC„IF�FOUND*ˆD5„FOUND�ENTRY�AT�0(A0,D5)**ˆPC+2‚IF�NOT�FOUND)*ˆD5„0(A0,D5)�POINTS�TO�FIRST�EMPTY�ENTRY* *’01234567*�USES�REGISTERS�D�R„*�E*�A�P†E**ˆDOES�NOT�GET�EXCLUSIVE�ACCESS*‰SECTION�LEVEL02* ‰XDEFƒFNDTSEG‰XDEFƒSBFNDSEG‰PAGE SBFNDSEG:FNDTSEG:‰CLR.L‚D0ŽCLEAR�FOR�SHORT�LOADS ‰MOVE.L�A0,D5‹BE�SURE�TST�EXISTS‰BEQ.S‚FNDTSEG4ˆEXIT�IF�NOT ‰CLR.L‚D5!‰MOVE.W�TSTLMMU(A0),D5�LAST�ENTRY FNDTSEG1:,‰BTSTƒ#SEGAUSED,TSTAATTR(A0,D5)ˆEMPTY�ENTRY?#‰BNE.S‚FNDTSEG2ˆBRANCH�IF�NOT�EMPTY #‰MOVE.L�D5,D0‹EMPTY--REMEMBER�ENTRY(‰BRA.S‚FNDTSEG3ˆLOOK�FOR�ANOTHER�SEGMENT FNDTSEG2: ‰CMP.L‚TSTANAME(A0,D5),D7…A�HIT?‰BEQ.S‚FNDTSEG5ˆBRANCH�IF�YES FNDTSEG3:!‰SUB.L‚#8,D5ŠTRY�NEXT�LOWER�ENTRY‰CMP.W‚#TSTMMU,D5!‰BGE„FNDTSEG1‡GO�CHECK�NEXT�ENTRY FNDTSEG4:‰MOVE.L�D0,D5‹THERE�ISN'T$‰ADD.L‚#2,(A7)ˆTAKE�NOT�FOUND�RETURN FNDTSEG5:‰RTS‰ENDéé«N=/*=/*†M68XXX.FNDUSEM.AF=/*,=/* Chain file to assemble M68XXX.FNDUSEM.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.FNDUSEM.LS=/*=/IFC \1ƒ=ARG�M68XXX.FNDUSEM.LS=/ENDIF=/*3=ASM M68XXX.FNDUSEM.SA,M68XXX.FNDUSEM.RO,\1;MRZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.UST.EQ=/*}=/*=ENDéé éééé´‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.UST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.UST.EQ‰LIST‰PAGE9FNDUSEM‚IDNT‚5,1ƒ68xxx�TRAP�0--FIND�USER�SEMAPHORE�IN�UST*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*†FNDUSEM‚--‚REV�1.01‚3/3/80ƒ(HLD6)*-*ˆPURPOSE:‚FIND�ENTRY�IN�USER�SEMAPHORE�TABLE!*�LOOKS�IN�UST�FOR�MATCHING�ENTRY6*�IF�FOUND�-�RETURNS�POINTER�TO�UST�ENTRY�FOR�MATCHING*›ENTRY7*�IF�NOT�FOUND�-�RETURNS�POINTER�TO�UNUSED�ENTRY�IN�UST!*ŸPOINTER�=�0�IF�NO�ROOM�IN�TABLE*?*ˆENTRY:�A0�=�SEMAPHORE�NAME�--�IF�0,�FIND�ANY�ENTRY,�THIS�TASK1*�A4�=�ADDR�OF�TCB�(TASK�NAME�AND�SESSION�IN�TCB)*9*ˆEXIT:‚RTS�TO�PCƒD0�=�ENTRY�#�OF�MATCHING�ENTRY�IN�TABLE*›A0�=�SEMAPHORE�NAME7*�RTS�TO�PC+2�D0�=�ENTRY�#�OF�1ST�UNUSED�ENTRY�IN�TABLE,*›D1�=�ENTRY�#�OF�SEMAPHORE�ENTRY�(IF�FOUND)&*–D2�=�UPDATED�COUNT�OF�ENTRIES�IN�UST,*›(REPLACES�USTCENT�IF�UNUSED�ENTRY�IS�USED)+*’OR‚D0�=�0�IF�NO�SPACE�IS�AVAILABLE�IN�UST***ˆREGISTERS�USED:‚01234567 *—D�******—A�*****ˆCODE�IS�RE-ENTRANT*ˆNO�SUBROUTINES�CALLED$*ˆUST�TABLE�CHECKED�BUT�NOT�MODIFIED**‰SECTION�LEVEL02* ‰XDEF„FNDUSEM‰XDEF„SBFNDSEM ‰XREF„KILLER ‰XREF.S‚USTBEG‰PAGE SBFNDSEM:FNDUSEM:‰CLR.LƒD2‰CLEAR�FOR�SHORT�LOAD%‰CLR.LƒD3‰CLEAR�UNUSED�ENTRY�REGISTER*‰CLR.LƒD1‰CLEAR�SEMAPHORE�POINTER�REGISTER.‰MOVE.L‚USTBEG,A1�PNTR�TO�USER�SEMAPHORE�TABLE  **ˆGET�READY�TO�SEARCH�TABLE* ‰MOVE.L‚A1,D4‰DOES�TABLE�EXIST?‰BEQ.SƒFNDUNOR‡BRANCH�IF�NO (‰MOVE.WƒUSTCENT(A1),D2…CURRENT�#�ENTRIES$‰CMP.WƒUSTMENT(A1),D2ˆIS�CURR�=�MAX?‰BEQ.SƒFNDUSM1ŠYES ‰ADD.Wƒ#1,D2 FNDUSM1:‰MOVE.L‚D2,D4ŽPUT�COUNT�IN�BOTH(‰MOVE.L‚#USTENTRY,D0‡OFFSET�TO�1ST�ENTRY  **‡CHECK�ONE�UST�ENTRY;*‡D0�=�OFFSET�TO�CURR�ENTRY�D1�=�ENTRY�#�OF�SEMAPHORE�ENTRY2*‡D2�=�COUNT�OF�ENTRIES…D3�=�ENTRY�#�OF�1ST�UNUSED&*‡D4�=�TABLE�INDEXŠA0�=�SEMAPHORE�NAME½XÆQ'*‡A1�=�ADDR�OF�CURRENT�UST‚A2�=�SCRATCH* FNDUSM2:‰TST.WƒUSTUCNT(A1,D0)‰BNE.SƒFNDUSM4  **ˆEMPTY�ENTRY�-�SAVE�FIRST�ONE.* ‰TST.LƒD3ˆHAVE�WE�SAVED�ONE‰BNE.SƒFNDUSM5ƒYES !‰MOVE.L‚D0,D3‰SAVE�UNUSED�ENTRY�#‰CMP.Lƒ#1,D4…IS�THIS�LAST�ENTRY‰BEQ.SƒFNDUSM5ƒYES +‰MOVE.W‚USTCENT(A1),D2‚NO�-�KEEP�ORIG�VALUE‰BRA.SƒFNDUSM5  *!*…GOOD�ENTRY�--�SEE�IF�IT�MATCHES* FNDUSM4:$‰CMP.L‚#0,A0‡IS�SEMAPHORE�NAME�=�0�?0‰BEQ.S‚FNDUSM4A„FIND�ANY�SEMAPHORE�FOR�THI S�TASK 0‰CMP.L‚USTSNAME(A1,D0),A0‚COMPARE�SEMAPHORE�NAME‰BNE.S‚FNDUSM5 FNDUSM4A:‰MOVE.L�TCBSESSN(A4),A2+‰CMP.L‚USTSESSN(A1,D0),A2‚COMPARE�SESSION�#‰BNE.SƒFNDUSM5 ‰MOVE.L�TCBNAME(A4),A2,‰CMP.L‚USTTNAME(A1,D0),A2‚COMPARE�TASK�NAMES‰BEQ.S‚FNDUSM8 )‰TST.W‚USTUCNT(A1,D0)„IS�THIS�A�SEMAPHORE‰BMI.S‚FNDUSM5‰NO &‰MOVE.L‚D0,D1ˆSAVE�SEMAPHORE�ENTRY�#‰* FNDUSM5:‰ADD.Lƒ#USTEL,D0'‰SUB.Wƒ#1,D4‰DECREMENT�COUNT�OF�ENTRIES(‰BNE…FNDUSM2‡GO�BACK�TO�CHECK�NEXT�ENTRY  **ƒNO�MATCHING�ENTRY�FOUND* '‰ADD.L‚#2,(A7)†INCREMENT�RETURN�ADDRESS#‰TST.L‚D3‹IS�THERE�AN�UNUSED�ENTRY?‰BNE.S‚FNDUSM7 FNDUNOR:‰CLR.LƒD0‰NO�UNUSED�ENTRY ‰CLR.LƒD2‰RTS�RETURN�-�TABLE�IS�FULL  FNDUSM7:&‰MOVE.L‚D3,D0„ENTRY�#�FOR�UNUSED�ENTRY!‰RTS�RETURN�-�WITH�UNUSED�ENTRY�#  **‰FOUND�ENTRY�IN�TABLE* FNDUSM8:0‰MOVE.L‚USTSNAME(A1,D0),A0„RETURN�SEMAPHORE�NAME‰RTS�RETURN�-�FOUND�MATCH‰ENDéé=/*=/*†M68XXX.GETTCB.AF=/*+=/* Chain file to assemble M68XXX.GETTCB.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.GETTCB.LS=/*=/IFC \1ƒ=ARG�M68XXX.GETTCB.LS=/ENDIF=/*1=ASM M68XXX.GETTCB.SA,M68XXX.GETTCB.RO,\1;MRZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDééééééÎ�page�bound)!‰BNE.S…GOT_BEŽthen�go�to�not_tcb; (‰MOVE.L„D0,A0�AO�<==�potential_tcb_addr; -‰PEA‡GOT_BE(PC)Šmake�bus�errors�go�to�got_be;‰MOVE.W„#'BE',-(A7) (‰CMP.L…#'!TCB',(A0)ˆif�((A0)�<>�#'!TCB')"‰BNE.S…NOT_TCB�then�go�to�not_tcb; 5‰CMP.L…TCBSESSN(A0),D1…if�(session_number�(A0)�<>�D1)"‰BNE.S…NOT_TCB�then�go�to�not_tcb; GOT_TCB:,‰ADDQ.L„#6,A7�pop�bus�error�stuff�off�stack;‰BRA.S…GETTCB9�go�to�gettcb9; NOT_TCB:,‰ADDQ.L„#6,A7�pop�bus�error�stuff�off�stack; GOT_BE:&‰ADD.L…#2,(A7)�indicate�tcb�not�found;*¦and�go�to�gettcb9;  *,*†GIVE�UP�EXCLUSIVE�ACCESS�TO�'TCB�ALL'�LIST* GETTCB9:‰IFNE„MULTPROC ‰TR0.VƒSEMTCB‰ENDC ‰RTS‹DONE‰ENDééééé=/*=/*†M68XXX.GTDTIM.AF=/*+=/* Chain file to assemble M68XXX.GTDTIM.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.GTDTIM.LS=/*=/IFC \1ƒ=ARG�M68XXX.GTDTIM.LS=/ENDIF=/*1=ASM M68XXX.GTDTIM.SA,M68XXX.GTDTIM.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDéééééé ð‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE2GTDTIMƒIDNT„5,1ƒ68xxx�DIRECTIVE--GET�DATE�AND�TIME*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*******************#*‡*‚G�T�D�T�I�M„*ƒGET�DATE�AND�TIME*‡*‚REV�1.00ƒHLD6**‡*‚11/12/79‡**‡********************1*†THIS�ROUTINE�RETURNS�DATE�AND�TIME�TO�REQUESTOR***‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A4�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�ORDINAL�DATE�(4�BYTES)*—4�-�TIME�(MILLISECONDS)**‹EXIT�:�D0�HAS�RETURN�CODE*’D0=�0…GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE**‰SECTION�LEVEL04* ‰XDEF„GTDTIM ‰XREF.S‚DATE‰PAGE**…GET�DATE�AND�TIME* GTDTIM: ˆTR0.RDTIMˆMOVE.LƒDATE,D0 ˆCMP.L„#24*60*60*1000,D1ˆBCS.S„GTDTIM3 ˆSUB.L„#24*60*60*1000,D1 ˆADD.L„#1,D0 GTDTIM3:'ˆMOVEM.L‚D0-D1,(A4)„SAVE�IN�PARAM�BLOCK ˆEXIT…SUBˆENDéééù?=/*=/*†M68XXX.GTTASKID.AF=/*-=/* Chain file to assemble M68XXX.GTTASKID.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.GTTASKID.LS=/*=/IFC \1ƒ=ARG�M68XXX.GTTASKID.LS=/ENDIF=/*5=ASM M68XXX.GTTASKID.SA,M68XXX.GTTASKID.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDéééé éét'M68XXX GTTASKIDSAQqqGTTNAME AF  qqGTTNAME SA))?qqINIT AF22qqINIT SA;,T >qqKILLER AF••qqKILLER SAžž.qqLOGPHY AF§§qqLOGPHY SA°° ‡qqPAGEALOCAFÁÁqqPAGEALOCSAÊÊ.qqPAGEFREEAFûûqqPAGEFREESAêqqPAUSE AFqqPAUSE SA&&-qqPOWRFAILAF//qqPOWRFAILSA882qqPSTATE AFAAqqPSTATE SAJJ dqqPVSEM SA[[ïqq‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE+GTTASKIDƒIDNT‚5,1„68xxx�TRAP�1--GET�TASK�ID*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*!*ƒGTTASKIDˆREV�1.00„7/25/84„(MSL)*(*ƒGET�TASK�ID�FROM�NAME�&�SESSION�NUMBER*'*ˆENTRY:‚A4‚POINTS�TO�8�BYTE�DATA�TABLE*�(A4)�4�BYTE�TASK�NAME*Ž4(A4)�4�BYTE�SESSION�NUMBER*�A6‚REQUESTOR'S�TCB�ADDRESS***ˆEXIT:'*�SUCCESS�(REQUESTOR�A�REAL-TIME�TASK):*˜A0�=�TARGET�TCB�ADDRESS/*˜A1�=�SESSION�NUMBER�(RESERVED�FOR�FUTURE�USE)*+*�SUCCESS�(REQUESTOR�NOT�A�REAL-TIME�TASK):*˜A0�=‚(A4)�ORIGINAL�TASKNAME$*˜A1�=�4(A4)�ORIGINAL�SESSION�NUMBER* *�FAILURE:*•TCBD0�=�RTCDTASK"*�(3�-�TARGET�TASK�DOES�NOT�EXIST)** *’01234567* USES REGISTERS D ***�A�**„*ŠA6�=�REQUESTOR'S�TCB*‰SECTION�LEVEL02*‰XDEF„GTTASKID‰PAGE*"*ˆCall�the�TRAP�#0�GETTCB�routine.* GTTASKID:‰TR0.GETTCB�(A4) ‰BRA.S…GTTID_01–Branch�if�found.*‰EXIT†RTCDTASK–Bad�target�task.  *!*ˆIf�(requestor�=�real-time�task)*ˆthen�(return�tcb_address);3*ˆelse�(return�original�taskname�&�session�number);* GTTID_01:9‰BTSTW…#TSKARTIM,TCBATTR(A6)‰If�(caller�=�real-time�task)‰BEQ.S…GTTID_02 *°then�do;+‰MOVE.L„A0,TCBA0(A6)”TCBA0�<==�tcb�address;.‰MOVE.L„D1,TCBA1(A6)”TCBA1�<==�session�number;‰EXIT†SUB›end;* GTTID_02: *°else�do;1‰MOVE.L„(A4),TCBA0(A6)’TCBA0�<==�taskname�(orig);3‰MOVE.L„4(A4),TCBA1(A6)‘TCBA1�<==�session�#�(orig);‰EXIT†SUB›end; ‰ENDéR =/*=/*†M68XXX.GTTNAME.AF=/*,=/* Chain file to assemble M68XXX.GTTNAME.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.GTTNAME.LS=/*=/IFC \1ƒ=ARG�M68XXX.GTTNAME.LS=/ENDIF=/*3=ASM M68XXX.GTTNAME.SA,M68XXX.GTTNAME.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDéééééé‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE*GTTNAMEƒIDNT‚5,1„68xxx�TRAP�1--GET�TASK�ID*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.* *ƒGTTNAME‰REV�1.00„7/25/84„(MSL)**ƒGET�TASKNAME�FROM�TASKID*9*ˆENTRY:‚A4‚POINTS�TO�8�BYTE�DATA�TABLE�CONTAINING�TASKID*�A6‚REQUESTOR'S�TCB�ADDRESS***ˆEXIT: *�SUCCESS:*˜A0�=�TARGET�TASKNAME!*˜A1�=�TARGET�TASK�SESSION�NUMBER* *�FAILURE:*•TCBD0�=�RTCDTASK"*�(3�-�TARGET�TASK�DOES�NOT�EXIST)** *’01234567* USES REGISTERS D*�A’A6�=�REQUESTOR'S�TCB*‰SECTION�LEVEL02* ‰XDEF„GTTNAME‰PAGE*ˆOnce�we�have�gotten�here,!*ˆthe�trap�#1�handler�has�already&*ˆgotten�a�pointer�to�the�target�task. &*ˆ(If�the�client�gave�us�a�bad�taskid,+*ˆthen�the�trap�#1�handler�discovered�this,&*ˆand�returned�the�proper�error�code.) .*ˆTherefore,�all�that�is�left�for�us�to�do�is:*7*�tcbao�(client_tcb_ptr)�<==�tcb_name�(target_tcb_ptr);:*�tcba1�(client_tcb_ptr)�<==�tcb_session�(target_tcb_ptr);*�exit�(subroutine�exit);* GTTNAME:‰MOVE.L„TCBNAME(A5),TCBA0(A6)‰MOVE.L„TCBSESSN(A5),TCBA1(A6) ‰EXIT†SUB‰ENDé é!@=/*=/*†M68XXX.INIT.AF=/*)=/* Chain file to assemble M68XXX.INIT.SA=/*:=/* If no output argument is specified for the listing the-=/* chain file will default to M68XXX.INIT.LS=/*=/IFC \1ƒ=ARG�M68XXX.INIT.LS=/ENDIF=/*+=ASM M68XXX.INIT.SA,M68XXX.INIT.RO,\1;RZ=75=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.PANEL.EQ=/*ƒ9995.&.GST.EQ=/*ƒ9995.&.UST.EQ=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.MAP.EQ=/*ƒ9995.&.IOV.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.UDR.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDééééé***ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.PANEL.EQ*ˆINCLUDEƒ9995.&.GST.EQ*ˆINCLUDEƒ9995.&.UST.EQ*ˆINCLUDEƒ9995.&.TRACE.EQ*ˆINCLUDEƒ9995.&.MAP.EQ*ˆINCLUDEƒ9995.&.IOV.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINCLUDEƒ9995.&.UDR.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.TST.EQŠINCLUDE�9995.&.PANEL.EQŠINCLUDE�9995.&.GST.EQŠINCLUDE�9995.&.UST.EQŠINCLUDE�9995.&.TRACE.EQŠINCLUDE�9995.&.MAP.EQŠINCLUDE�9995.&.IOV.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.UDR.EQŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGE INIT†IDNTƒ5,1�SYSTEM�INITIALIZER*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆSYSTEM�INITIALIZER**ˆEXECUTES�WHEN�IPL�CHUNK�IS�IN**,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesH*…________‚_____________‚_______________________________________________:*†12/�7/84�SJFŒAdded�initialization�of�LAST_MMU_INT_LEVEL.C*†12/23/83�Mark�Lanus…Re-wrote�memory�initialization�routine�to�fix.*žbug�in�"hole"�processing�(and�several�more).***‰PAGE ŠXDEFƒKILLER*ŠXREFƒCRASHSAV ŠXREFƒENDMEMT ŠXREFƒMEMTABL  ŠXREF.S�ADEFTYPŠXREF.S�ASNTBLŠXREF.S�BKG_ACTIVEŠXREF.S�BKG_HEADŠXREF.S�BKG_TAIL ŠXREF.S�CCBHDŠXREF.S�CURR_ASNŠXREF.S�ENDSYSPŠXREF.S�EXCSTACKŠXREF.S�GSTBEGŠXREF.S�IOVCTBGN ŠXREF.S�LAMŠXREF.S�LAST_MMU_INT_LEVELŠXREF.S�MACSTRCŠXREF.S�MAPBEGŠXREF.S�MIDNIGHT ŠXREF.S�NSEŠXREF.S�NOTLAM ŠXREF.S�PANELŠXREF.S�PATBEGŠXREF.S�READYHDŠXREF.S�SDEFTYPŠXREF.S�SEMENDŠXREF.S�SEMLIST ŠXREF.S�TCBHDŠXREF.S�TDEFTYP ŠXREF.S�TIATŠXREF.S�TIME_LEFTŠXREF.S�TRACEBEGŠXREF.S�TRACFLAGŠXREF.S�UDEFTYPŠXREF.S�UDRBEGŠXREF.S�USTBEGŠXREF.S�VCTUBGNŠPAGE* *„REFERENCES�TO�INITDATA�SEGMENT* ŠSECTION�8 ŠXREFƒASNŠXREFƒDISPATCH ŠXREFƒEEND ŠXREFƒESTACK ŠXREFƒESTART ŠXREFƒGSTSIZ ŠXREFƒIOVSIZ,3g<MD<LGT6\6d/l=t>|@„*Œ0”=œQ¤#¬U´Y¼)ÄIÌSÔVÜ/ä<ìNôAüPT 6P2 ŠXREFƒMEMTYPA ŠXREFƒMEMTYPS ŠXREFƒMEMTYPT ŠXREFƒMEMTYPUŠXREFƒPAGESIZE ŠXREFƒPANELA ŠXREFƒPATSIZ ŠXREFƒRDYHEAD ŠXREFƒSMEMHI ŠXREFƒSMEMLO ŠXREFƒTCBHEAD ŠXREFƒTRCFLAG ŠXREFƒTRCSIZ ŠXREFƒUDRSIZ ŠXREFƒUSTSIZŠXREFƒWHERLOAD**(*ˆEXPECT�THE�FIRST�16�BYTES�TO�DISAPPEAR*(START…MOVE.L�#$400,A7‹LOAD�STACK�POINTER.ŠMOVE.L�D0,$3FCŒBE�SURE�MEMORY�CAN�BE�ACCESSED*$*ˆCLEAR�MEMORY�THROUGH�END�OF�SYSPAR*2ŠLEA„CRASHSAV,A0ˆSTART�WHERE�USEABLE�MEMORY�STARTS(ŠMOVE.L�#ENDSYSP,D6ˆEND�AT�END�OF�SYSPAR$ŠSUB.L‚A0,D6ŽCOUNT�OF�BYTES�TO�CLEAR#ŠADD.L‚#255,D6ŒCLEAR�TO�END�OF�PAGEŠCLR.B‚D6‘EVEN�PAGE�BOUNDRYŠBSR„TBLCLRBŒCLEAR�MEMORY*'ŠMOVE.L�ESTACK(PC),A7†LOAD�SYSTEM�STACK/ŠMOVE.L�A7,EXCSTACKˆSAVE�STACK�POINTER�FOR�EXEC$ŠMOVE.L�$24,MACSTRCˆSET�MACSTRAC�NOW*,*‡FIND�OUT�IF�PANEL�EXISTS�-�PUT�'BF'�IN�LED*)ŠMOVE.L�PANELA(PC),A1†PANEL�ADDRESS�TO�A1!ŠMOVE.L�A1,PANEL‹SAVE�IT�FOR�EXEC ŠBEQ.S‚PANELBEŒGO�ON�IF�NO�PANEL(ŠLEA„PANELBE(PC),A0…GO�HERE�ON�BUS�ERROR"ŠMOVE.L�A0,$8ŽSET�BUS�ERROR�VECTOR+ŠMOVE.W�#$80,FPLEDST(A1)ƒTEST�FOR�BUS�ERROR ŠMOVE.W�#$BF,D1ŒWANT�'BF'�IN�LEDŠBSR„PANELEDD‹GO�LIGHT�IT�UP ŠBRA.S‚MOVE2LOŒGO�TO�MOVE�MEMORY*1PANELBEƒMOVE.L�#CRASHSAV,PANEL„SET�PANEL�TO�DUMMY'ŠMOVE.L�EXCSTACK,A7ˆRESET�STACK�POINTERŠPAGE*/*†MOVE�ALL�OF�OS�TO�LOWER�MEMORY�IF�APPROPRIATE*3MOVE2LOƒMOVE.L�WHERLOAD(PC),D1„WHERE�ARE�WE�LOADED?ŠBEQ.S‚VECTINIT‹BRANCH�IF�AT�0'ŠMOVE.L�ESTART(PC),A3†'MOVE�TO'�ADDRESS!ŠMOVE.L�D1,A2Ž'MOVE�FROM'�ADDRESS'ŠLEA„ENDMEMT(PC),A4…END�OF�MEMORY�TABLE#ŠADD.L‚#$800,A4‹EXTRA�FOR�MINI-TCBS&ŠLEA„VECTINIT(PC),A0„WHERE�TO�GO�LATER%ŠSUB.L‚A2,A0ŽSUBTRACT�START�OF�'FROM'ŠADD.L‚A3,A0ŽADD�START�OF�'TO'(ŠLEA„MOVDONE(PC),A1…GO�HERE�ON�BUS�ERRORŠMOVE.L�A1,$8ŽBUS�ERROR�VECTOR*#MOVEALLƒMOVE.L�(A2)+,(A3)+ˆMOVE�ALLŠCMP.L‚A2,A4ŽFINISHED?ŠBGT„MOVEALLŒBRANCH�IF�NO ŠADD.L‚#6,A7*'MOVDONEƒJMP„(A0)�CONTINUE�IN�OTHER�COPYŠPAGE**ˆSET�UP�VECTORS*;VECTINIT‚MOVE.L�ESTART(PC),A2†START�SEARCH�AT�START�OF�EXEC&ŠMOVE.L�#'!VCT',D0‰D0=!VCT�FOR�COMPARE&ŠLEA„$200(A2),A0ˆEND�OF�SEARCH�ADDRESS-VECTSRCH‚CMP.L‚(A2)+,D0‹IS�THIS�VECTOR�TABLE?ŠBEQ.S‚VECTSETŒBRANCH�IF�FOUND%ŠSUB.L‚#2,A2ŽWANT�TO�CHECK�EVERY�WORD$ŠCMP.L‚A0,A2ŽSHOULD�SEARCH�CONTINUE?ŠBNE„VECTSRCH‹BRANCH�IF�YES#ŠBSR„KILLER�NO�VECTOR�TABLE�--�QUIT*&VECTSETƒLEA„0,A3�ADDRESS�OF�VECTOR�#�0*ŠMOVE.L�(A2)+,A4‹ADDRESS�OF�COMINT�ROUTINE;ŠMOVE.L�A4,VCTUBGN‰SAVE�COMINT�ADDRESS�FOR�VECTOR�USE�TABLEŠCLR.L‚D6‘SET�1ST�VECTOR�#ŠCLR.L‚D5‘CLEAR�FOR�SHORT�LOAD+ŠMOVE.L�D5,A5ŽINITIALIZE�VECTOR�SET�ADDRESS+ŠTST.B‚(A2)�SHOULD�VECTOR�0�BE�INITIALIZED?ŠBEQ.S‚VECTENTŒBRANCH�IF�YESŠMOVE.W�#2,D6Ž1ST�VECTOR�TO�SETŠLEA„8,A3�ADDRESS�OF�VECTOR�#�2*,VECTENTƒMOVE.L�(A2)+,D0‹GET�NEXT�TABLE�ENTRY,ŠBNE.S‚VECTENT2‹BRANCH�IF�NOT�END�OF�ENTRIES+ŠMOVE.W�#300,D5ŒUSE�HI�#�FOR�VECTOR�COMPARE ŠBRA.S‚VECTCMPŒBRANCH�TO�COMPARE-VECTENT2‚ROL.L‚#8,D0ŽPUT�VECTOR�#�IN�BITS�0-7ŠMOVE.B�D0,D5ŽSAVE�VECTOR�#ŠLSR.L‚#8,D0ŽRESTORE�ADDRESS+ŠCMP.L‚#1,D0ŽSHOULD�THIS�VECTOR� BE�SKIPPED?ŠBNE.S‚VECTCMPŒBRANCH�IF�NOŠNEG.L‚D0‘NEGATIVE=SKIP�FLAG*&VECTCMPƒCMP.W‚D6,D5ŽCOMPARE�VECTOR�#'S$ŠBMI„VECTENTŒBRANCH�TO�GET�NEW�ENTRY*ŠBNE.S‚VECTSTOR‹BRANCH�IF�NOT�AT�ENTRY�YET ŠMOVE.L�D0,A5ŽNEW�VECTOR�ADDRESS*"VECTSTOR‚MOVE.L�A5,D1ŽTEST�ADDRESS+ŠBMI.S‚VECTINC2‹IF�NEG�-�SKIP�VECTOR�CHANGE$ŠBNE.S‚VECTINC1‹BRANCH�IF�ADDRESS�OK+ŠMOVE.L�A4,(A3)+‹USE�COMINT�ROUTINE�ADDRESS%ŠBRA.S‚VECTINC3‹BRANCH�TO�INCR�VECTOR*0VECTINC1‚MOVE.L�A5,(A3)+‹STORE�ADDRESS�IN�VECTOR%ŠADD.L‚#2,A5ŽINCREMENT�VECTOR�ADDRESSŠBRA.S‚VECTINC3*6VECTINC2‚LEA„4(A3),A3‹DO�NOT�SET�VECTOR�-�INCR�ADDRESS'VECTINC3‚ADD.L‚#1,D6ŽINCREMENT�VECTOR�#ŠCMP.L‚#$400,A3‹END�OF�VECTORS?ŠBNE„VECTCMPŒBRANCH�IF�NO*/*‡SET�BUS�ERROR�--�IN�CASE�ERROR�OCCURS�IN�INIT*)ŠPEA„KILLER(PC)‰PUT�ERROR�RETURN�ON�STACK)ŠMOVE.W�#'BE',-(A7)ˆBUS�ERROR�RETURN�FLAGŠPAGE*J*‚Initialize�SYSPAR�parameters�for�background�and�CALL_GUARDED�processing.*>ŠMOVE.L�#0,BKG_HEADˆInitialize�background�queue�to�empty:‚headDŠMOVE.L�#BKG_HEAD,BKG_TAIL�ptr�is�0�and�tail�ptr�points�to�head�ptr.8ŠSF…BKG_ACTIVE‰Initialize�ACTIVE�flag�to�false�since�the*§background�isn't�running. *5*‚Initialize�LAST_MMU_INT_LEVEL�to�interrupt�level�0.*+ŠCLR„LAST_MMU_INT_LEVEL�Set�the�level�to�0.  *+*‡START�PROCESSING�MEMORY�PARTITION�ENTRIES* ŠBSR„IMEM ŠPAGE**†SET�DEFAULT�MEMORY�TYPES*1ŠMOVE.B�MEMTYPA(PC),ADEFTYP�DEFAULT�TYPE�FOR�ASQS1ŠMOVE.B�MEMTYPT(PC),TDEFTYP�DEFAULT�TYPE�FOR�TCBS9ŠMOVE.W�MEMTYPS(PC),SDEFTYP�DEFAULT�TYPE�FOR�SYSTEM�TASKS7ŠMOVE.W�MEMTYPU(PC),UDEFTYP�DEFAULT�TYPE�FOR�USER�TASKS**ˆPUT�TASKS�ON�LISTS*,ŠMOVE.L�TCBHEAD(PC),TCBHD‚POINT�TO�FIRST�TCB0ŠMOVE.L�RDYHEAD(PC),READYHD�POINT�TO�FIRST�READY * *ˆSEMAPHORES*,SEMS†LEA„SEMLIST,A1‰START�OF�EXEC�SEMAPHORES+INITSEMƒMOVE.W�#1,(A1)ŒSET�COUNT�FIELD�TO�1 ŠCLR.L‚2(A1)ŽCLEAR�ADDRESS�FIELD(ŠADD.L‚#6,A1ŽINCREMENT�TO�NEXT�SEMAPHORE$ŠCMP.L‚#SEMEND,A1‰END�OF�SEMAPHORES? ŠBLT.S‚INITSEMŒBRANCH�BACK�IF�NO**ˆINITIALIZE�MMU* ŠXREFƒINITMMU3ŠBSR„INITMMUŒINVOKE�CONFIGURATION-DEPENDENT�ROUTINE**‰ADDRESS�SPACE�PARAMETERS*$ŠMOVE.L�PAGESIZE(PC),D0„GET�PAGESIZE:ŠIF…�THEN.S‰If�the�pagesize�specified�by�the�Sysgen�is%�MOVE.L�#256,D0Œzero,�default�to�256.ŠENDIƒ* ŠSUB.L‚#1,D0ŽNOTLAM�=�PAGESIZE-1$ŠMOVE.L�D0,NOTLAMŠNOTLAM�INTO�SYSPAR-ŠMOVE.L�#$FFFFFFFF,LAM…PREPARE�TO�COMPUTE�LAM$ŠSUB.L‚D0,LAM�LAM�=�$FFFFFFFF-NOTLAM*ŠCLR.L‚ASNTBL�SET�FOR�NO�ASNTBLŠMOVE.L�ASN,D2�ASNTBL�DESIRED?ŠBEQ.S‚ASN99ŽBRANCH�IF�NO.ŠMOVE.L�#2,A0Ž512�BYTES�FOR�127�ADDRESS�SPACES(ŠMOVE.L�#T0PAGAL,D0ˆPAGEALOC�DIRECTIVE�#ŠTRAPƒ#0‘EXEC�CALL"ŠBRA.S‚ASN10ŽBRANCH�IF�GOOD�RETURN!ŠBSR„KILLER�CRASH�IF�ERROR�RETURN4ASN10…MOVE.L�A0,ASNTBLŠSAVE�ASNTBL�ADDRESS�IN�SYSPAR/ŠBSR„TBLCLR�CLEAR�ADDRESS�SPACE�TABLE�TO�ZEROESŠMOVE.L�#'!ASN',(A0)‡EYECATCHERASN996ŠMOVE.B�#$FF,CURR_ASN†RESET�CURR_ASN�MEMORY�COMPONENT.**ˆBUILD�GLOBAL�SEGMENT�TABLE*ABLDGST„CLR.L‚GSTBEG‹SET�SYSPAR�ADDRESS�TO�0�IN�CASE�NO�GST�NEEDEDŠMOVE.L�GSTSIZ(PC),D2†NEED�GST?ŠBEQ.S‚BLDUST�BRANCH�IF�NO)ŠMOVE.L�D2,A0ŽPUT�SIZE�IN�A0�FOR�PAGEALOC(ŠMOVE.L�#T0PAGAL,D0ˆPAGEALOC‚DIRECTIVE�#ŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDGST01‹BRANCH�IF�GOOD�RETURN!ŠBSR„KILLER�CRASH�IF�ERROR�RETURN3BLDGST01‚MOVE.L�A0,GSTBEGŠSAVE�GST�ADDRESS�FOR�EXECŠBSR„TBLCLR�CLEAR�GST�TO�ZEROESŠMOVE.L�#'!GST',(A0)‡EYECATCHER-ŠMOVE.W�#1,GSTNSEG(A0)…NUMBER�OF�GST�SEGMENTS)ŠMOVE.W�D2,GSTNPAGE(A0)„GST�LENGTH�TO�GSTŠLSL.L‚#8,D2ŽLENGTH�IN�BYTES2ŠSUB.L‚#GSTENTRY,D2‡SUBTRACT�LENGTH�OF�HEADER�INFO&ŠDIVUƒ#GSTEL,D2ŠDIVIDE�BY�ENTRY�LENGTH-ŠMOVE.W�D2,GSTMENT(A0)…SAVE�MAXIMUM�#�ENTRIES)ŠLEA„GSTENTRY(A0),A2„ADDRESS�OF�1ST�ENTRY%ŠMOVE.L�A2,GSTFENT(A0)…SAVE�IN�HEADER**ˆBUILD�USER�SEMAPHORE�TABLE*9BLDUST„CLR.L‚USTBEG�CLEAR�UST�ADDRESS�IN�CASE�NONE�NEEDEDŠMOVE.L�USTSIZ(PC),D2†NEED�UST?ŠBEQ.S‚BLDVTU�BRANCH�IF�NO(ŠMOVE.L�D2,A0ŽPUT�SIZE�IN�A0�FOR�PAGALOC,ŠMOVE.L�#T0PAGAL,D0ˆDIRECTIVE�#�FOR�PAGE ALOCŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDUST01‹BRANCH�IF�GOOD�RETURNŠBSR„KILLER�CRASH�IF�NO�MEMORY3BLDUST01‚MOVE.L�A0,USTBEGŠSAVE�UST�ADDRESS�FOR�EXECŠBSR„TBLCLR�CLEAR�UST�TO�ZEROES*ŠMOVE.L�#'!UST',UST(A0)„EYE�CATCHER�TO�UST)ŠMOVE.W�#1,USTNSEG(A0)…ONLY�1�UST�SEGMENT(ŠMOVE.W�D2,USTNPAGE(A0)„#�PAGES�IN�TABLE#ŠLSL.L‚#8,D2ŽCONVERT�PAGES�TO�BYTES(ŠSUB.L‚#USTENTRY,D2‡SUBRTACT�HEADER�SIZE&ŠDIVUƒ#USTEL,D2ŠDIVIDE�BY�ENTRY�LENGTH-ŠMOVE.W�D2,USTMENT(A0)…SAVE�MAXIMUM�#�ENTRIES(ŠLEA„USTENTRY(A0),A2„FIRST�ENTRY�ADDRESS(ŠMOVE.L�A2,USTFENT(A0)…SAVE�IT�IN�HEADER**ˆBUILD�VECTOR�USE�TABLE*+BLDVTU„MOVE.L�#1,A0ŽSIZE�IS�ALWAYS�ONE�PAGE,ŠMOVE.L�#T0PAGAL,D0ˆDIRECTIVE�#�FOR�PAGEALOCŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDVTU01‹BRANCH�IF�GOOD�RETURN$ŠBSR„KILLER�CRASH�IF�NO�MEMORY�FOUND�THEN.SŒBRANCH�IF�NO#�MOVE.L�#1,D2‹PAT�minimum�size�is�1ŠENDI)ŠMOVE.L�D2,A0ŽPUT�SIZE�IN�A0�FOR�PAGEALOC(ŠMOVE.L�#T0PAGAL,D0ˆPAGEALOC‚DIRECTIVE�#ŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDPAT01‹BRANCH�IF�GOOD�RETURN!ŠBSR„KILLER�CRASH�IF�ERROR�RETURN3BLDPAT01‚MOVE.L�A0,PATBEGŠSAVE�PAT�ADDRESS�FOR�EXECŠBSR„TBLCLR�CLEAR�PAT�TO�ZEROESŠMOVE.L�#'!PAT',(A0)‡EYECATCHER#ŠLSL.W‚#8,D2ŽCONVERT�PAGES�TO�BYTES&ŠMOVE.L�D2,PATTSIZ(A0)…SAVE�TABLE�SIZEŠLEA„0(A0,D2),A2ˆTOP�OF�TABLE)ŠLEA„PATENTRY(A0),A1„ADDRESS�OF�1ST�ENTRYŠLEA„PATFHDR-PATNEXT(A0),A4:BLDPAT04‚MOVE.L�A1,PATNEXT(A4)…SAVE�ENTRY�ADDRESS�IN�CHAIN)ŠMOVE.L�#-1,PATTCB(A1)…FLAG�ENTRY�AS�FREE(ŠMOVE.L�A1,A4ŽSAVE�CURRENT�ENTRY�ADDRESS%ŠLEA„PATEL(A1),A1‡POSSIBLE�NEXT�ENTRY#ŠLEA„PATEL(A1),A3‡POINT�BEYOND�NEXTŠCMP.L‚A3,A2ŽWILL�IT�FIT?#ŠBCC„BLDPAT04‹YES,�GO�INITIALIZE�IT E*�Insert�two�dummy�entries�into�the�PAT�list.‚These�entries�will�haveG*ƒthe�maximum�possible�delta�and�will�cause�and�exec�procedure�to�fire.F*ƒThe�code�for�the�exec�procedure�is�contained�in�the�RMS.SA�module�ofE*ƒRMS68K.‚These�nodes�are�placed�on�the�PAT�so�that�the�PAT�list�willE*ƒnever�be�empty,�simplifying�PAT�processing�in�many�places.‚When�theG*ƒPAT�node�fires,�the�associated�code�in�the�RMS.SA�module�gets�controlG*ƒand�this�code�simply�places�a�dummy�PAT�node�(like�the�one�that�firedE*ƒto�get�us�here)�at�the�very�end�of�the�PAT�list.‚This�scheduling�ofI*ƒthe�dummy�PAT�node�is�a�special�case�in�that�it�does�not�use�the�normal/*ƒPAT�node�schedule�routine�PAT_SCHED_NEW_NODE. �#'DUMY'�DO.S �LEA‚2(A3),A3ŠENDW ŠLEA„4(A3),A3$*£A3�now�contains�the�address�of�the"*£exec�code�to�reschedule�the�node"ŠBSR.S‚BLDPAT12‹Build�a�dummy�node;ŠMOVE.L�A4,PATHDR(A0)†Link�the�dummy�node�into�the�PAT�list4ŠMOVE.L�A4,A2ŽSave�addr�of�this�node�for�future�link1ŠBSR.S‚BLDPAT12‹Build�an�identical�2nd�dummy�node/ŠMOVE.L�A4,PATNEXT(A2)…Link�2nd�node�behind�1stŠMOVE.L�#PATBIGDELTA,NSE>ŠMOVE.L�#PATBIGDELTA,TIME_LEFT�Make�TIME_LEFT�as�big�as�we�canŠCLR.L‚MIDNIGHT.ŠBRA.S‚BLDUDR�Done�with�PAT�stuff�all�together*$* Subroutine to build dummy PAT node:BLDPAT12‚MOVE.L�PATFHDR(A0),A4…A4�points�to�free�PAT�entry@ŠMOVE.L�PATNEXT(A4),PATFHDR(A0)�Unlink�this�entry�from�free�list*£Initialize�PAT�entriesŠCLR.L‚PATNEXT(A4)$ŠCLR.L‚PATTCB(A4)‰Indicate�exec�node5ŠMOVE.L�#PATBIGDELTA,PATDELTA(A4)�Make�delta�very�bigŠCLR.L‚PATINTV(A4)'ŠMOVE.L�A3,PATASR(A4)†Execution�address(ŠCLR.W‚PATOPT(A4)‰Options�-�not�periodic4ŠMOVE.L�#PATDUMMYID,PATARID(A4)�Plug�in�the�dummy�ID4ŠMOVE.W�#$FFFF-$0700,PATILVL(A4)�Interrupt�level�=�0ŠRTS *$*ˆBUILD�USER�DEFINED�DIRECTIVE�TABLE*9BLDUDR„CLR.L‚UDRBEG�CLEAR�UDR�ADDRESS�IN�CASE�NONE�NEEDEDŠMOVE.L�UDRSIZ(PC),D2†NEED�UDR?ŠBEQ.S‚BLDTRACŒBRANCH�IF�NO(ŠMOVE.L�D2,A0ŽPUT�SIZE�IN�A0�FOR�PAGALOC,ŠMOVE.L�#T0PAGAL,D0ˆDIRECTIVE�#�FOR�PAGEALOCŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDUDR01‹BRANCH�IF�GOOD�RETURNŠBSR„KILLER�CRASH�IF�NO�MEMORY3BLDUDR01‚MOVE.L�A0,UDRBEGŠSAVE�UST�ADDRESS�FOR�EXECŠBSR„TBLCLR�CLEAR�UST�TO�ZEROES*ŠMOVE.L�#'!UDR',UDR(A0)„EYE�CATCHER�TO�UDR#ŠLSL.L‚#8,D2ŽCONVERT�PAGES�TO�BYTES(ŠSUB.L‚#UDRENTRY,D2‡SUBRTACT�HEADER�SIZE(ŠDIVUƒ#UDRESIZ,D2ˆDIVIDE�BY�ENTRY�LENGTH,ŠMOVE.W�D2,UDRCNT(A0)†SAVE�MAXIMUM�#�ENTRIES**ˆBUILD‚TRACE�TABLE*DBLDTRACƒCLR.L‚TRACEBEG‰CLEAR�SYSPAR�ADDRESS�IN�CASE�TRACE�NOT�NEEDED'ŠMOVE.L�TRCSIZ(PC),D2†NEED�TRACE�TABLE?ŠBEQ.S‚BLDTIATŒBRANCH�IF�NO)ŠMOVE.L�D2,A0ŽPUT�SIZE�IN�A0�FOR�PAGEALOC(ŠMOVE.L�#T0PAGAL,D0ˆPAGEALOC�DIRECTIVE�#ŠTRAPƒ#0‘EXEC�CALL%ŠBRA.S‚BLDTRC01‹BRANCH�IF�GOOD�RETURNŠBSR„KILLER�CRASH�IF�NO�MEMORY1BLDTRC01‚MOVE.L�A0,TRACEBEGˆSAVE�ADDRESS�FOR�EXEC'ŠBSR„TBLCLR�CLEAR�TRACE�TABLE�TO�ZEROES+ŠLEA„TRCENTRS(A0),A2„ADDRESS�OF�FIRST�ENTRYŠMOVE.L�A2,(A0)ŒSAVE�IN�HEADER#ŠLSL.L‚#8,D2ŽCONVERT�BYTES�TO�PAGES(ŠSUB.L‚#TRCENTRS,D2‡SUBTRACT�HEADER�SIZE'ŠDIVUƒ#TRCENTSZ,D2‡DIVIDE�BY�ENTRY�SIZE)ŠMULUƒ#TRCENTSZ,D2‡MULTIPLY�BY�ENTRY�SIZE$ŠADD.L‚A2,D2ŽADD�ENTRY�START�ADDRESS4ŠMOVE.L�D2,TRCLNG(A0)†SAVE�END�ADDRESS�OF�LAST�ENTRY*,ŠMOVE.W�TRCFLAG(PC),TRACFLAG�SET�TRACE�FLAGS*#*ˆTRAP�INSTRUCTION�ASSIGNMENT�TABLE*>BLDTIATƒMOVE.L�#$01010000,TIAT„SET�TRAP�0�AND�1�'USED�BY�EXEC'ŠPAGE*0*…INITIALIZE�CONFIGURATION-DEPENDENT�I/O�DEVICES* ŠXREFƒINITIO)ŠBSR„INITIO�SUBROUTINE�WILL�INITIALIZE�IO*1*ˆCREATE�TASK�CONTROL�BLOCKS�FOR�ROM�BASED�SYSTEM**LOOKTCBƒTST.L‚TCBHDŽDO�TCBS�ALREADY�EXIST?%ŠBNE„BLDTCB99‹BRANCH�IF�YES�-�NOT�ROM'ŠCLR.L‚READYHDŒBE�SURE�READYHD�IS�CLEAR4ŠLEA„ENDMEMT(PC),A3…START�SEARCH�AT�END�OF�MEM�TABLEŠLEA„$200(A3),A1ˆEND�OF�SEARCH,ŠMOVE.L�#'!TCB',D0‰INITIALIZE�D0�FOR�COMPARE'LOOKT2„CMP.L‚(A3),D0ŒLOOK�FOR�MINI�TCBSŠBEQ.S‚BLDTCBSŒBRANCH�IF�FOUND!ŠADD.L‚#2,A3ŽCHECK�ALL�EVEN�BYTESŠCMP.L‚A3,A1ŽEND�OF�SEARCH?ŠBNE„LOOKT2�LOOP�BACKŠBSR„KILLER�QUIT�IF�NO�TCBS*)BLDTCBSƒLEA„4(A3),A3‹START�OF�TABLE�ENTRY!ŠMOVE.B�18(A3),D4ŠTASK�PRIORITIESŠLSL.W‚#8,D4ŽUSE�PRIORITY�TWICE)ŠMOVE.B�18(A3),D4ŠFOR�BOTH�CURR�AND�LIMIT ŠSWAPƒD4‘PRIORITIES�TO�UPPER�1/2!ŠMOVE.W�22(A3),D4ŠTASK�ATTRIBUTESŠMOVE.L�24(A3),D5ŠENTRY�ADDRESS ŠCLR.L‚D6ŠMOVE.W�16(A3),D6ŠUSER�NUMBER,ŠMOVE.W�#$8000,D7ŠOPTIONS�-�MONITOR�SUPPLIED1ŠMOVE.L�#T0CRTCB,D0ˆDIRECTIVE�NUMBER�-�CREATE�TCBŠTRAPƒ#0‘EXEC�DIRECTIVE$ŠBRA.S‚BLDTCB2ŒBRANCH�IF�GOOD�RETURN&ŠBSR.S‚KILLER�QUIT�IF�REQUEST�REJECTED*#BLDTCB2ƒMOVE.W�20(A3),D2ŠSTATE�WORD#ŠMOVE.W�D2,TCBSTATE(A5)„SAVE�IN�TCB!ŠBTSTƒ#TSK2NRDY,D2‡ON�READY�LIST?ŠBEQ.S‚BLDTCB3ŒBRANCH�IF�NO3ŠMOVE.L�READYHD,TCBREADY(A5)�LINK�TO�PREVIOUS�ENTRY ŠMOVE.L�A5,READYHD‰ADD�NEW�ENTRY* *ˆPUT�TST�INFO�INTO�TCB*+BLDTCB3ƒLEA„28(A3),A2ŠSTART�OF�TST�MMU�INFO)ŠMOVE.L�#SEGMENTS-1,D0…MAX�#�SEGMENTS�-�1ŠCLR.L‚D1‘CLEAR�FOR�COUNT%BLDTCB4ƒTST.W‚6(A2)ŽTEST�SEGMENT�TYPE#ŠBEQ.S‚BLDTCB6ŒBRANCH�IF�NO�SEGMENT$ŠADD.L‚#1,D1ŽCOUNT�SEGMENTS�EXISTING.BLDTCB6ƒLEA„8(A2),A2‹INCREMENT�TO�NEXT�SEGMENT*ŠDBRAƒD0,BLDTCB4‰DECREMENT�AND�BRANCH�BACK*$ŠLEA„28(A3),A3ŠSTART�OF�TST�MMU�INFO(ŠMOVE.L�TCBTST(A5),A4†ADDRESS�OF�NEW�TST.ŠMOVE.B�D1,TSTCSEGS(A4)„SAVE�ACTUAL�#�SEGMENTS,ŠLEA„TSTMMU(A4),A4†ADDRESS�OF�MMU�WITHIN�TST-ŠMOVE.L�#4*SEGMENTS-1,D0ƒ#�LONG�WORDS�TO�MOVE2BLDTCB8ƒMOVE.L�(A3)+,(A4)+ˆMOVE�MMU�AND�ATTRIBUTES(ŠDBRAƒD0,BLDTCB8‰CONTINUE�TILL�ALL�MOVEDŠCMP.L‚#'!TCB',(A3)‡MORE�TCB'S?ŠBEQ„BLDTCBSŒBRANCH�IF�YESBLDTCB99* *ˆSTART�TIMER* ŠXREFƒTIMERST3ŠBSR„TIMERSTŒINVOKE�CONFIGURATION-DEPENDENT�ROUTINE*(*ˆINDICATE�SYSTEM�RUNNING�ON�FRONT�PANEL*-FPGO†MOVE.L�EXCSTACK,A7ˆRESTORE�STACK�POINTER)ŠMOVE.W�#$C0,D1ŒWANT�'C0'�IN�PANEL�LIGHTS4ŠBSR.S‚PANELEDE‹SET�LIGHTS�-�ENABLE�READY/FAIL�LIGHT**‰GO�TO�EXEC�-�INIT�COMPLETE*:INITENDƒMOVE.L�DISPATCH(PC),-(A7)�ADDRESS�OF�START�OF�EXECŠRTS—GO�TO�EXEC*%*ƒKILLER�ROUTINE�--�ERROR�DURING�INIT*KILLER„PEA„(A6)�SAVE�REGISTER�6 ŠLEA„CRASHSAV,A6ˆCRASH�SAVE�AREA'ŠMOVE.L�4(A7),(A6)‰SAVE�PROGRAM�COUNTER%ŠMOVE.W�SR,4(A6)‹SAVE�STATUS�REGISTER0ŠDISABLE_INTERRUPTSˆBE�SURE�INTERRUPTS�INHIBITED ŠLEA„8(A6),A6‹REGISTER�SAVE�AREA-ŠMOVEM.L�D0-D7/A0-A5,(A6)‚SAVE�MOST�REGISTERS$ŠMOVE.L�(A7)+,56(A6)‡SAVE�REGISTER�6$ŠMOVE.L�A7,60(A6)ŠSAVE�STACK�POINTER'KILLOOPƒMOVE.W�#$A2,D1ŒWANT�'A2'�IN�LED/ŠBSR.S‚PANELEDE‹PUT�IT�THERE�-�ALLOW�FAIL�LIGHT4ŠBRA„KILLOOPŒLOOP�-�WAIT�FOR�SOMEONE�TO�DO�SOMETHINGŠPAGE* *ˆTABLE�CLEAR*'TBLCLR„MOVE.L�D2,D6ŽGET�LENGTH�IN�PAGESŠLSL.L‚#8,D6ŽLENGTH�IN�BYTES!TBLCLRBƒMOVE.L�D6,A6ŽLENGTH�IN�A6ŠADD.L‚A0,A6ŽEND�+�1�IN�A6$ŠCLR.L‚D6‘THE�ZERO�THAT�GET'S�STORED&TBLCLRLƒMOVE.L�D6,-(A6)‹STORE�ONE�WORDŠCMP.L‚A0,A6ŽDONE?&ŠBGT.S‚TBLCLRLŒBRANCH�BACK�IF�NOT�DONEŠRTS—GO�BACK�WHEN�DONE*#*ƒPANELEDE�--�ENABLE‚TTO�--�SET�LED$*ƒPANELEDD�--�DISABLE�TTO�--�SET�LED*-PANELEDE‚MOVE.W�#$10,D0ŒCLEAR�DISABLE�TTO�BIT&ŠBRA.S‚PANELD2ŒSKIP�AROUND�OTHER�ENTRY+PANELEDD‚MOVE.W�#$90,D0ŒSETƒDISABLE�TTO�BIT*PANELD2ƒNOT.B‚D1‘USE�COMPLEMENT�TO�SET�LEDŠROR.L‚#4,D1ŽSEPARATE�DIGITSŠOR.BƒD1,D0ŽPUT�MSD�IN�D0ŠMOVE.W�#$02,D1Œ'SET�LSD'�FLAGŠROL.L‚#4,D1ŽLSD�IN�D1!ŠMOVE.L�PANEL,A1‹ADDRESS�OF�PANEL'ŠLEA„FPLEDST(A1),A1…LED�STATUS�REGISTER+ŠMOVE.W�D1,(A1)ŒSET�LEAST�SIGNIFICANT�DIGITŠOR.Wƒ#$30,D1ŒSET�LATCH�BITSŠMOVE.W�D1,(A1)ŒLATCH�IT*ŠMOVE.W�D0,(A1)ŒSET�MOST�SIGNIFICANT�DIGITŠOR.Wƒ#$30,D0ŒSET�LATCH�BITSŠMOVE.W�D0,(A1)ŒLATCH�ITŠRTS +ŠTTL„INIT�MEMORY�PARTITIONS�-�DOCUMENTATIONŠPAGEN*********************************************************************************.***‚Name:‚IMEM�(initialize_memory_partitions).*** ***‚Function:A***ŠChecks�all�memory�locations�described�in�the�SYSGENed�MEMTBL.F***…Maps�out�any�"holes"�in�memory.‚Sets�up�FML�(free�memory�list)�andC***…FML_HEADER�(free�memory�list�header)�in�each�partition.‚Sets�upE***…MEMTBL�(memory�mapping�table)�immediately�after�the�FML_HEADER�in***…partition�zero.*** ***‚Inputs:H***…1.)‚Src_memtbl�(created�by�SYSGEN)�located�at�address�MEMTABL�within***ŠINITDAT�data�area.*** ***‚Outputs:I***…1.)‚Dest_memtbl�located�immediately�after�the�FML_HEADER�in�partition ***Šzero.G***…2.)‚MAPBEG�longword�in�SYSPAR�data�area.‚Points�to�the�dest_memtbl.***Š(Item�#1�above.)E***…3.)‚FML_HEADERs�for�all�RAM�memory�partitions.‚(Pointed�to�by�the***Šdest_memtbl.)@***…4.)‚FMLs�for�all�RAM�memory�partitions.‚(Pointed�to�by�their***ŠFML_HEADERs.)******‚Side�effects:C***…1.)‚All�registers�destroyed,�except�for�the�stack�pointer�(A7).)***…2.)‚Might�never�return�(call�KILLER).***H***‚Explanation:‚This�routine�is�basically�a�driver�for�initializing�theB***…memory�partitions.‚It�is�primarily�concerned�with�initializing I***…partition�zero.‚The�last�subroutine�call�(call�init_next_partitions),H***…handles�the�initialization�of�all�memory�partitions�except�partitionI***…zero.‚This�unique�handling�of�partition�zero�is�neccessary�due�to�theI***…fact�that�the�INIT�module�resides�in�a�portion�of�partition�zero�thatD***…will�later�be�used�by�the�system.‚We�obviously�cannot�clear�this ***…memory.***D***ŠThe�first�call�sets�up�the�neccessary�pointers�to�the�src_memtblF***…and�to�partition�zero.‚The�next�call�will�build�the�FML�(clear�anyE***…memory�not�in�the�INIT�module,�map�out�any�"holes"�in�memory,�andA***…set�up�the�FML�linked�list�describing�the�available�memory�inG***…partition�zero).‚If�the�first_node_ptr�is�returned�as�zero,�then�weF***…did�not�find�even�one�256�byte�block�of�available�memory.‚Since�weE***…need�at�least�one�block�in�partition�zero�for�the�MEMTBL,�this�is3***…obviously�a�fatal�error,�and�so�we�call�KILLER.***F***ŠNext�we�call�build_fml_header�to�build�the�FML_HEADER�in�partitionE***…zero.‚If�the�fml_header_ptr�is�returned�as�zero,�then�we�couldn'tC***…find�enough�memory�in�partition�zero�for�the�FML_HEADER�and�theG***…dest_memtbl,�so�we�cannot�continue,�and�therefore�must�call�KILLER.***@***ŠOtherwise,�we�set�our�dest_memtbl_ptr�to�point�to�the�memory@***…immediately�after�the�FML_HEADER�for�partition�zero,�and�setF***…the�MAPBEG�variable�in�SYSPAR�equal�to�this�value.‚Finally�we�callF***…build_ram_memtbl_entry�to�record�this�ram�partition�in�the�MEMTBL,D***…and�call�init_next_partitions�to�initialize�all�partitions�after***…partition�zero.***L****************************************************************************2ŠTTL„INIT�MEMORY�PARTITIONS�-�REGISTER�ASSIGNMENTSŠPAGEL**********************************************************************************…A0�=�src_memtbl_ptr;7***ŠPoints�to�the�"source"�MEMTBL�in�INITDAT�data�area.******…A1�=�dest_memtbl_ptr;<***ŠPoints�to�the�"destination"�MEMTBL�immediately�after�the!***ŠFML_HEADER�in�partition�zero.***+***…A2�=�temp_memtbl_ptr/previous_node_ptr;?***ŠShared�register.‚During�check_memmap_conflict�it�is�used�toB***Šstep�through�the�dest_memtbl�looking�for�conflicts�between�theB***Š"current"�RAM�partition�(pointed�to�by�the�src_memtbl_ptr)�andB***Šany�previously-defined�RAM�partitions�(pointed�to�by�the�temp_***Šmemtbl_ptr.)C***ŠDuring�build_fml�(and�its�subroutine�build_fml_node)�A2�is�used;***Što�point�to�the�"previous"�node�in�the�FML�linked�list.******…A3�=�first_node_ptr;0***ŠPoints�to�the�first�node�in�the�current�FML.******…A4�=�last_node_ptr;/***ŠPoints�to�the�last�node�in�the�current�FML.***&***…A5�=�clear_mem_ptr/fml_header_ptr;@***ŠShared�register.‚During�build_fml�(and�build_fml_node)�it�is<***Šused�to�point�to�the�next�memory�location�to�be�cleared.<***ŠDuring�all�the�other�routines�it�is�used�to�point�to�the***ŠFML_HEADER�block.***…A6�=�scratch;****** ***…D0�=�0;B***ŠUsed�for�zeroing�out�memory,�and�checking�if�address�registers***Šare�equal�to�zero.******…D1-D3�=�scratch;******…D4�=�start_of_part_ptr;:***ŠPoints�to�the�start�of�the�"current"�memory�partition.******…D5�=�end_of_part_ptr;8***ŠPoints�to�the�end�of�the�"current"�memory�partition.******…D6�=�bytes_cleared;>***ŠContains�a�count�of�the�number�of�the�bytes�cleared�in�the?***Š"current"�memory�partition.‚When�we�find�a�"hole"�in�memory@***Š(take�a�bus_error),�then�we�stop�incrementing�bytes_cleared.C***ŠThus�bytes_cleared�will�contain�a�count�of�the�number�of�"good"?***Šbytes�in�the�current�block�of�the�current�memory�partition.D***ŠThis�value�will�be�used�to�describe�the�ammount�of�"free"�memory***Šin�the�current�block.******…D7�=�fml_header_len;C***ŠContains�a�count�of�the�number�of�256�byte�blocks�neccessary�toA***Šdescribe�the�"current"�FML_HEADER.‚This�value�is�usually�one.@***ŠIt�was�made�into�a�variable�in�order�to�accommodate�the�caseA***Šwhere�the�FML_HEADER�(26�bytes)�and�the�dest_memtbl�("n"�*�10>***Šbytes)�requi red�more�than�one�256�byte�block.‚This�added�a<***Šcertain�ammount�of�complexity�to�the�algorityhms,�but�itA***Šremoved�the�rather�arbitrary�restriction�that�the�dest_memtblB***Šmust�be�limited�to�(256�-�26)�/�10�or�23�entries.‚(Dest_memtbl2***Šcould�only�describe�23�RAM�or�ROM�partitions.)***L****************************************************************************'ŠTTL„INIT�MEMORY�PARTITIONS�-�ALGORITHMŠPAGE#*init_memory_partitions: procedure;    *ˆcall�init_pointers;*ˆcall�build_fml;*ˆif�(first_node_ptr�=�0)*ˆthen�call�KILLER;*ˆcall�build_fml_header;*ˆif�(fml_header_ptr�=�0)*ˆthen�call�KILLER;;*ˆdest_memtbl_ptr�<==�fml_header_ptr�+�length�(fml_header);&*ˆSYSPAR�(MAPBEG)�<==�dest_memtbl_ptr;*ˆcall�build_ram_memtbl_entry;*ˆcall�init_next_partitions;  *end init_memory_partitions;ŠPAGE"ŠTTL„INIT�MEMORY�PARTITIONS�-�CODE*#*init_memory_partitions: procedure;*IMEM:**ˆcall�init_pointers;*ˆcall�build_fml;*ˆif�(first_node_ptr�=�0)*ˆthen�call�KILLER;* ŠBSR.S‚IPTRS ŠBSR„BFML ŠIF.LƒA3��D0�THEN.S �BSR„KILLERŠENDI **ˆcall�build_fml_header;*ˆif�(fml_header_ptr�=�0)*ˆthen�call�KILLER;;*ˆdest_memtbl_ptr�<==�fml_header_ptr�+�length�(fml_header);&*ˆSYSPAR�(MAPBEG)�<==�dest_memtbl_ptr;* ŠBSR„BFMLHEAD ŠIF.LƒA5��D0�THEN.S �BSR„KILLERŠENDI ŠLEA„FMLHDSZ(A5),A1 ŠMOVE.L�A1,MAPBEG **ˆcall�build_ram_memtbl_entry;*ˆcall�init_next_partitions;* ŠBSR„BRAMNODE ŠBSR.S‚INEXTMEM **end init_memory_partitions;*ŠRTS "ŠTTL„INIT�POINTERS�-�DOCUMENTATIONŠPAGEN********************************************************************************* ***…Name:‚IPTRS�(init_pointers):*** ***…Function:A***ŠInitializes�all�pointers�and�counters�for�initializing�memory***„partition�zero.*** ***…Inputs:1***ˆ1.)‚Src_memtbl�in�INITDAT�at�address�MEMTABL.*** ***…Outputs:***ˆ1.)‚A0�=�src_memtbl_ptr;***ˆ2.)‚A5�=�clear_mem_ptr;***ˆ3.)‚D0�=�0;***ˆ4.)‚D4�=�start_of_part_ptr;***ˆ5.)‚D5�=�end_of_part_ptr;***ˆ6.)‚D6�=�bytes_cleared;***ˆ7.)‚D7�=�fml_header_len;******…Side�effects:****ˆ1.)‚A2�(temp_memtbl_ptr)�is�destroyed.$***ˆ2.)‚D1�(scratch)�gets�destroyed.)***ˆ3.)‚Might�never�return�(call�KILLER).******…Explanation:***?***ŠFirst�we�initialize�D0�and�the�src_memtbl_ptr.‚If�the�firstI***…entry�in�the�src_memtbl�is�not�a�RAM�partition�whose�partition�number<***…is�zero,�then�we�cannot�continue,�and�so�we�call�KILLER.***E***ŠNext�we�initialize�fml_header_len�to�equal�the�number�of�256�byteG***…blocks�neccessary�to�contain�the�FML_HEADER�for�partition�zero,�andB***…one�entry�in�the�dest_memtbl�for�every�entry�in�the�src_memtbl9***…(including�the�last�entry�delimiting�the�src_memtbl).***D***ŠNow�we�initialize�the�end_of_part_ptr�to�point�to�the�"floor"�ofB***…the�MAPENDA�field�of�the�first�entry�in�the�src_memtbl.‚(Note:H***…throughout�these�algorithms�we�will�always�take�the�"ceiling"�of�theH***…start�of�the�partition,�and�the�"floor"�of�the�end�of�the�partition.K***…This�insures�that�all�partitions�start�and�end�on�a�256�byte�block,�andG***…also�that�we�only�grab�the�same�ammount�of�memory,�or�less,�that�is%***…described�within�the�src_memtbl.)***E***ŠNow,�if�the�exec�is�in�partition�zero,�then�the�start_of_part_ptrD***…points�to�the�next�256�byte�block�after�the�end�of�the�exec,�theJ***…clear_mem_ptr�points�to�the�next�256�byte�block�after�the�start�of�theH***…INIT�module,�and�bytes_cleared�gets�set�to�the�displacement�from�theI***…start�of�the�INIT�module�to�the�end�of�the�INITDAT�data�area�(also�onH***…a�256�byte�boundary).‚The�clear_mem_ptr�and�bytes_cleared�are�set�upF***…in�this�way�in�order�to�tell�the�build_fml�subroutine�that�we�haveG***…started�clearing�memory�at�the�location�pointed�to�by�clear_mem_ptr@***…and�we�have�already�cleared�bytes_cleared�locations.‚This�isI***…neccessary�because �we�wish�to�reclaim�the�memory�occupied�by�the�INITD***…module�as�free�memory�in�partition�zero,�but�we�obviously�cannotG***…clear�it�out�at�this�point�in�time.‚Thus�we�must�fake�out�build_fmlB***…into�thinking�that�we�have�already�cleared�the�INIT�portion�ofI***…partition�zero.‚Finally,�if�TCBHEAD�=�0,�(we�have�mini�TCBs�followingF***…the�src_memtbl),�then�we�increment�bytes_cleared�by�$800�to�insure)***…that�we�don't�zero�out�the�mini�TCBs.***D***ŠIf�the�exec�is�not�in�partition�zero,�then�we�set�both�start_of_G***…part_ptr�and�clear_mem_ptr�to�point�to�the�next�256�byte�page�after8***…the�SYSPAR�data�area,�and�set�bytes_cleared�to�zero.***B***ŠFinally,�if�the�start_of_part_ptr�and�end_of_part_ptr�describeF***…a�partition�that�does�not�contain�some�positive�ammount�of�memory,=***…then�we�obviously�cannot�continue,�and�so�we�call�KILLER.***L**************************************************************************** ŠTTL„INIT�POINTERS�-�ALGORITHMŠPAGE*init_pointers: procedure;   *ˆDO�<==�0;.*ˆsrc_memtbl_ptr�<==�addr�(INITDAT�(MEMTABL));0*ˆif�(MAPMTYP.MAPPART�(src_memtbl_ptr)�<>�$0000)*ˆthen�call�KILLER; *ˆfml_header_len�<==�0;%*ˆtemp_memtbl_ptr�<==�src_memtbl_ptr;7*ˆdo�until�(MAPMTYP.MAPPART�(temp_memtbl_ptr)�=�$FFFF);%*’fml_header_len�<==�fml_header_len�+*¥length�(dest_memtbl_entry);'*’temp_memtbl_ptr�<==�temp_memtbl_ptr�+*¦length�(src_memtbl_entry); *ˆend;C*ˆfml_header_len�<==�(length�(fml_header)�+�length�(memtbl_entry)�+,*œ(temp_memtbl_ptr�-�src_memtbl_ptr))�/�256; 7*ˆend_of_part_ptr�<==�floor�(MAPENDA�(src_memtbl_ptr));)*ˆif�(exec�is�in�partition�xero)�then�do;.*’start_of_part_ptr�<==�ceil�(INITDAT�(EEND));(*’clear_mem_ptr�<==�ceil�(addr�(START));5*’bytes_cleared�<==�ceil�(addr�(INITDAT�(ENDMEMT)))�-*¤clear_mem_ptr;*’if�(INITDAT�(TCBHEAD)�=�0).*’then�bytes_cleared�<==�bytes_cleared�+�$800;*ˆend; *ˆelse�do;7*’start_of_part_ptr�<==�ceil�(addr�(SYSPAR�(ENDSYSP)));&*’clear_mem_ptr�<==�start_of_part_ptr;*’bytes_cleared�<==�0;*ˆend; +*ˆif�(start_of_part_ptr�>=�end_of_part_ptr)*ˆthen�call�KILLER;  *end init_pointers; ŠTTL„INIT�POINTERS�-�CODEŠPAGE**init_pointers: procedure;* IPTRS:* *ˆD0�<==�0;.*ˆsrc_memtbl_ptr�<==�addr�(INITDAT�(MEMTABL));,*ˆif�(MAPMTYP.MAPPART�(src_memtbl_ptr)�<>�0)*ˆthen�call�KILLER;* ŠCLR.L‚D0 ŠLEA„MEMTABL(PC),A0 ŠIF.Wƒ(A0)�‹D0�THEN.S �BSR„KILLERŠENDI **ˆfml_header_len�<==�0;%*ˆtemp_memtbl_ptr�<==�src_memtbl_ptr;7*ˆdo�until�(MAPMTYP.MAPPART�(temp_memtbl_ptr)�=�$FFFF);%*’fml_header_len�<==�fml_header_len�+*¥length�(dest_memtbl_entry);'*’temp_memtbl_ptr�<==�temp_memtbl_ptr�+*¦length�(src_memtbl_entry);*ˆend;* ŠCLR.L‚D7 ŠLEA„(A0),A2 ŠREPEAT�ADD.L‚#MAPENTSZ,D7�LEA„12(A2),A2ŠUNTIL.W�(A2)Ž�#$FFFF *5*ˆfml_header_len�<==�ceil�(length�(fml_header_node)�+*¡fml_header_len�+$*¡length�(dest_memtbl_entry))�/�256;7*ˆend_of_part_ptr�<==�floor�(MAPENDA�(src_memtbl_ptr));*!ŠADD.L‚#(FMLHDSZ+MAPENTSZ+255),D7 ŠLSR.L‚#8,D7 ŠMOVE.L�MAPENDA(A0),D5 ŠCLR.B‚D5 *)*ˆif�(exec�is�in�partition�zero�then�do);.*’start_of_part_ptr�<==�ceil�(INITDAT�(EEND));(*’clear_mem_ptr�<==�ceil�(addr�(START));5*’bytes_cleared�<==�ceil�(addr�(INITDAT�(ENDMEMT)))�-*¤clear_mem_ptr;*’if�(INITDAT�(TCBHEAD)�=�0).*’then�bytes_cleared�<==�bytes_cleared�+�$800;*ˆend;**ŠMOVE.L�EEND(PC),D4ˆD4�<==�INITDAT�(EEND).8ŠIF.LƒD4�ˆD5�THEN.S†If�(exec_end�<�end_of_part_ptr),!*§Then�exec�is�in�partition�zero;�ADD.L‚#255,D4 �CLR.B‚D4 �LEA„255+START(PC),A5 �MOVE.L�A5,D1 �CLR.B‚D1 �MOVE.L�D1,A5 �LEA„255+ENDMEMT(PC),A6 �MOVE.L�A6,D6 �CLR.B‚D6 �SUB.L‚A5,D6 �IF.LƒTCBHEAD(PC)�„D0�THEN.S�ADD.L‚#$800,D6�ENDI * *ˆelse�do;7*’start_of_part_ptr�<==�ceil�(addr�(SYSPAR�(ENDSYSP)));&*’clear_mem_ptr�<==�start_of_part_ptr;*’bytes_cleared�<==�0;*ˆend;*�ELSE.S�MOVE.L�#ENDSYSP+255,D4  �CLR.B‚D4 �MOVE.L�D4,A5 �CLR.L‚D6ŠENDI *+*ˆif�(start_of_part_ptr�>=�end_of_part_ptr)*ˆthen�call�KILLER;*ŠIF.LƒD4��D5�THEN.S �BSR„KILLERŠENDI **end init_pointers;*ŠRTS )ŠTTL„INIT_NEXT_PARTITIONS�-�DOCUMENTATIONŠPAGEN*************************************************************************************…Name:‚INEXTMEM�(init_next_partitions):*** ***…Function:=***ŠInitializes�all�partitions�except�partition�zero.‚For�ROMH***„partitions,�we�make�an�entry�in�the�dest_memtbl.‚For�RAM�partitions,A***„we�insure�that�no�conflict�exists�with�a�previously-describedH***„partition,�build�the�FML,�build�the�FML_HEADER,�and�make�an�entry�in***„the�dest_memtbl.*** ***…Inputs:***ˆ1.)‚A0�=�src_memtbl_ptr;2***�(Points�to�the�first�entry�in�the�src_memtbl.)***ˆ2.)‚A1�=�dest_memtbl_ptr;3***�(Points�to�the�first�entry�in�the�dest_memtbl.)*** ***…Outputs:***ˆ1.)‚Dest_memtbl.#***ˆ2.)‚FML�for�all�RAM�partitions.+***ˆ3.)‚FML_HEADERs�for�all�RAM�partitions.******…Side�effects:B***ˆ1.)‚Most�registers�are�destroyed,�except�for�the�stack�pointer ***�(A7).******…Explanation:D***ŠWe�keep�looping�until�the�MAPMTYP�and�MAPPART�fields�of�the�nextH***…entry�in�the�src_memtbl�both�contain�$FF.‚(This�indicates�the�end�ofH***…the�memtbl.)‚When�we�see�the�end�of�the�src_memtbl,�then�we�write�an.***…end�entry�for�the�dest_memtbl,�and�return.***E***ŠFor�every�good�entry�in�the�src_memtbl�we�call�init_next_pointersG***…to�set�up�our�pointers�and�counters�for�this�memory�partition.‚ThenE***…if�the�MAPMTYP�field�of�the�src_memtbl�entry�=�$FF,�we�have�a�ROM4***…partition�and�so�we�call�build_rom_memtbl_entry.***8***ŠFor�every�RAM�entry�in�the�src_memtbl,�we�first�callG***…check_memmap_conflict�to�insure�that�the�current�RAM�partition�doesH***…not�conflict�in�any�way�with�a�previously-described�partition.‚ThereG***…are�three�possible�return�conditions�from�the�check_memmap_conflict***…subroutine:'***Š1.)‚A�fatal�conflict�was�detected�-;***�Execution�will�never�return�(check_memmap_conflict�will***�call�KILLER).@***Š2.)‚This�partition�is�an�alias�of�a�previous�partition�(both+***�partitions�start�at�the�same�address)�-;***�Execution�will�return,�and�the�got_alias_partition_flag***�will�be�set.+***Š3.)‚This�partition�is�a�new�partition�-;***�Execution�will�return,�and�the�got_alias_partition_flag***�will�be�reset.H***…Therefore,�if�execution�returns,�and�the�got_alias_partition_flag�is@***…set,�we�call�build_ram_memmap_entry�to�build�an�entry�in�the(***…dest_memtbl�for�the�alias�partition.***C***ŠIf�execution�returns�and�the�got_alias_partition_flag�is�reset,H***…then�we�call�build_fml�to�build�the�free�memory�list�for�the�new�RAMB***…partition.‚Then�if�the�previous_node_ptr�is�not�equal�to�zero,C***…build_fml�found�at�least�one�256�byte�page�of�memory�in�the�newI***…partition�and�so�we�call�build_fml_header�to�build�the�FML_HEADER�forA***…the�new�partition.‚Now,�since�this�is�not�partition�zero,�andH***…therefore�all�FML_HEADERs�require�only�one�256�byte�block�of�memory,A***…we�know�that�build_fml_header�successfully�found�room�for�theD***…FML_HEADER�and�so�we�can�call�build_ram_memtbl_entry�to�build�an7***…entry�for�the�current�partition�in�the�dest_memtbl.***=***ŠIf�the�previous_node_ptr�is�equal�to�zero,�then�build_fmlE***…did�not�find�even�one�256�byte�page�within�the�current�partition.=***…In�this�case�we�reset�the�dest_memtbl_ptr�to�point�to�theE***…previous�entry�within�the�dest_memtbl�(decrement�it�by�the�lengthC***…of�one�entry).‚This�has�the�effect�of�ignoring�the�current�null***…partition.***N****************************************************************************** %ŠTTL„INIT�NEXT�PARTITIONS�-�ALGORITHMŠPAGE!*init_next_partitions: procedure;    >*ˆdo�while�(MAPMTYP.MAPPART�(next�(src_memtbl_ptr))�<>�$FFFF);*’call�init_next_pointers;%*’if�(MAPMTYP�(src_memtbl_ptr)�=�$FF) #*’then�call�build_rom_memtbl_entry; *’else�do;*œcall�check_memmap_conflict;%*œif�(got_alias_partition_flag�=�set)#*œthen�call�build_ram_memmap_entry; *œelse�do;*¦call�build_fml;*¦if�(previous_node_ptr�=�0)*¦then�dest_memtbl_ptr�<==*«dest_memtbl_ptr�-*«length�(dest_memtbl_entry); *¦else�do;*°call�build_fml_header;*°call�build_ram_memtbl_entry;*¦end;*œend;*’end;*ˆend;4*ˆMAPTYP.MAPPART�(next�(dest_memtbl_ptr))�<==�$FFFF;  *end init_next_partitions; 'ŠTTL„INIT�NEXT�MEMORY�PARTITIONS�-�CODEŠPAGE*!*init_next_partitions: procedure;* INEXTMEM:*>*ˆdo�while�(MAPMTYP.MAPPART�(next�(src_memtbl_ptr))�<>�$FFFF);*’call�init_next_pointers;%*’if�(MAPMTYP�(src_memtbl_ptr)�=�$FF)#*’then�call�build_rom_memtbl_entry;* ŠWHILE.W�12(A0)��#$FFFF�DO.S �BSR.S‚INEXTPTRS �IF.Bƒ(A0)��#$FF�THEN.S �BSR„BROMNODE * *’else�do;*œcall�check_memmap_conflict;%*œif�(got_alias_partition_flag�=�set)#*œthen�call�build_ram_memtbl_entry;*�ELSE.S �BSR„CMEMCONF �TST.B‚D2�IF…�THEN.Sˆ “BSR„BRAMNODE * *›else�do;*¦call�build_fml;*¦if�(previous_node_ptr�<>�0)*¦then�dest_memtbl_ptr�<==*«dest_memtbl_ptr�-*«length�(dest_memtbl_entry); *¦else�do;*°call�build_fml_header;*°call�build_ram_memtbl_entry;*¦end;*œend;*’end;*ˆend;*“ELSE.S “BSR.S‚BFML “IF.LƒA2��D0�THEN.S“LEA„-MAPENTSZ(A1),A1“ELSE.S –BSR„BFMLHEAD –BSR„BRAMNODE“ENDI�ENDI�ENDIŠENDW *5*ˆMAPMTYP.MAPPART�(next�(dest_memtbl_ptr))�<==�$FFFF;*#ŠMOVE.W�#$FFFF,MAPMTYP+MAPENTSZ(A1) **end init_next_partitions;*ŠRTS 'ŠTTL„INIT�NEXT�POINTERS�-�DOCUMENTATIONŠPAGEM********************************************************************************)***…Name:‚INEXTPTRS�(init_next_pointers):*** ***…Function:C***ŠInitializes�all�pointers�and�counters�for�all�memory�partitions***…except�partition�zero.*** ***…Inputs:'***ˆ1.)‚A0�=�previous�(src_memtbl_ptr).(***ˆ2.)‚A1�=�previous�(dest_memtbl_ptr).*** ***…Outputs:&***ˆ1.)‚A0�=�current�(src_memtbl_ptr).'***ˆ2.)‚A1�=�current�(dest_memtbl_ptr).***ˆ3.)‚A5�=�clear_mem_ptr.***ˆ4.)‚D4�=�start_of_part_ptr.***ˆ5.)‚D5�=�end_of_part_ptr.***ˆ6.)‚D6�=�bytes_cleared.***ˆ7.)‚D7�=�fml_header_len.******…Side�effects:1***ˆ1.)‚Execution�might�not�return�(call�KILLER).******…Explanation:@***ŠFirst�we�set�the�fml_header_len�to�one�(any�partition�exceptG***…partition�zero�requires�only�one�256�byte�page�for�its�FML_HEADER),@***…and�advance�both�the�src_memtbl_ptr�and�the�dest_memtbl_ptr.***C***ŠNext�we�set�the�start_of_part_ptr�to�the�ceiling�of�the�MAPSTRAH***…field�in�the�src_memtbl,�and�the�end_of_part_ptr�to�the�floor�of�theH***…MAPENDA�field.‚(Note�that�we�always�align�our�partitions�on�256�byteI***…page�boundaries,�and�that�we�always�round�to�the�same�ammount�or�less+***…memory�as�described�in�the�src_memtbl).***D***ŠWe�then�set�clear_mem_ptr�to�the�value�of�start_of_part_ptr,�andE***…set�bytes_cleared�to�zero.‚(Thus�we�will�start�clearing�memory�atG***…the�start�of�the�current�partition.)‚Finally,�we�call�KILLER�if�theG***…current�partition�described�by�the�src_memtbl�does�not�contain�some'***…positive�number�of�pages�of�memory.***L**************************************************************************** #ŠTTL„INIT�NEXT�POINTERS�-�ALGORITHMŠPAGE*init_next_pointers: procedure;    *ˆfml_header_len�<==�1;@*ˆsrc_memtbl_ptr�<==�src_memtbl_ptr�+�length�(src_memtbl_entry);C*ˆdest_memtbl_ptr�<==�dest_memtbl_ptr�+�length�(dest_memtbl_entry); 8*ˆstart_of_part_ptr�<==�ceil�(MAPSTRA�(src_memtbl_ptr));7*ˆend_of_part_ptr�<==�floor�(MAPENDA�(src_memtbl_ptr));&*ˆclear_mem_ptr�<==�start_of_part_ptr;*ˆbytes_cleared�<==�0; +*ˆif�(start_of_part_ptr�>=�end_of_part_ptr)*ˆthen�call�KILLER;  *end init_next_pointers; ŠTTL„INIT�NEXT�POINTERS�-�CODEŠPAGE**init_next_pointers: procedure* INEXTPTRS: **ˆfml_header_len�<== �1;@*ˆsrc_memtbl_ptr�<==�src_memtbl_ptr�+�length�(src_memtbl_entry);C*ˆdest_memtbl_ptr�<==�dest_memtbl_ptr�+�length�(dest_memtbl_entry);* ŠMOVE.L�#1,D7 ŠLEA„12(A0),A0 ŠLEA„MAPENTSZ(A1),A1 *8*ˆstart_of_part_ptr�<==�ceil�(MAPSTRA�(src_memtbl_ptr));7*ˆend_of_part_ptr�<==�floor�(MAPENDA�(src_memtbl_ptr));&*ˆclear_mem_ptr�<==�start_of_part_ptr;*ˆbytes_cleared�<==�0;*ŠMOVE.L�MAPSTRA(A0),D4ŠADD.L‚#255,D4 ŠCLR.B‚D4 ŠMOVE.L�MAPENDA(A0),D5 ŠCLR.B‚D5 ŠMOVE.L�D4,A5 ŠCLR.L‚D6 *+*ˆif�(start_of_part_ptr�>=�end_of_part_ptr)*ˆthen�call�KILLER;*ŠIF.LƒD4��D5�THEN.S �BSR„KILLERŠENDI **end init_next_pointers;*ŠRTS ŠPAGEŠTTL„BUILDŽFML�-�DOCUMENTATIONL**********************************************************************************…Name:‚BFML�(build_fml):*** ***…Function:>***ŠBuild_fml�will�zero�out�memory�starting�at�clear_mem_ptr�+A***…bytes_cleared,�and�build�the�free�memory�list�to�describe�theF***…partition.‚It�also�detects�"holes"�in�the�partition,�and�describes3***…them�as�"used"�memory�within�the�current�block.*** ***…Inputs:***ˆ1.)‚A5�=�clear_mem_ptr.***ˆ2.)‚D4�=�end_of_part_ptr.***ˆ3.)‚D6�=�bytes_cleared.*** ***…Outputs:=***ˆ1.)‚A3�=�first_node_ptr�(from�subroutine�build_fml_node).***ˆ2.)‚A4�=�last_node_ptr."***ˆ3.)‚FML�for�current�partition.******…Side�effects:,***ˆ1.)‚A2�(previous_node_ptr)�is�destroyed.2***ˆ2.)‚A5�(clear_mem_ptr)�=�D5�(end_of_part_ptr)./***ˆ3.)‚D1,�D2,�and�D3�(scratch)�are�destroyed.(***ˆ4.)‚D6�(bytes_cleared)�is�destroyed.-***ˆ5.)‚Might�not�return�(might�call�KILLER).******…Explanation:B***ŠFirst�we�initialize�the�first_node_ptr�to�zero.‚This�tells�theH***…build_fml_node�subroutine�that�we�are�working�with�the�first�node�in ***…the�FML.***C**ŠNote�that�the�clear_next_node�and�build_last_fml_node�labels�canI***…both�be�jumped�to�by�the�code�for�handling�bus�errors�(build_fml_be).***B***ŠAt�clear_next_node�we�update�last_node_ptr�to�the�value�of�theC***…clear_mem_ptr.‚(Last_node_ptr�is�an�input�to�the�build_fml_nodeG***…subroutine�telling�him�where�the�"last"�or�current�node�is�located,H***…and�is�also�an�output�from�this�routine�telling�the�caller�where�theH***…last�node�in�the�FML�is�located.)‚We�also�increment�clear_mem_ptr�byE***…the�value�of�bytes_cleared.‚(This�is�neccessary�in�order�to�"skipD***…over"�and�not�initialize�the�INIT�code�when�building�the�FML�for***…partition�zero.***B***ŠNext�we�set�up�the�stack�so�that�any�bus�error�will�send�us�toI***…build_fml_be.‚This�is�the�code�that�will�be�used�for�mapping�over�any$***…"holes"�in�the�memory�partition.***D***ŠNow�we�loop�until�we�either�clear�the�rest�of�the�current�memoryF***…partition�(fall�through�the�loop),�or�find�a�hole�in�memory�(go�to***…build_fml_be).***D***ŠIf�we�do�clear�memory�to�the�end�of�the�current�partition�withinG***…this�loop,�we�must�pop�the�bus�error�vector�junk�off�the�stack,�andI***…calculate�the�value�of�bytes_cleared�(clear_mem_ptr�-�last_node_ptr).F***…This�calculation�is�neccessary�at�this�point�in�order�to�make�thisE***…case�(found�a�block�of�all�good�memory)�look�the�same�as�the�caseE***…where�we�found�some�good�memory�and�then�found�a�"hole"�in�memoryF***…(took�a�bus�error,�and�went�to�build_fml_be).‚In�that�case�we�willH***…"freeze"�bytes_cleared�to�the�value�of�clear_mem_ptr�-�last_node_ptrH***…in�order�to�remember�the�number�of�"good"�bytes�of�memory�within�theI***…current�block,�and�increment�clear_mem_ptr�(by�pages)�until�we�eitherG***…reach�the�end�of�the�partition,�or�we�find�some�more�"good"�memory.I***…Thus�at�that�point�our�current�block�will�be�framed�by�the�last_node_E***…ptr�(points�to�the�start�of�the�current�block),�the�clear_mem_ptrJ***…(point�to�the�end�of�the�current�block),�and�the�bytes_cleared�counterG***…which�holds�the�number�of�"good"�bytes�in�the�current�block�(or�theD***…number�of�bytes�of�free�memory).‚This�is�most�of�the�infor mation&***…needed�to�build�a�node�in�the�FML.***C***ŠFinally,�the�build_last_fml_node�label�will�build�a�node�in�the;***…FML�if�the�value�of�bytes_cleared�is�greater�than�zero.***M***************************************************************************** ŠTTL„BUILDŽFML�-�ALGORITHMŠPAGE*build_fml: procedure;    *ˆprevious_node_ptr�<==�0; *clear_next_node:*ˆD1,D2,D3�<==�0;"*ˆlast_node_ptr�<==�clear_mem_ptr;2*ˆclear_mem_ptr�<==�clear_mem_ptr�+�bytes_cleared;*ˆpush�addr�(build_fml_be); *ˆpush�'BE';-*ˆdo�until�(clear_mem_ptr�=�end_of_part_ptr);'*’four_longwords�(clear_mem_ptr)�<==�0;'*’clear_mem_ptr�<==�clear_mem_ptr�+�16;*ˆend;*ˆpop�bus_error�junk�off�stack;2*ˆbytes_cleared�<==�clear_mem_ptr�-�last_node_ptr; *build_last_fml_node:*ˆif�(bytes_cleared�>�0)*ˆthen�call�build_fml_entry;  *end build_fml; "ŠTTL„BUILDŽFREE�MEMORY�LIST�-�CODEŠPAGE**build_fml: procedure;*BFML: **ˆprevious_node_ptr�<==�0;* ŠSUB.L‚A2,A2 **clear_next_node:*ˆD1,D2,D3�<==�0;!*ˆlast_node_ptr�<==�clear_mem_ptr2*ˆclear_mem_ptr�<==�clear_mem_ptr�+�bytes_cleared;*ˆpush�addr�(build_fml_be); *ˆpush�'BE';* CNEXTNODE: ŠCLR.L‚D1 ŠCLR.L‚D2 ŠCLR.L‚D3 ŠLEA„(A5),A4 ŠLEA„(A5,D6.L),A5 ŠPEA„BFMLBE(PC) ŠMOVE.W�#'BE',-(A7) *-*ˆdo�until�(clear_mem_ptr�=�end_of_part_ptr);'*’four_longwords�(clear_mem_ptr)�<==�0;'*’clear_mem_ptr�<==�clear_mem_ptr�+�16;*ˆend;*ŠREPEAT�MOVEM.L�D0-D3,(A5)/�NOP”This�NOP�forces�the�execution�unit�to�wait)*§until�the�bus�interface�unit�is�done�on&*§a�68020,�in�case�we�get�a�bus�error.�LEA„16(A5),A5ŠUNTIL.L�A5��D5**ˆpop�bus_error�junk�off�stack;2*ˆbytes_cleared�<==�clear_mem_ptr�-�last_node_ptr;* ŠADD.L‚#6,A7 ŠMOVE.L�A5,D6 ŠSUB.L‚A4,D6 **build_last_fml_node:*ˆif�(bytes_cleared�>�0)*ˆthen�call�build_fml_entry;* BLASTNODE:ŠIF.LƒD6��D0�THEN.S�BSR.S‚BFMLNODEŠENDI **end build_fml;*ŠRTS 4ŠTTL„BUS�ERROR�WHILE�CLEARING�MEMORY�-�DOCUMENTATIONŠPAGEN************************************************************************************…Explanation:?***ŠThis�code�is�executed�if�we�encounter�a�hole�while�clearing@***…memory.‚Note�the�two�labels�build_fml_be�and�build_fml_be_x.G***…Execution�will�"go�to"�the�build_fml_be�label�if�a�bus�error�occursB***…when�clearing�memory�via�the�loop�in�the�build_fml�subroutine.F***…Likewise,�execution�will�"go�to"�the�build_fml_be_x�label�if�a�busH***…error�occurs�while�looking�at�the�top�of�each�page�of�memory�for�theF***…next�"good"�page.‚(i.e.,�This�block�of�code�contains�a�"bus�error"G***…loop.‚We�keep�going�to�build_fml_be_x�until�we�either�reach�the�end:***…of�the�current�partition,�or�find�some�"good"�memory.)***A***ŠFirst�we�calculate�bytes_cleared�to�be�the�difference�betweenG***…the�clear_mem_ptr�and�the�last_node_ptr.‚Then�we�call�KILLER�if�theJ***…bus�error�occurred�in�the�middle�of�a�page.‚(Bytes_cleared�is�not�on�a***…page�boundary.)***E***ŠOtherwise,�we�update�the�clear_mem_ptr�to�point�to�the�top�of�theG***…next�page�in�memory.‚If�we�are�at�the�end�of�the�current�partition,@***…then�we�go�to�the�build_last_fml_node�label�in�the�build_fml***…subroutine.***B***ŠIf�we�are�not�at�the�end�of�the�partition,�we�set�the�stack�upF***…so�that�a�bus�error�will�send�us�back�to�the�build_fml_be_x�label.G***…Then�we�attempt�to�write�into�the�memory�location�pointed�to�by�theF***…clear_mem_ptr.‚(If�a�bus�error�occurs,�then�execution�will�"go�to"I***…build_fml_be_x,�and�we�will�"loop"�until�we�run�out�of�memory�in�this+***…partition,�or�find�some�"good"�memory.)***D***ŠIf�we�"fall�through"�to�the�next�instruction�(find�a�good�memoryI***…location),�then�we�get�rid�of�the�bus�error�information�on�the�stack.J***…If�we�found�some�good�memory�in�the�current�block�(bytes_cleared�>�0),E***…then�we�call�build_fml_node�to�build�a�node�in�the�FML,�and�resetI***…bytes_cleared�to�zero.‚In�either�case�we�go�to  �clear_next_node�in�the***…build_fml�subroutine.***N****************************************************************************** 0ŠTTL„BUS�ERROR�WHILE�CLEARING�MEMORY�-�ALGORITHMŠPAGE*build_fml_be:2*ˆbytes_cleared�<==�clear_mem_ptr�-�last_node_ptr;$*ˆif�(mod�(bytes_cleared,�256)�<>�0)*ˆthen�call�KILLER; *build_fml_be_x:(*ˆclear_mem_ptr�<==�clear_mem_ptr�+�256;&*ˆif�(clear_mem_ptr�=�end_of_part_ptr)!*ˆthen�go�to�build_last_fml_node;*ˆpush�addr�(build_fml_be_x); *ˆpush�'BE';*ˆword�(clear_mem_ptr)�<==�0;*ˆpop�bus_error�junk�off�stack;!*ˆif�(bytes_cleared�>�0)�then�do;*’call�build_fml_node;*’bytes_cleared�<==�0;*ˆend;*ˆgo�to�clear_next_node;  *end build_fml_be; +ŠTTL„BUS�ERROR�WHILE�CLEARING�MEMORY�-�CODEŠPAGE**build_fml_be:*BFMLBE: *2*ˆbytes_cleared�<==�clear_mem_ptr�-�last_node_ptr;$*ˆif�(mod�(bytes_cleared,�256)�<>�0)*ˆthen�call�KILLER;* ŠMOVE.L�A5,D6 ŠSUB.L‚A4,D6 ŠIF.BƒD6��D0�THEN.S �BSR„KILLERŠENDI **build_fml_be_x:*BFMLBEX: *(*ˆclear_mem_ptr�<==�clear_mem_ptr�+�256;&*ˆif�(clear_mem_ptr�=�end_of_part_ptr)!*ˆthen�go�to�build_last_fml_node;*ŠLEA„256(A5),A5 ŠIF.LƒA5��D5�THEN.S�BRA„BLASTNODEŠENDI**ˆpush�addr�(build_fml_be_x); *ˆpush�'BE';*ˆword�(clear_mem_ptr)�<==�0;*ŠPEA„BFMLBEX(PC)ŠMOVE.W�#'BE',-(A7) ŠMOVE.W�D0,(A5)/ŠNOP—This�NOP�forces�the�execution�unit�to�wait)*§until�the�bus�interface�unit�is�done�on&*§a�68020,�in�case�we�get�a�bus�error. **ˆpop�bus_error�junk�off�stack;!*ˆif�(bytes_cleared�>�0)�then�do;*’call�build_fml_node;*’bytes_cleared�<==�0;*ˆend;*ˆgo�to�clear_next_node;* ŠADD.L‚#6,A7 ŠIF.LƒD6��D0�THEN.S�BSR.S‚BFMLNODE �CLR.L‚D6ŠENDI  ŠBRA„CNEXTNODE #ŠTTL„BUILDŽFML�NODE�-�DOCUMENTATIONŠPAGEL*******************************************************************************$***…Name:‚BFMLNODE�(build_fml_node):*** ***…Function:E***ŠBuilds�a�node�in�the�free�memory�list�(fills�in�the�fmlfp,�fmlbp,E***…fmlfree,�and�fmlused�fields),�and�links�this�node�to�any�previous***…nodes�in�the�FML.*** ***…Inputs:***ˆ1.)‚A2�=�previous_node_ptr.***ˆ2.)‚A4�=�last_node_ptr.***ˆ3.)‚A5�=�clear_mem_ptr.***ˆ4.)‚D6�=�bytes_cleared.*** ***…Outputs:8***ˆ1.)‚FML�node�(pointed�to�by�previous�last_node_ptr).D***ˆ2.)‚Fmlfp�of�previous�node�in�FML�(if�this�is�not�the�first�node***�in�the�FML).C***ˆ3.)‚A3�=�first_node_ptr�(if�this�is�the�first�node�in�the�FML).***ˆ4.)‚A4�=�previous_node_ptr.******…Side�effects:"***ˆ1.)‚D1�(scratch)�is�destroyed.******…Explanation:B***ŠFirst�we�set�up�the�fmlfp�and�fmlbp�links�in�the�current�node.E***…Next�we�set�up�fmlused�to�contain�the�number�of�pages�between�theA***…last_node_ptr�and�the�clear_mem_ptr�minus�the�number�of�pagesE***…described�by�the�bytes_cleared�counter.‚Then�we�set�fmlfree�equalG***…to�the�number�of�pages�described�by�the�bytes_cleared�counter.‚ThusJ***…the�sum�of�fmlused�and�fmlfree�is�equal�to�the�number�of�pages�between-***…the�last_node_ptr,�and�the�clear_mem_ptr.***E***ŠNow,�if�this�is�the�first�node�in�the�FML�(previous_node_ptr�=�0)K***…then�set�first_node_ptr�equal�to�last_node_ptr�and�thus�"remember"�thatG***…this�is�the�first�node.‚Otherwise,�update�the�fmlfp�of�the�previousF***…node�to�point�to�this�node.‚Finally�set�previous_node_ptr�equal�to>***…last_node_ptr�(and�thus�"remember"�this�node),�and�return.***M***************************************************************************** ŠTTL„BUILDŽFML�NODE�-�ALGORITHMŠPAGE*build_fml_node: procedure;    *ˆfmlfp�(last_node_ptr)�<==�0;.*ˆfmlbp�(last_node_ptr)�<==�previous_node_ptr;@*ˆfmlused�(last_node_ptr)�<==�((clear_mem_ptr�-�last_node_ptr)�-*¥(bytes_cleared))�/�256;2*ˆfmlfree�(last_node_ptr)�<==�bytes_cleared�/�256;*ˆif�(previous_node_ptr�=�0)(*ˆthen�first_node_ptr�<==�last_node_ptr;3*ˆelse�fmlfp�(previous_node_ptr)�<==�last_node_ptr;&*ˆ  previous_node_ptr�<==�last_node_ptr;  *end build_fml_node; ŠTTL„BUILDŽFML�NODE�-�CODEŠPAGE**build_fml_node:* BFMLNODE: **ˆfmlfp�(last_node_ptr)�<==�0;.*ˆfmlbp�(last_node_ptr)�<==�previous_node_ptr;*ŠCLR.L‚FMLFP(A4)ŠMOVE.L�A2,FMLBP(A4) **ˆfmlused�(last_node_ptr)�<==8*’(clear_mem_ptr�-�last_node_ptr�-�bytes_cleared)�/�256;2*ˆfmlfree�(last_node_ptr)�<==�bytes_cleared�/�256;* ŠMOVE.L�A5,D1 ŠSUB.L‚A4,D1 ŠSUB.L‚D6,D1 ŠLSR.L‚#8,D1ŠMOVE.L�D1,FMLUSED(A4) ŠMOVE.L�D6,D1 ŠLSR.L‚#8,D1ŠMOVE.L�D1,FMLFREE(A4) *ˆif�(previous_node_ptr�=�0)(*ˆthen�first_node_ptr�<==�last_node_ptr;3*ˆelse�fmlfp�(previous_node_ptr)�<==�last_node_ptr;*ŠIF.LƒA2��D0�THEN.S �LEA„(A4),A3 �ELSE.S�MOVE.L�A4,FMLFP(A2)ŠENDI *&*ˆprevious_node_ptr�<==�last_node_ptr;* ŠLEA„(A4),A2 **end build_fml_node;*ŠRTS %ŠTTL„BUILDŽFML�HEADER�-�DOCUMENTATIONŠPAGEM********************************************************************************&***…Name:‚BFMLHEAD‚(build_fml_header):*** ***…Function:E***ŠFinds�a�block�of�memory�to�contain�the�FML_HEADER�node�(in�eitherF***…high�or�low�memory),�and�builds�an�FML_HEADER�node�to�describe�the***…current�partition.*** ***…Inputs:D***ˆ1.)‚Src_memtbl_node�(tells�whether�the�FML_HEADER�belongs�in�low***�high�memory).***ˆ2.)‚A0�=�src_memtbl_ptr.***ˆ3.)‚D4�=�start_of_part_ptr.***ˆ4.)‚D5�=�end_of_part_ptr.*** ***…Outputs:9***ˆ1.)‚FML_HEADER�node�describing�the�current�partition.E***ˆ2.)‚Fml_header_ptr�(If�the�fml_header_ptr�=�0�upon�returning�from<***�this�routine,�then�we�couldn't�find�enough�memory�in�theA***�current�partition�for�the�FML_HEADER.‚This�is�meaningful�only***�for�partition�zero.)******…Side�effects:‚None.******…Explanation:D***ŠFirst�we�determine�whether�the�FML_HEADER�belongs�in�low�or�highB***…memory�and�call�the�appropriate�subroutine�to�return�to�us�theI***…corresponding�pointer.‚If�the�subroutine�returned�a�non-zero�pointer,G***…then�it�found�enough�memory�in�the�current�partition�to�contain�theF***…FML_HEADER�(it�found�at�least�fml_header_len�pages),�and�so�we�may%***…continue�to�build�the�FML_HEADER.***?***ŠWe�set�lowfree,�stravail,�and�endavail�to�the�values�of�theH***…first_node_ptr,�start_of_part_ptr,�and�end_of_part_ptr�respectively.E***…We�move�the�MAPMTYP�and�MAPPART�fields�from�the�src_memtbl�to�the7***…FML_HEADER�node,�and�set�up�the�semaphore�counters.***M***************************************************************************** !ŠTTL„BUILDŽFML�HEADER�-�ALGORITHMŠPAGE*build_fml_header: procedure;    '*ˆif�(fml_header�belongs�in�low�memory)#*ˆthen�call�get_fml_header_ptr_low;$*ˆelse�call�get_fml_header_ptr_high; #*ˆif�(fml_header_ptr�<>�0)�then�do;.*’lowfree�(fml_header_ptr)�<==�first_node_ptr;2*’stravail�(fml_header_ptr)�<==�start_of_part_ptr;0*’endavail�(fml_header_ptr)�<==�end_of_part_ptr; 8*’memtype�(fml_header_ptr)�<==�MAPMTYP�(src_memtbl_ptr);8*’mempart�(fml_header_ptr)�<==�MAPPART�(src_memtbl_ptr); "*’semfrmem�(fml_header_ptr)�<==�1;$*’semfrmem+2�(fml_header_ptr)�<==�0;"*’semwtmem�(fml_header_ptr)�<==�0;$*’semwtmem+2�(fml_header_ptr)�<==�0;*ˆend;  *end build_fml_header; ŠTTL„BUILDŽFML�HEADER�-�CODEŠPAGE**build_fml_header: procedure;* BFMLHEAD: *'*ˆif�(fml_header�belongs�in�low�memory)#*ˆthen�call�get_fml_header_ptr_low;$*ˆelse�call�get_fml_header_ptr_high;*:ŠBTSTƒ#0,10(A0)ŠIf�(src_memtbl_node�(byte_10�(bit_0))�=�0)7ŠIF…�THEN.SŒthen�fml_header�belongs�in�HIGH�memory; 6�BSR.S‚GFMLPTRH‹else�fml_header�belongs�in�LOW�memory; �ELSE.S�BSR.S‚GFMLPTRLŠENDI *#*ˆif�(fml_header_ptr�<>�0)�then�do;.*’lowfree�(fml_header_ptr)�<==�first_node_ptr;2*’stravail�(fml_header_ptr)�<==�start_of_part_ptr;0*’endavail�(fml_header_ptr)�<==�end_of_part_ptr;*ŠIF.LƒA5��D0�T! HEN.S�MOVE.L�A3,LOWFREE(A5)�MOVE.L�D4,STRAVAIL(A5)�MOVE.L�D5,ENDAVAIL(A5) *8*’memtype�(fml_header_ptr)�<==�mapmtyp�(src_memtbl_ptr);8*’mempart�(fml_header_ptr)�<==�mappart�(src_memtbl_ptr);*�MOVE.W�MAPMTYP(A0),MEMTYPE(A5) *"*’semfrmem�(fml_header_ptr)�<==�1;$*’semfrmem+2�(fml_header_ptr)�<==�0;"*’semwtmem�(fml_header_ptr)�<==�0;$*’semwtmem+2�(fml_header_ptr)�<==�0;*ˆend;*�MOVE.W�#1,SEMFRMEM(A5)�CLR.L‚SEMFRMEM+2(A5)�CLR.W‚SEMWTMEM(A5)�CLR.L‚SEMWTMEM+2(A5)ŠENDI **end build_fml_header;*ŠRTS 0ŠTTL„GET�FML�HEADER�POINTER�HIGH�-�DOCUMENTATIONŠPAGEN*********************************************************************************-***…Name:‚GFMLPTRH�(get_fml_header_ptr_high):*** ***…Function::***ŠThis�subroutine�returns�a�pointer�to�a�block�of�memoryI***…fml_header_len�pages�long�in�the�current�partition.‚This�block�is�theE***…highest�addressed�block�in�the�current�partition�that�is�at�leastI***…fml_header_len�pages�long.‚This�subroutine�handles�all�accounting�forE***…the�block�it�"steals"�from�the�partition.‚(It�either�counts�it�asE***…being�a�"used�page�in�the�current�block,�or,�if�the�current�blockH***…consists�of�only�fml_header_len�pages,�then�it�"unlinks"�the�currentH***…block,�and�counts�it�as�a�"used"�portion�of�the�previous�block,�if�a***…previous�block�exists.)*** ***…Inputs:***ˆ1.)‚A4�=�last_node_ptr.***ˆ2.)‚D7�=�fml_header_len.*** ***…Outputs:***ˆ1.)‚A5�=�fml_header_ptr.;***ˆ2.)‚If�we�can't�find�any�block�in�the�current�partition'***�at�least�fml_header_len�pages�long:+***�A.)‚A3�(first_node_ptr)�is�set�to�zero.****�B.)‚A4�(last_node_ptr)�is�set�to�zero.******…Side�effects:&***ˆ1.)‚D1�(scratch)�may�be�destroyed.******…Explanation:E***ŠFirst�we�set�fml_header_ptr�equal�to�the�last_node_ptr�and�searchJ***…backward�through�the�FML�until�we�find�a�block�at�least�fml_header_lenI***…pages�long.‚If�we�reach�the�beginning�of�the�FML�(fml_header_pty�=�0)H***…without�finding�a�block�of�memory�fml_header_len�pages�long,�then�weG***…zero�out�the�first�and�last_node_ptr�and�return.‚(Fml_header_ptr�is***…also�zero.)***E***ŠOtherwise,�we�check�to�see�if�the�block�is�exactly�fml_header_lenG***…pages�long.‚If�it�is,�then�we�call�unlink_fml_header_node�to�unlinkI***…the�node�from�the�FML�linked�list,�and�count�its�memory�as�being�part.***…of�the�used�portion�of�the�previous�block.***>***ŠIf�the�block�is�greater�than�fml_header_len�pages,�we�thenH***…decrement�fmlfree�and�increment�fmlused�by�fml_header_len�pages,�and@***…increment�fml_header_ptr�by�fml_header_len*256�bytes�so�thatI***…fml_header_ptr�now�points�to�the�first�"used"�page�within�the�current***…block�and�return.***N****************************************************************************** ,ŠTTL„GET�FML�HEADER�POINTER�HIGH�-�ALGORITHMŠPAGE$*get_fml_header_ptr_high: procedure;    #*ˆfml_header_ptr�<==�last_node_ptr;7*ˆdo�while�(fmlfree�(fml_header_ptr)�<�fml_header_len);,*’fml_header_ptr�<==�fmlbp�(fml_header_ptr);"*’if�(fml_header_ptr�=�0)�then�do;*œfirst_node_ptr�<==�0;*œlast_node_ptr�<==�0; *œreturn;*’end;*ˆend;0*ˆif�(fmlfree�(fml_header_ptr)�=�fml_header_len)#*ˆthen�call�unlink_fml_header_node; *ˆelse�do;9*’fmlfree�(fml_header_ptr)�<==�fmlfree�(fml_header_ptr)�-*¯fml_header_len;9*’fmlused�(fml_header_ptr)�<==�fmlused�(fml_header_ptr)�+*¯fml_header_len;%*’fml_header_ptr�<==�fml_header_ptr�+!*¥fmlfree�(fml_header_ptr)�*�256;*ˆend; *end get_fml_header_ptr_high; 'ŠTTL„GET�FML�HEADER�POINTER�HIGH�-�CODEŠPAGE*$*get_fml_header_ptr_high: procedure;* GFMLPTRH: *#*ˆfml_header_ptr�<==�last_node_ptr;7*ˆdo�while�(fmlfree�(fml_header_ptr)�<�fml_header_len);,*’fml_header_ptr�<==�fmlbp�(fml_header_ptr);* ŠLEA„(A4),A5 !ŠWHILE.L�FMLFREE(A5)��D7�DO.S �MOVE.L�FMLBP(A5),A5 *"*’if�(fml_header_ptr�=�0)�then�do;*œfirst_node_ptr�<==�0;*œlast_n! ode_ptr�<==�0; *œreturn;*’end;*ˆend;�IF.LƒA5��D0�THEN.S �SUB.L‚A3,A3 �SUB.L‚A4,A4�RTS�ENDIŠENDW *0*ˆif�(fmlfree�(fml_header_ptr)�=�fml_header_len)#*ˆthen�call�unlink_fml_header_node;* ŠIF.LƒFMLFREE(A5)�„D7�THEN.S�BSR.S‚UFMLHEAD * *ˆelse�do;9*’fmlfree�(fml_header_ptr)�<==�fmlfree�(fml_header_ptr)�-*¯fml_header_len;9*’fmlused�(fml_header_ptr)�<==�fmlused�(fml_header_ptr)�+*¯fml_header_len;%*’fml_header_ptr�<==�fml_header_ptr�+!*¥fmlfree�(fml_header_ptr)�*�256;*ˆend*�ELSE.S�SUB.L‚D7,FMLFREE(A5) �ADD.L‚D7,FMLUSED(A5) �MOVE.L�FMLFREE(A5),D1 �LSL.L‚#8,D1�LEA„(A5,D1.L),A5ŠENDI**end get_fml_header_ptr_high;*ŠRTS /ŠTTL„GET�FML�HEADER�POINTER�LOW�-�DOCUMENTATIONŠPAGEN*********************************************************************************,***…Name:‚GFMLPTRL�(get_fml_header_ptr_low):*** ***…Function::***ŠThis�subroutine�returns�a�pointer�to�a�block�of�memory;$\-*5[=$ELMPU3]ae3m_uQ}.…BI***…fml_header_len�pages�long�in�the�current�partition.‚This�block�is�theD***…lowest�addressed�block�in�the�current�partition�that�is�at�leastI***…fml_header_len�pages�long.‚This�subroutine�handles�all�the�accountingI***…for�the�block�it�"steals"�from�the�partition.‚(It�counts�the�block�asI***…part�of�the�"used"�portion�of�the�previous�block,�if�a�previous�blockH***…exists.)‚Also,�since�this�subroutine�"steals"�a�block�of�memory�fromE***…low�memory,�it�may�hvae�to�move�the�pointers�and�counters�(fmlfp,J***…fmlbp,�fmlfree,�fmlused)�from�their�position�to�a�location�fml_header_'***…len�pages�further�"down"�in�memory.*** ***…Inputs:***ˆ1.)‚A3�=�first_node_ptr.***ˆ2.)‚D7�=�fml_header_len.*** ***…Outputs:***ˆ1.)‚A5�=�fml_header_ptr.;***ˆ2.)‚If�we�can't�find�any�block�in�the�current�partition'***�at�least�fml_header_len�pages�long:+***�A.)‚A3�(first_node_ptr)�is�set�to�zero.****�B.)‚A4�(last_node_ptr)�is�set�to�zero.******…Side�effects:‚None:******…Explanation:F***ŠFirst�we�set�fml_header_ptr�equal�to�the�first_node_ptr�and�searchI***…forward�through�the�FML�until�we�find�a�block�at�least�fml_header_lenC***…pages�long.‚If�we�reach�the�end�of�the�FML�(fml_header_pty�=�0)H***…without�finding�a�block�of�memory�fml_header_len�pages�long,�then�weG***…zero�out�the�first�and�last_node_ptr�and�return.‚(Fml_header_ptr�is***…also�zero.)***E***ŠOtherwise,�we�check�to�see�if�the�block�is�exactly�fml_header_lenG***…pages�long.‚If�it�is,�then�we�call�unlink_fml_header_node�to�unlinkI***…the�node�from�the�FML�linked�list,�and�count�its�memory�as�being�part.***…of�the�used�portion�of�the�previous�block.***>***ŠIf�the�block�is�greater�than�fml_header_len�pages,�we�callG***…move_fml_node�to�move�the�pointers�and�counters�of�the�current�nodeJ***…(fmlfp,�fmlbp,�fmlfree,�fmlused)�fml_header_len�pages�"down"�in�memory;***…in�order�to�make�room�for�the�FML_HEADER�in�low�memory.***N****************************************************************************** +ŠTTL„GET�FML�HEADER�POINTER�LOW�-�ALGORITHMŠPAGE#*get_fml_header_ptr_low: procedure;    $*ˆfml_header_ptr�<==�first_node_ptr;7*ˆdo�while�(fmlfree�(fml_header_ptr)�<�fml_header_len);,*’fml_header_ptr�<==�fmlfp�(fml_header_ptr);"*’if�(fml_header_ptr�=�0)�then�do;*œfirst_node_ptr�<==�0;*œlast_node_ptr�<==�0; *œreturn;*’end;*ˆend;0*ˆif�(fmlfree�(fml_header_ptr)�=�fml_header_len)#*ˆthen�call�unlink_fml_header_node;*ˆelse�call�move_fml_node;  *end get_fml_header_low; &ŠTTL„GET�FML�HEADER�POINTER�LOW�-�CODEŠPAGE#*get_fml_header_ptr_low: procedure;* GFMLPTRL: *$*ˆfml_header_ptr�<==�first_node_ptr;7*ˆdo�while�(fmlfree�(fml_header_ptr)�<�fml_header_len);,*’fml_header_ptr�<==�fmlfp�(fml_header" _ptr);* ŠLEA„(A3),A5 !ŠWHILE.L�FMLFREE(A5)��D7�DO.S �MOVE.L�FMLFP(A5),A5 *"*’if�(fml_header_ptr�=�0)�then�do;*œfirst_node_ptr�<==�0;*œlast_node_ptr�<==�0; *œreturn;*’end;*ˆend;*�IF.LƒA5��D0�THEN.S �SUB.L‚A3,A3 �SUB.L‚A4,A4�RTS�ENDIŠENDW *0*ˆif�(fmlfree�(fml_header_ptr)�=�fml_header_len)#*ˆthen�call�unlink_fml_header_node;*ˆelse�call�move_fml_node;* ŠIF.LƒFMLFREE(A5)�„D7�THEN.S�BSR.S‚UFMLHEAD�ELSE.S�BSR.S‚MFMLNODEŠENDI **end get_fml_header_ptr_low;*ŠRTS +ŠTTL„UNLINK�FML�HEADER�NODE�-�DOCUMENTATIONŠPAGEN*********************************************************************************,***…Name:‚UFMLHEAD�(unlink_fml_header_node):*** ***…Function:E***ŠThis�subroutine�handles�the�unlinking�of�the�fml_header_node�fromI***…the�FML.‚It�takes�care�of�linking�the�previous_node�(if�there�is�one)I***…to�the�next_node�(if�there�is�one)�and�vice�versa.‚It�also�takes�careJ***…of�accounting�for�the�fml_header_node�as�part�of�the�"used"�portion�of(***…the�previous_node�(if�there�is�one).*** ***…Inputs:***ˆ1.)‚A3�=�first_node_ptr.***ˆ2.)‚A4�=�last_node_ptr.***ˆ3.)‚A5�=�fml_header_ptr.*** ***…Outputs:E***ˆ1.)‚Updated�FML�with�the�fml_header_node�"unlinked"�from�the�FML,?***�and�counted�as�part�of�the�"used"�part�of�its�previous_node***�(if�there�is�one).******…Side�effects:.***ˆ1.)‚A3�(first_node_ptr)�could�get�changed.-***ˆ2.)‚A4�(last_node_ptr)�could�get�changed.3***ˆ3.)‚A2�(previous_node_ptr)�could�get�destroyed.)***ˆ4.)‚A6�(scratch)�could�get�destroyed.&***ˆ5.)‚D1�(scratch)�may�be�destroyed.******…Explanation:C***ŠThe�first�do�block�handles�the�case�where�the�fml_header_ptr�isA***…equal�to�the�first_node_ptr.‚In�this�case�we�must�advance�theG***…first_node_ptr�to�point�to�the�next�node�in�the�FML.‚If�there�is�noJ***…next�node�(new�first_node_ptr�=�0),�then�we�zero�out�the�last_node_ptrD***…to�indicate�an�empty�FML,�and�return.‚Otherwise,�we�zero�out�theD***…fmlbp�of�the�new�first_node_ptr�to�indicate�that�this�is�now�the%***…beginning�of�the�FML,�and�return.***>***ŠThe�next�large�do�block�of�code�handles�the�case�where�theI***…fml_header_ptr�is�equal�to�the�last_node_ptr.‚In�this�case�we�attemptJ***…to�back�up�the�last_node_ptr�to�point�to�the�previous�node�in�the�FML.F***…If�there�is�no�previous�node�(new�last_node_ptr�=�0),�then�we�zero@***…out�the�first_node_ptr�to�indicate�an�empty�FML,�and�return.J***…Otherwise,�we�zero�out�the�fmlfp�of�the�new�last_node�to�indicate�thatG***…this�is�now�the�end�of�the�FML,�update�the�fmlused�field�of�the�new@***…last_node�to�equal�its�current�value,�plus�the�length�of�the9***…previous�last_node�(fmlfree�and�fmlused),�and�return.***@***ŠIf�neither�of�these�cases�occurred,�then�the�fml_header_nodeI***…exists�somewhere�in�the�middle�of�the�FML.‚In�this�case�we�must�firstD***…get�a�pointer�to�the�node�before�the�fml_header_node�in�the�FML.G***…Now�the�fmlfp�of�this�previous�node�must�be�set�to�the�value�of�the:***…fmlfp�of�the�fml_header_node,�and�thus�"skip�over"�theG***…fml_header_node.‚Having�done�this,�we�update�the�fmlused�portion�ofI***…this�previous_node�to�include�its�old�fmlused�value�and�the�length�of?***…the�fml_header_node�(fmlfree�and�fmlused).‚(This�in�essenceG***…counts�the�entire�fml_header_node,�used�and�free�memory,�as�part�ofH***…the�used�portion�of�the�previous�node.)‚Finally,�we�update�the�fmlbpI***…of�the�node�after�the�fml_header_node�in�the�FML�to�point�back�to�the;***…previous�node,�and�thus�complete�the�"unlinking"�of�the***…fml_header_node.***M***************************************************************************** 'ŠTTL„UNLINK�FML�HEADER�NODE�-�ALGORITHMŠPAGE#*unlink_fml_header_node: procedure;    /*ˆif�(fml_header_ptr�=�first_node_ptr)�then�do;,*’first_node_ptr�<==�fmlfp�(first_node_ptr);*’if�(first_node_ptr�=�0)" *’then�last_node_ptr�<==�0;%*’else�fmlbp�(first_node_ptr)�<==�0);*ˆend;3*ˆelse�if�(fml_header_ptr�=�last_node_ptr)�then�do;**’last_node_ptr�<==�fmlbp�(last_node_ptr);*’if�(last_node_ptr�=�0)*’then�first_node_ptr�<==�0; *’else�do;*œfmlfp�(last_node_ptr�<==�0);*œfmlused�(last_node_ptr)�<==*¦fmlused�(last_node_ptr)�+*¦fmlfree�(fml_header_ptr)�+*¦fmlused�(fml_header_ptr);*’end;*ˆend; *ˆelse�do;/*’previous_node_ptr�<==�fmlbp�(fml_header_ptr);7*’fmlfp�(previous_node_ptr)�<==�fmlfp�(fml_header_ptr);!*’fmlused�(previous_node_ptr)�<==*œfmlused�(previous_node_ptr)�+*œfmlfree�(fml_header_len)�+*œfmlused�(fml_header_ptr);+*’next_node_ptr�<==�fmlfp�(fml_header_ptr);.*’fmlbp�(next_node_ptr)�<==�previous_node_ptr;*ˆend;  *end unlink_fml_header_node; "ŠTTL„UNLINK�FML�HEADER�NODE�-�CODEŠPAGE#*unlink_fml_header_node: procedure;* UFMLHEAD: */*ˆif�(fml_header_ptr�=�first_node_ptr)�then�do;,*’first_node_ptr�<==�fmlfp�(first_node_ptr);*’if�(first_node_ptr�=�0)*’then�last_node_ptr�<==�0);$*’else�fmlbp�(first_node_ptr)�<==�0;*ˆend*ŠIF.LƒA5��A3�THEN.S �MOVE.L�FMLFP(A3),A3 �IF.LƒA3��D0�THEN.S �SUB.L‚A4,A4 �ELSE.S�CLR.L‚FMLBP(A3)�ENDI *3*ˆelse�if�(fml_header_ptr�=�last_node_ptr)�then�do;**’last_node_ptr�<==�fmlbp�(last_node_ptr);*’if�(last_node_ptr�=�0)*’then�first_node_ptr�<==�0);*�ELSE.S�IF.LƒA5��A4�THEN.S �MOVE.L�FMLBP(A4),A4 �IF.LƒA4��D0�THEN.S  “SUB.L‚A3,A3 * *’else�do;*œfmlfp�(last_node_ptr)�<==�0;*œfmlused�(last_node_ptr)�<==*¦fmlused�(last_node_ptr)�+*¦fmlfree�(fml_header_ptr)�+*¦fmlused�(fml_header_ptr);*’end;*ˆend;*“ELSE.S“CLR.L‚FMLFP(A4) “MOVE.L�FMLFREE(A5),D1“ADD.L‚FMLUSED(A5),D1“ADD.L‚D1,FMLUSED(A4)�ENDI * *ˆelse�do;/*’previous_node_ptr�<==�fmlbp�(fml_header_ptr);7*’fmlfp�(previous_node_ptr)�<==�fmlfp�(fml_header_ptr);!*’fmlused�(previous_node_ptr)�<==*œfmlused�(previous_node_ptr)�+*œfmlfree�(fml_header_ptr)�+*œfmlused�(fml_header_ptr);+*’next_node_ptr�<==�fmlfp�(fml_header_ptr);.*’fmlbp�(next_node_ptr)�<==�previous_node_ptr;*ˆend;*�ELSE.S�MOVE.L�FMLBP(A5),A2 �MOVE.L�FMLFP(A5),FMLFP(A2) �MOVE.L�FMLFREE(A5),D1�ADD.L‚FMLUSED(A5),D1�ADD.L‚D1,FMLUSED(A2) �MOVE.L�FMLFP(A5),A6 �MOVE.L�A2,FMLBP(A6)�ENDIŠENDI**end unlink_fml_header_node;*ŠRTS "ŠTTL„MOVE�FML�NODE�-�DOCUMENTATIONŠPAGEN*********************************************************************************#***…Name:‚MFMLNODE�(move_fml_node):*** ***…Function:D***ŠThis�subroutine�"moves"�the�pointers�and�counters�(fmlfp,�fmlbp,C***…fmlfree,�fmlused)�of�an�FML�node�fml_header_len�pages�"down"�inG***…memory.‚It�also�handles�all�accounting�for�the�change�in�the�statusH***…of�the�moved�memory�(fmlfree�of�the�current�node�gets�decremented�byH***…fml_header_len�pages,�and�fmlused�for�the�previous�node�(if�there�isB***…one)�gets�incremented�by�the�same�value).‚This�subroutine�alsoG***…accounts�for�any�change�in�the�status�of�the�first_node_ptr�(if�theH***…fml_header_ptr�was�pointing�to�the�first�node),�or�the�last_node_ptrF***…(if�the�fml_header_ptr�was�pointing�to�the�last�node)�as�required.*** ***…Inputs:***ˆ1.)‚A3�=�first_node_ptr.***ˆ2.)‚A4�=�last_node_ptr.***ˆ3.)‚A5�=�fml_header_ptr.***ˆ4.)‚D7�=�fml_header_len.*** ***…Outputs:C***ˆ1.)‚A�new�FML�node�moved�down�in�memory�by�fml_header_len�page.A***ˆ2.)‚All�new�pointers�to�reflect�the�displacement�of�the�node.******…Side�effects:***ˆ1.)‚A2�gets�destroyed.+***ˆ2.)‚A3�(first_node_ptr)�may�be�updated.****ˆ3.)‚A4�(last_node_ptr)�may�be�updated.$***ˆ4.)‚A6�(scratch)�gets�destroyed.******…Explanation:D***ŠFirst�we�compute�the�address�of�the�moved�node�to�be�the�addressH***…of�the�fml_header_ptr�plus�the�offset,�in�bytes,�that�the�node�is�toH***…be�moved�(fml_header_len*256).‚Then�we�get�a�pointer�to�the�previousE***…node�in�the�FML.‚If�there�is�no�previous�node,# �then�we�update�theG***…first_node_ptr�to�point�to�the�moved�node.‚Otherwise,�we�update�theH***…fmlfp�field�of�the�previous�node�to�point�to�the�moved�node,�and�addH***…the�fml_header_len�pages�to�the�"used"�portion�of�the�previous�node.***D***ŠNext�we�decrement�the�"free"�field�of�the�fml_header_node�by�theJ***…value�of�the�fml_header_len�to�reflect�the�fact�that�this�memory�is�noI***…longer�available�to�that�node.‚Then�we�get�a�pointer�to�the�next�nodeD***…in�the�FML,�and�if�it�is�zero�(no�next�node),�then�we�update�theF***…last_node_ptr�to�point�to�the�moved�node.‚Otherwise,�we�update�the;***…fmlbp�of�the�next�node�to�point�back�to�the�moved�node.***C***ŠFinally,�we�actually�move�the�pointers�and�counters�of�the�nodeJ***…from�the�memory�pointed�to�by�the�fml_header_ptr�to�the�memory�pointed)***…to�by�the�moved_node_ptr,�and�return.***M***************************************************************************** ŠTTL„MOVE�FML�NODE�-�ALGORITHMŠPAGE*move_fml_node: procedure;    9*ˆmoved_node_ptr�<==�fml_header_ptr�+�fml_header_len*256; /*ˆprevious_node_ptr�<==�fmlbp�(fml_header_ptr);*ˆif�(previous_node_ptr�=�0))*ˆthen�first_node_ptr�<==�moved_node_ptr; *ˆelse�do;/*’fmlfp�(previous_node_ptr)�<==�moved_node_ptr;!*’fmlused�(previous_node_ptr)�<==*œfmlused�(previous_node_ptr)�+*œfml_header_len;*ˆend; *ˆfmlfree�(fml_header_ptr)�<==*œfmlfree�(fml_header_ptr)�-*œfml_header_len; +*ˆnext_node_ptr�<==�fmlfp�(fml_header_ptr);*ˆif�(next_node_ptr�=�0)(*ˆthen�last_node_ptr�<==�moved_node_ptr;0*ˆelse�fmlbp�(next_node_ptr)�<==�moved_node_ptr; 2*ˆfmlfp.fmlbp.fmlused.fmlfree�(moved_node_ptr)�<==/*’fmlfp.fmlbp.fmlused.fmlfree�(fml_header_ptr);  *end move_fml_node; ŠTTL„MOVE�FML�NODE�-�CODEŠPAGE*move_fml_node: proc;* MFMLNODE: *9*ˆmoved_node_ptr�<==�fml_header_ptr�+�fml_header_len*256;* ŠLSL.L‚#8,D7ŠLEA„(A5,D7.L),A6 ŠLSR.L‚#8,D7 */*ˆprevious_node_ptr�<==�fmlbp�(fml_header_ptr);*ˆif�(previous_node_ptr�=�0))*ˆthen�first_node_ptr�<==�moved_node_ptr;*ŠMOVE.L�FMLBP(A5),A2 ŠIF.LƒA2��D0�THEN.S �LEA„(A6),A3 * *ˆelse�do;/*’fmlfp�(previous_node_ptr)�<==�moved_node_ptr;!*’fmlused�(previous_node_ptr)�<==*œfmlused�(previous_node_ptr)�+*œfml_header_len;*ˆend;*�ELSE.S�MOVE.L�A6,FMLFP(A2) �ADD.L‚D7,FMLUSED(A2)ŠENDI *ˆfmlfree�(fml_header_ptr)�<==*œfmlfree�(fml_header_ptr)�-*œfml_header_len;*ŠSUB.L‚D7,FMLFREE(A5) *+*ˆnext_node_ptr�<==�fmlfp�(fml_header_ptr);*ˆif�(next_node_ptr�=�0)(*ˆthen�last_node_ptr�<==�moved_node_ptr;0*ˆelse�fmlbp�(next_node_ptr)�<==�moved_node_ptr;*ŠMOVE.L�FMLFP(A5),A2 ŠIF.LƒA2��D0�THEN.S �LEA„(A6),A4 �ELSE.S�MOVE.L�A6,FMLBP(A2)ŠENDI *2*ˆfmlfp.fmlbp.fmlused.fmlfree�(moved_node_ptr)�<==/*’fmlfp.fmlbp.fmlused.fmlfree�(fml_header_ptr);*ŠMOVE.L�FMLFP(A5),FMLFP(A6)ŠMOVE.L�FMLBP(A5),FMLBP(A6)ŠMOVE.L�FMLUSED(A5),FMLUSED(A6)ŠMOVE.L�FMLFREE(A5),FMLFREE(A6) **end move_fml_node;*ŠRTS *ŠTTL„CHECKŽMEMMAP�CONFLICT�-�DOCUMENTATIONŠPAGEM********************************************************************************+***…Name:‚CMEMCONF�(check_memmap_conflict):*** ***…Function:C***ŠThis�subroutine�checks�the�RAM�partition�described�by�the�entryB***…in�the�src_memtbl�pointed�to�by�the�src_memtbl_ptr�against�allE***…previously-described�RAM�partitions.‚If�this�subroutine�detects�aD***…fatal�conflict�it�will�not�return�execution�to�the�caller.‚If�itC***…detects�an�alias�partition�(same�starting�address�as�some�otherK***…partition),�it�returns�execution�with�the�got_alias_partition_flag�set.9***…Otherwise,�it�returns�execution�with�that�flag�reset.*** ***…Inputs:***ˆ1.)‚A0�=�src_memtbl_ptr.***ˆ2.)‚A1�=�dest_memtbl_ptr.***ˆ3.)‚D4�=�start_of_part_ptr.***ˆ4.)‚SYSPAR�(MAPBEG).*** ***…Outputs:&***ˆ1.)‚D2�=�got_alias_partition_flag.@***ˆ2.)‚# A5�=�fml_header_ptr�(if�got_alias_partition_flag�=�set).******…Side�effects:,***ˆ1.)‚A2�(temp_memtbl_ptr)�gets�destroyed.$***ˆ2.)‚D1�(scratch)�gets�destroyed.3***ˆ3.)‚Execution�may�not�return�(may�call�KILLER).******…Explanation:@***ŠFirst�we�initialize�for�the�loop�by�resetting�the�got_alias_I***…partition_flag,�setting�the�current_partition_number,�and�setting�theF***…temp_memtbl_ptr�to�point�to�the�beginning�of�the�dest_memtbl.‚Then***…we�begin�the�loop.***B***ŠIf�we�detect�a�duplicate�partition�number,�then�we�call�KILLERC***…and�die.‚If�we�detect�a�duplicate�start_of_part_ptr,�we�set�theI***…got_alias_partition_flag,�set�the�fml_header_ptr�equal�to�the�MAPFMLPB***…field�of�the�alias�partition�and�return.‚If�we�detect�that�ourD***…current�start_of_part_ptr�is�at�a�lower�memory�location�than�theF***…ENDAVAIL�field�of�some�previous�partition,�then�we�call�KILLER�andC***…die.‚Otherwise,�we�keep�looping�until�we�have�looked�at�all�the>***…previously-defined�entries�in�the�dest_memtbl,�and�return.***L**************************************************************************** &ŠTTL„CHECKŽMEMMAP�CONFLICT�-�ALGORITHMŠPAGE"*check_memmap_conflict: procedure;    !*ˆreset�got_alias_partition_flag;B*ˆcurrent_partition_number�<==�MAPMTYP�(src_memtbl_ptr)�.AND.�$0F;&*ˆtemp_memtbl_ptr�<==�SYSPAR�(MAPBEG);/*ˆdo�until�(temp_memtbl_ptr�=�dest_memtbl_ptr);;*’if�(MAPPART�(temp_memtbl_ptr)�=�current_partition_number)*’then�call�KILLER;=*’if�(MAPSTRA�(temp_memtbl_ptr)�=�start_of_part_ptr)�then�do;*œset�got_alias_partition_flag;/*œfml_header_ptr�<==�MAPFMLP�(temp_memtbl_ptr); *œreturn;*’end;=*’if�(start_of_part_ptr�<�ENDAVAIL�(MAPFMLP�(temp_memtbl�ptr)*’then�call�KILLER;'*’temp_memtbl_ptr�<==�temp_memtbl_ptr�+*¦length�(dest_memtbl_entry); *ˆend;  *end check_memmap_conflict; !ŠTTL„CHECKŽMEMMAP�CONFLICT�-�CODEŠPAGE"*check_memmap_conflict: procedure;* CMEMCONF: *!*ˆreset�got_alias_partition_flag;B*ˆcurrent_partition_number�<==�MAPMTYP�(src_memtbl_ptr)�.AND.�$0F;'*ˆtemp_memtbl_ptr�<==�SYSPAR�(MAPBEG));/*ˆdo�until�(temp_memtbl_ptr�=�dest_memtbl_ptr);* ŠCLR.B‚D2 ŠMOVE.B�MAPMTYP(A0),D1ŠAND.B‚#$0F,D1 ŠMOVE.L�MAPBEG,A2 ŠREPEAT *;*’if�(mappart�(temp_memtbl_ptr)�=�current_partition_number)*’then�call�KILLER;* �IF.BƒMAPPART(A2)�„D1�THEN.S �BSR„KILLER�ENDI *=*’if�(mapstra�(temp_memtbl_ptr)�=�start_of_part_ptr)�then�do;*›set�got_alias_partition_flag;/*›fml_header_ptr�<==�mapfmlp�(temp_memtbl_ptr); *›return;*’end;* �IF.LƒMAPSTRA(A2)�„D4�THEN.S�ST…D2�MOVE.L�MAPFMLP(A2),A5�RTS�ENDI *>*’if�(start_of_part_ptr�<�endavail�(mapfmlp�(temp_memtbl_ptr))*’then�call�KILLER;*�MOVE.L�MAPFMLP(A2),A6!�IF.LƒD4��ENDAVAIL(A6)�THEN.S �BSR„KILLER�ENDI **’temp_memtbl_ptr�<==*œtemp_memtbl_ptr�+*œlength�(dest_memtbl_entry);*�LEA„MAPENTSZ(A2),A2 **ˆend;*ŠUNTIL.L�A2��A1 **end check_memmap_conflict;*ŠRTS +ŠTTL„BUILDŽRAM�MEMTBL�ENTRY�-�DOCUMENTATIONŠPAGEN*********************************************************************************,***…Name:‚BRAMNODE�(build_ram_memtbl_entry):*** ***…Function:D***ŠThis�subroutine�writes�in�all�pointers�and�descriptors�for�a�RAM'***…partition�entry�in�the�dest_memtbl.*** ***…Inputs:***ˆ1.)‚A0�=�src_memtbl_ptr.***ˆ2.)‚A1�=�dest_memtbl_ptr.***ˆ3.)‚A5�=�fml_header_ptr.***ˆ4.)‚D4�=�start_of_part_ptr.*** ***…Outputs:7***ˆ1.)‚Dest_memtbl_entry�(RAM�entry)�pointed�to�by�the***�dest_memtbl_ptr.******…Side�effects:+***ˆ1.)‚D1,�and�D2�(scratch)�get�destroyed.******…Explanation:D***ŠThe�MAPMTYP�field�of�the�dest_memtbl_entry�gets�set�equal�to�theF***…most�significant�four�bits�of�the�MAPPART�field�of�the�src_memtbl_H***…entry,�and�the�MAPPART�field�of�the�dest_memtbl_entry�gets�set�equalI***…to�the�four�least�significant�bits�of�the�same�field.‚Finally,�we�setJ***…the�MAPSTRA�fiel$ d�of�the�dest_memtbl_entry�equal�to�the�start_of_part_G***…ptr,�and�the�MAPFMLP�field�equal�to�the�fml_header_ptr,�and�return.***M***************************************************************************** 'ŠTTL„BUILDŽRAM�MEMTBL�ENTRY�-�ALGORITHMŠPAGE#*build_ram_memtbl_entry: procedure;    *ˆMAPMTYP�(dest_memtbl_ptr)�<==%*’MAPPART�(src_memtbl_ptr)�.AND.�$70;*ˆMAPPART�(dest_memtbl_ptr)�<==%*’MAPPART�(src_memtbl_ptr)�.AND.�$0F;2*ˆMAPSTRA�(dest_memtbl_ptr)�<==�start_of_part_ptr;/*ˆMAPFMLP�(dest_memtbl_ptr)�<==�fml_header_ptr;  *end build_ram_memtbl_entry; "ŠTTL„BUILDŽRAM�MEMTBL�ENTRY�-�CODEŠPAGE#*build_ram_memtbl_entry: procedure;* BRAMNODE: **ˆMAPMTYP�(dest_memtbl_ptr)�<==%*’MAPMTYP�(src_memtbl_ptr)�.AND.�$70;*ŠMOVE.B�MAPMTYP(A0),D1 ŠMOVE.B�D1,D2ŠAND.B‚#$70,D1ŠMOVE.B�D1,MAPMTYP(A1) **ˆmappart�(dest_memtbl_ptr)�<==&*’mapmtyp�(dest_memtbl_ptr)�.AND.�$0F;*ŠAND.B‚#$0F,D2ŠMOVE.B�D2,MAPPART(A1) *2*ˆmapstra�(dest_memtbl_ptr)�<==�start_of_part_ptr;*ŠMOVE.L�D4,MAPSTRA(A1) */*ˆmapfmlp�(dest_memtbl_ptr)�<==�fml_header_ptr;*ŠMOVE.L�A5,MAPFMLP(A1) **end build_ram_memtbl_entry;*ŠRTS +ŠTTL„BUILDŽROM�MEMTBL�ENTRY�-�DOCUMENTATIONŠPAGEM********************************************************************************,***…Name:‚BROMNODE�(build_rom_memtbl_entry):*** ***…Function:E***ŠThis�subroutine�does�some�primitive�checking�on�the�legality�of�aB***…ROM�partition�described�in�the�src_memtbl,�and�then�writes�theH***…descriptors�and�pointers�to�describe�that�node�into�the�dest_memtbl.*** ***…Inputs:***ˆ1.)‚A0�=�src_memtbl_ptr.***ˆ2.)‚A1�=�dest_memtbl_ptr.***ˆ3.)‚D4�=�start_of_part_ptr.***ˆ4.)‚D5�=�end_of_part_ptr.*** ***…Outputs:7***ˆ1.)‚Dest_memtbl_entry�(ROM�entry)�pointed�to�by�the***�dest_memtbl_ptr.******…Side�effects:$***ˆ1.)‚A6�(scratch)�gets�destroyed./***ˆ2.)‚Execution�may�not�return�(call�KILLER).******…Explanation:D***ŠFirst�we�verify�that�the�current�ROM�partition�does�not�start�atH***…a�lower�memory�location�than�the�ending�of�the�last�partition�in�theH***…dest_memtbl.‚If�it�does,�we�have�a�fatal�configuration�error,�and�so***…we�call�KILLER.***>***ŠOtherwise,�we�move�the�MAPMTYP�and�MAPPART�fields�from�theH***…src_memtbl�to�the�dest_memtbl,�set�the�MAPSTRA�and�MAPENDA�fields�ofF***…the�dest_memtbl�equal�to�the�start_of_part_ptr�and�end_of_part_ptr***…respectively,�and�return.***N****************************************************************************** 'ŠTTL„BUILDŽROM�MEMTBL�ENTRY�-�ALGORITHMŠPAGE#*build_rom_memtbl_entry: procedure;   ?*ˆif�(MAPMTYP�(previous�(dest_memtbl_ptr))�=�ROM_type)�then�do;*’if�(start_of_part_ptr�<'*œMAPENDA�(previous�(dest_memtbl_ptr)))é*’then�call�KILLER;*ˆend; *ˆelse�do;*’if�(start_of_part_ptr�<1*œENDAVAIL�(MAPFMLP�(previous�(dest_memtbl_ptr)))*’then�call�KILLER;*ˆend; '*ˆMAPMTYP.MAPPART�(dest_memtbl_ptr)�<==#*’MAPMTYP.MAPPART�(src_memtbl_ptr);3*ˆMAPSTRA�(dest_memtbl_ptr)�<==�start_of_part_ptr);0*ˆMAPENDA�(dest_memtbl_ptr)�<==�end_of_part_ptr;  *end build_rom_memtbl_entry; "ŠTTL„BUILD�ROM�MEMTBL�ENTRY�-�CODEŠPAGE#*build_rom_memtbl_entry: procedure;* BROMNODE: ?*ˆif�(MAPMTYP�(previous�(dest_memtbl_ptr))�=�ROM_type)�then�do;*’if�(start_of_part_ptr�<'*œMAPENDA�(previous�(dest_memtbl_ptr)))*’then�call�KILLER;*ˆend; +ŠIF.BƒMAPMTYP-MAPENTSZ(A1)��#$FF�THEN.S)ŠIF.LƒD4��MAPENDA-MAPENTSZ(A1)�THEN.S ŠBSR„KILLERŠEND$ I *ˆelse�do;*’if�(start_of_part_ptr�<1*œENDAVAIL�(MAPFMLP�(previous�(dest_memtbl_ptr)))*’then�call�KILLER;*ˆend; ŠELSE.SŠMOVE.L�MAPFMLP-MAPENTSZ(A1),A6!ŠIF.L�D4��ENDAVAIL(A6)�THEN.S ŠBSR„KILLERŠENDIŠENDI *'*ˆmapmtyp.mappart�(dest_memtbl_ptr)�<==#*’mapmtyp.mappart�(src_memtbl_ptr);2*ˆmapstra�(dest_memtbl_ptr)�<==�start_of_part_ptr;0*ˆmapenda�(dest_memtbl_ptr)�<==�end_of_part_ptr;*ŠMOVE.W�MAPMTYP(A0),MAPMTYP(A1) ŠMOVE.L�D4,MAPSTRA(A1) ŠMOVE.L�D5,MAPENDA(A1)**end build_rom_memtbl_entry;*ŠRTS  ŠEND éé=/*=/*†M68XXX.KILLER.AF=/*+=/* Chain file to assemble M68XXX.KILLER.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.KILLER.LS=/*=/IFC \1ƒ=ARG�M68XXX.KILLER.LS=/ENDIF=/*1=ASM M68XXX.KILLER.SA,M68XXX.KILLER.RO,\1;MRZ=040=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.PANEL.EQ=/*}=/*=ENDéééééé�‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.PANEL.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.PANEL.EQ‰LIST‰PAGE&KILLERƒIDNT„5,1…68xxx�CRASH�THE�SYSTEM*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*2*†SOMETHING�HAS�GONE�WRONG---GET�OUT�OF�THIS�TASK!*‰SECTION�LEVEL00* ‰XDEF„KILLER‰XDEF„KILLERT0 ‰XREF.S‚CRASHSAV ‰XREF.S‚PANEL    KILLERT0:KILLER:‰MOVEM.L�D0-D7/A0-A7,CRASHSAV+8%‰MOVE.W‚SR,CRASHSAV+6ŒSAVE�STATUS�REG% &‰MOVE.L‚(A7),CRASHSAVŒSAVE�PC�OF�CRASH ‰MOVE„USP,A1‰MOVE.L‚A1,CRASHSAV+72‹SAVE�USP4‰MOVE.L‚$8,CRASHSAV+76‹SAVE�BUS�ERROR�VECTOR�ADDRESS KILLER2:‰MOVE.L‚PANEL,A1‘PANEL�ADDRESS(‰MOVE.W‚#$95,FPLEDST(A1)‰DISABLE�TTO--AX!‰MOVE.W‚#$B5,FPLEDST(A1)‰LATCH�IT‰MOVE.W‚#$A0,FPLEDST(A1)‰XF!‰MOVE.W‚#$B0,FPLEDST(A1)‰LATCH�IT$‰OR.W„#$700,SR‘STOP�OTHER�INTERRUPTS‰BRA.SƒKILLER2‰ENDéééé–/=/*=/*†M68XXX.LOGPHY.AF=/*+=/* Chain file to assemble M68XXX.LOGPHY.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.LOGPHY.LS=/*=/IFC \1ƒ=ARG�M68XXX.LOGPHY.LS=/ENDIF=/*1=ASM M68XXX.LOGPHY.SA,M68XXX.LOGPHY.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*}=/*=ENDééééééŸ% ‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰LIST‰PAGEALOGPHYƒIDNT‚5,1ƒ68xxx�TRAP�0--CONVERT�LOGICAL�ADDRESS�TO�PHYSICAL*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ********************8*ˆ*�LOGPHY†2.00�*ƒLOGICAL�TO�PHYSICAL�ADDRESS�CONVERSION*ˆ*�7616�04/23/79„**ˆ*�HLD6�07/06/79„**ˆ*�HLD6�02/26/81„*=*ˆ*�SJF‚10/14/83‚MMIO�segments�no�longer�treated�differently.*ˆ*********************$*�ENTRY‚A0„POINTS�TO�TST�(PRESERVED)%*ˆD6„LOGICAL�WINDOW�BEGINNING�ADDRESS*ˆD5„WINDOW�LENGTH�IN�BYTES*2*�EXITƒPC„IF�WINDOW�IS�COMPLETELY�WITHIN�A�SEGMENT&*ˆD6„PHYSICAL�WINDOW�BEGINNING�ADDRESS!*ˆD5„0(A0,D5)�POINTS�TO�MMU�ENTRY%*ˆD3„Logical�window�beginning�address*/*ˆPC+2‚IF�WINDOW�PARTIALLY�CONTAINED�IN�SEGMENT*ˆD6„SAME�AS�SUPPLIED!*ˆD5„0(A0,D5)�POINTS�TO�MMU�ENTRY*1*ˆPC+4‚IF�WINDOW�COMPLETELY�OUTSIDE�ADDRESS�SPACE&*�-�OR�-�IF�WINDOW�WITHIN�MMIO�SEGMEMT*ˆD6„SAME�AS�SUPPLIED)*ˆD5„0(A0,D5)�POINTS�TO�FIRST�EMPTY�ENTRY*�-�OR�-�POINTS�TO�MMIO�SEGMENT(*ŽD5�=�0�IF�NONE�EMPTY�(AND�NO�MMIO�SEG)* *’01234567*�USES�REGISTERS�D�R‚**RR*�A�P†E*‰SECTION�LEVEL02* ‰XDEF�LOGPHY ‰XDEF�LOGPHYO‰XDEF�SBLOGPHY‰XDEF�SBLOGPHO‰PAGE SBLOGPHY:LOGPHY:(‰BCLRƒ#0,D6ˆSTARTING�ADDRESS�ALWAYS�EVEN SBLOGPHO:LOGPHYO::‰AND.L‚#$FFFFFF,D6‚CLEAR�1ST�BYTE�OF�ADDRESS�(24�BITS�MAX),‰CLR.L‚D0‹CLEAR�-�USED�AS�EMPTY�ENTRY�OFFSET'‰MOVE.L�D6,D3ˆWINDOW�BEGIN�PAGE�ADDRESS‰LSR.L‚#8,D6ˆCONVERT�TO�PAGE‰MOVE.L�D5,D4ˆLENGTH�OF�WINDOW3‰BLE.S‚LOGPHY6†ERROR�RETURN�IF�LENGTH�IS�0�OR�MINUS -‰ADD.L‚D3,D4ˆBEG�ADDR�+�LENGTH�=�END�ADDR�+�1‰SUB.L‚#1,D4ˆENDING�ADDRESS!‰LSR.L‚#8,D4ˆCONVERT�TO�LAST�PAGE ‰CLR.L‚D5$‰MOVE.W�TSTLMMU(A0),D5‰LAST�MMU�LOAD  **ˆLOOK�FOR�ENTRY�IN�TST* LOGPHY1:‰TST.B‚TSTCTL+1(A0,D5)ˆIN�USE?‰BEQ.S‚LOGPHY4�BRANCH�IF�NO 1‰CMP.W‚TSTLB(A0,D5),D6ˆWINDOW�START�BEFORE�BEGIN?¨V±2$‰BCS.S‚LOGPHY5�YES--TRY�NEXT�SEGMENT .‰CMP.W‚TSTLE(A0,D5),D6ˆWINDOW�START�AFTER�END?$‰BHI.S‚LOGPHY5�YES--TRY�NEXT�SEGMENT  *4*ˆWINDOW�CONTAINED�OR�PARTIALLY�CONTAINED�IN�SEGMENT* 7‰CMP.W‚TSTLE(A0,D5),D4ˆFOUND�SEG--WINDOW�END�AFTER�END?(‰BHI.S‚LOGPHY8�BRANCH�IF�WINDOW�OVERLAPS  *%*ˆWINDOW�TOTALLY�CONTAINED�IN�SEGMENT* /‰ADD.W‚TSTPO(A0,D5),D6ˆCOMPUTE�PHYSICAL�ADDRESS‰LSL.L‚#8,D6’CONVERT�TO�BYTES(‰ADD.B‚D3,D6’ADD�BYTES�BEYOND�PAGE�START‰RTS  **ˆLOOP�BACK�TO�CHECK�NEXT�ENTRY* LOGPHY4:%‰MOVE.L�D5,D0ˆSAVE�EMPTY�ENTRY�OFFSET LOGPHY5:‰SUB.L‚#8,D5ˆGET�NEXT�ENTRY&‰CMP.W‚#TSTMMU,D5ƒALL�ENTRIES�CHECKED?(‰BGE„LOGPHY1†GO�BACK�TO�CHECK�NEXT�ENTRY  *.*ˆNO�ENTRY�FOUND�-�MMIOSEG�-�PARTLY�IN�SEGMENT* LOGPHY6:'‰MOVE.L�D0,D5ˆRETURN�EMPTY�ENTRY�OFFSET‰ADD.L‚#2,(A7)†CHANGE�RETURN LOGPHY8:'‰ADD.L‚#2,(A7)†WINDOW�PARTLY�IN�SEGMENT%‰MOVE.L�D3,D6ˆRETURN�ORIGINAL�ADDRESS‰RTS‰ENDééé& é=/*=/*†M68XXX.PAGEALOC.AF=/*-=/* Chain file to assemble M68XXX.PAGEALOC.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.PAGEALOC.LS=/*=/IFC \1ƒ=ARG�M68XXX.PAGEALOC.LS=/ENDIF=/*5=ASM M68XXX.PAGEALOC.SA,M68XXX.PAGEALOC.RO,\1;MRZ=070=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.SEG.EQ=/*ƒ9995.&.MAP.EQ=/*}=/*=ENDééééé鹉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*ˆINCLUDEƒ9995.&.MAP.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.SEG.EQ‰INCLUDEƒ9995.&.MAP.EQ‰LIST‰PAGE8PAGEALOC�IDNT�5,1ƒ68xxx�TRAP�0--ALLOCATE�PHYSICAL�MEMORY*»3/06/79�GGC3$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*»2/12/81�HLD6&*…PAGAL‚--�ALLOCATE�PAGES�EXEC�ROUTINE*/*‹ENTRY:�A0�UPPER�1/2�-�OPTIONS�AND�MEMORY�TYPE'*¡BIT‚26=1‚WAIT�IF�MEMORY�NOT�AVAILABLE+*¡BIT‚25=1‚ALLOCATE�LARGEST�BLOCK�AVAILABLE'*¡BIT‚24=1‚ALLOCATE�AT�PHYSICAL�ADDRESS&*¡BIT‚23=1‚SEGMENT�IS�MMIO�OR�PHYS�ROM*¡BITS�22-20�MEMORY�TYPE*¡BITS�19-16�PARTITION�NUMBER*,*“A0�LOWER�1/2�-�NUMBER�OF�PAGES�TO�ALLOCATE+*“A1�=�PHYSICAL�ADDRESS�IF�BIT�24�OF�A0�=�1*6*‹EXIT�:�SUCCESS‚RTS�WITH�A0=ADDRESS�OF�NEW�ALLOCATION*¤D1=1�BYTE�MEMORY�DESCRIPTION*¤D2=NUMBER�OF�PAGES�ALLOCATED*“FAIL„RTS�TO�PC+2* *“01234567*�USES�REGISTERS‚D�****‘A�*****‰SECTION�LEVEL01**,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‚ChangesH*…--------‚------‚------------------------------------------------------@*†1/19/84‚MSL…Fixed�so�that�user�could�GTSEG�on�a�ROM�partition.**‰XDEF‚PAGEALOC ‰XDEF‚SBPAGAL ‰XREFƒDISPATCH ‰XREFƒPSWAIT ‰XREFƒSVXSTAK ‰XREF.S�MAPBEG‰PAGESBPAGAL: PAGEALOC:)‰MOVEM.L�D3-D5/A3-A5,-(A7)‚SAVE�REGISTERS ‰MOVE.L‚A0,D3ˆREQUEST�PARAMETERS ‰CLR.LƒD2$‰MOVE.W‚D3,D2ˆD2�=�#�PAGES�REQUESTED‰BNE.SƒPAGAL0‡ERROR�IF& �ZERO ‰MOVE.L‚#1,D4ˆSET�ERROR�CODE‰BRA…PAGALC6†GO�TO�RETURN PAGAL0:4‰SWAP„D3‹Low�D3�=�options,�High�D3�=�number�of�pages"‰MOVE.W‚D3,D1ˆD1�=�REQUEST�OPTIONS  *:*ˆIf�partition�number�is�specified,�go�directly�to�PAGAL1.9*ˆNote�that�in�this�case,�we�skip�the�preparation�for�the*ˆWAITMEM�option.* 5‰MOVE.L‚#MAPPART,D4‚D4�=�PARTITION�OFFSET�FOR�COMPARE&‰AND.Lƒ#$0F,D3†WAS�PARTITION�#�GIVEN�?.‰BNE.SƒPAGAL1‡BRANCH�IF�YES�-�D3�=�PARTITION�#  *ÂXË[Ó_Û]ã[ëG=*ˆSince�partition�number�is�not�specified,�use�partition�type* #‰MOVE.W‚D1,D3ˆRESTORE�OPTIONS�TO�D3‰AND.Lƒ#$70,D3†D3�=�MEMORY�TYPE@‰MOVE.L‚#MAPMTYP,D4‚TYPE�OFFSET�FOR�COMPARE-�IF�PART=0,�USE�TYPE  *3*ˆIF�'WAIT�FOR�MEMORY'�WAS�REQUESTED�--�PREPARE�NOW* ‰IFNE„WAITMEM,‰BTST„#SGPBOWAI,D1‚'WAIT�FOR�MEM'�REQUESTED? ‰BEQ.SƒPAGAL1 )‰BSR…PAGASVST…GO�SAVE�REGISTERS�AND�STACK‰ENDC  **ˆINITIALIZE�FOR�MEMMAP�SEARCH* PAGAL1:7‰LEA…0,A5…A5=POINTER�TO�FML�HEADER�FOR�'BEST�FIT'�ENTRY0‰LEA…0,A4…A4=POINTER�TO�FML�ENTRY�FOR�'BEST�FIT' ‰IFNE„SHARMEM ‰CLR.Lƒ-(A7)„MARK�PLACE�ON�STACK‰ENDC #‰MOVE.L‚A1,A2„SAVE�PHYSICAL�ADDRESS)‰MOVE.L‚MAPBEG,A1‚POINTER�TO�MEMMAP�TABLE)‰BTST„#SGPBOPHY,D1‚NEED�PHYSICAL�ADDRESS?‰BNE…PAGPHYA…BRANCH�IF�YES‰PAGE*4*„LOOK�FOR�PARTITION�#�OR�TYPE�MATCH�IN�MEMMAP�TABLE@*„D1=OPTIONSƒD2=#�PAGESƒD3=PARTITION�#�OR�TYPE�#‚D4=TABLE�OFFSET$*„A1=POINTER�TO�CURRENT�MEMMAP�ENTRY* PAGALKM1:/‰TST.WƒMAPMTYP(A1)‚TEST�FOR�ROM�OR�NO�PARTITION$‰BMI.SƒPAGALKM4…BRANCH�TO�SKIP�ENTRY ,‰CMP.Bƒ0(A1,D4),D3‚IS�THIS�A�MATCHING�ENTRY?‰BNE.SƒPAGALKM4…BRANCH�IF�NO ,‰MOVE.L‚MAPFMLP(A1),A3ƒA3=CURRENT�FML�HEADER  **ˆCHECK�FOR�DUPLICATE�ENTRY* ‰IFNE„SHARMEM2‰MOVE.L‚A7,A0‰STACK�TO�A0�-�CHECK�ENTRIES�ON�STACK PAGALKM2:‰TST.Lƒ(A0)ŠEND�OF�ENTRIES?*‰BEQ.SƒPAGALKM3†BRANCH�IF�YES�-�ALL�TESTED #‰CMP.Lƒ(A0)+,A3†COMPARE�FML�POINTER+‰BEQ.SƒPAGALKM4†BRANCH�IF�EQUAL�-�DUPLICATE #‰BRA…PAGALKM2†GO�BACK�TO�CHECK�MORE  PAGALKM3:*‰PEA…(A3)ŠSAVE�FML�HEADER�ADDRESS�ON�STACK%‰TR0.PƒSEMFRMEM(A3)ƒWAIT�ON�SEMAPHORE‰ENDC (‰BSR…PAGASFML†GO�SEARCH�FREE�MEMORY�LIST PAGALKM4:&‰LEA…MAPENTSZ(A1),A1‚NEXT�MEMMAP�ENTRY$‰CMP.Wƒ#-1,MAPMTYP(A1)ƒEND�OF�TABLE?‰BNE…PAGALKM1‰BRANCH�IF�NO‰PAGE*,*…SEARCH�COMPLETE�--�ALLOCATE�IF�SPACE�FOUND* PAGALC3:‰CLR.LƒD4ŠCLEAR�FOR�RETURN�CODE(‰TST.Lƒ(A7)ˆWAS�'BEST�FIT'�HEADER�FOUND?‰BEQ.SƒPAGAER2…BRANCH�IF�NO )‰MOVE.L‚A4,D0‡WAS�'BEST�FIT'�ENTRY�FOUND?‰BEQ.SƒPAGALC9…BRANCH�IF�NO 2‰CMP.LƒFMLFREE(A4),D2‚CHECK�FOR�ENOUGH�SPACE�FOUND ‰BLE.SƒPAGALC3A„BRANCH�IF�ENOUGH ‰BTST„#SGPBOLES,D1‚ACCEPT�LESS?‰BEQ.SƒPAGALC9…BRANCH�IF�NO 1‰MOVE.L‚FMLFREE(A4),D2‚ALLOCATE�LARGEST�AVAILABLE PAGALC3A:%‰BSR…PAGATAK…TAKE�SPACE�-�REBUILD�FML PAGALC4:-‰MOVE.B‚MAPMTYP(A1),D1ƒRETURN�MEMORY�MAP�TYPE)‰OR.B„MAPPART(A1),D1ƒAND�PARTITION�NUMBER PAGALC5: ‰IFNE„SHARMEM ‰BSR…PAGARSM‰ENDC  **…ALLOCATION�COMPLETE�-�RETURN* PAGALC6:.‰BCLR„#TSK2RTEX,TCBSTAT2(A6)„CLEAR�RET-TO-EXEC ‰MOVE.L‚A3,A0‰ALLOCATION�ADDRESS‰MOVE.L‚D4,D0‰RETURN�CODE*‰BEQ.SƒPAGALC7‡BRANCH�IF�SUCCESSFUL�RETURN &‰ADD.Lƒ#2,24(A7)…CHANGE�RETURN�ADDRESS PAGALC7:,‰MOVEM.L�(A7)+,D3-D5/A3-A5ƒRESTORE�REGISTERS‰RTS‰PAGE**„MEMORY�NOT�AVAILABLE�NOW* ‰IFNE„WAITMEMPAGALC9:#‰BTST„#SGPBOWAI,D1„WAIT�FOR�MEMORY?‰BEQ.SƒPAGAER1‰BRANCH�IF�NO  *.*„PUT�TASK�ON�'WAIT�FOR�MEMORY'�SEMAPHORE�LIST* 1‰BSET„#TSK2RTEX,TCBSTAT2(A6)ƒSET�RET-TO-EXEC�FLAG/‰MOVE.B‚#EXECPRIO,TCBRPRI(A6)„SET�HIGH�PRIORITY)‰LEA…SEMWTMEM(A5),A0„ADDRESS�OF�SEMAPHORE%‰MOVE.L‚A0,TCBXA0(A6)†SAVE�FOR�RETURN )‰MOVE.W‚SR,-(A7)‹SAVE�OLD�INTERRUPT�LEVEL"‰OR.W„' #$0700,SRŠINHIBIT�INTERRUPTS #‰MOVE.W‚(A0),D0ŒGET�SEMAPHORE�COUNT&‰LSL.Wƒ#1,D0ŽSHIFT�OUT�MULTI-PROC�FLAG%‰ASR.Wƒ#1,D0ŽCONVERT�COUNT�TO�16�BITS PAGAWT2:‰SUB.Wƒ#1,D0ŽDECREMENT�COUNT!‰BGE…PAGAWT2ŒSHOULD�NEVER�BE�PLUS ‰MOVE.W‚D0,(A0)ŒRESAVE�COUNT‰BSR…PSWAIT�GO�PUT�TASK�ON�LIST '‰BCLR„#HIBIT,(A0)ˆCLEAR�MULTI-PROC�FLAG,‰MOVE.W‚(A7)+,SR‹RESTORE�OLD�INTERRUPT�LEVEL &‰TR0.READY‚(A6)ŒPUT�TASK�ON�READY�LIST ‰IFNE„SHARMEM#‰BSR…PAGARSM‰RELEASE�ALL�SEMAPHORES‰ENDC $‰BRA…DISPATCH‰GO�RUN�SOME�OTHER�TASK-*�WILL�RETURN�TO�PAGALC1�WHEN�MEMORY�RELEASED‰ENDC  **…ERROR�RETURNS*PAGAER2:-‰ADD.Lƒ#1,D4‡PART#�OR�MEM�TYPE�DOES�NOT�EXIST PAGAER1:$‰ADD.Lƒ#1,D4‡MEM�SPACE�NOT�AVAILABLE‰BRA…PAGALC5…GO�TO�RETURN  ‰IFEQ„WAITMEMPAGALC9‚EQU…PAGAER1‰ENDC‰PAGE**ˆSEARCH�FREE�MEMORY�LIST* PAGASFML:&‰MOVE.L‚LOWFREE(A3),D0„GET�FIRST�ENTRY&‰BEQ.SƒPAGAS9†BRANCH�IF�NO�FREE�MEMORY PAGAS2:&‰MOVE.L‚D0,A2‡POINTER�TO�CURRENT�ENTRY&‰MOVE.L‚A4,D0‡TEST�FOR�ANY�ENTRY�SAVED+‰BEQ.SƒPAGAS6†IF�NONE�SAVED�-�SAVE�THIS�ONE 6‰MOVE.L‚FMLFREE(A2),D5ƒD5�=�FREE�PAGES�-�CURRENT�ENTRY‰CMP.LƒD2,D5ˆIS�CURR�>=�NEED�?"‰BLT.SƒPAGAS4‡BRANCH�IF�NOT�ENOUGH '‰CMP.LƒFMLFREE(A4),D2ƒIS�NEED�>�SAVED�?‰BGT.SƒPAGAS6‡BRANCH�IF�YES '‰CMP.LƒFMLFREE(A4),D5ƒIS�CURR�>�SAVED�?‰BLT.SƒPAGAS6‡BRANCH�IF�NO ‰BRA.SƒPAGAS8‡BRANCH�IF�YES PAGAS4:'‰CMP.LƒFMLFREE(A4),D5ƒIS�CURR�>�SAVED�?‰BLE.SƒPAGAS8†BRANCH�IF�NO PAGAS6: ‰MOVE.L‚A2,A4‡SAVE�CURRENT�ENTRY)‰MOVE.L‚A3,A5‡SAVE�CURRENT�HEADER�ADDRESS PAGAS8:7‰MOVE.L�(A2),D0…GET�FWD�POINTER-NEXT�ENTRY�IN�FREE�LIST$‰BNE„PAGAS2†LOOP�BACK�FOR�NEXT�ENTRY PAGAS9:‰RTS‰PAGE*5*‰FOUND�A�LINK�THAT�HAS�ENOUGH�FREE�SPACE�TO�ALLOCATE* PAGATAK:;‰SUB.L‚D2,FMLFREE(A4)ƒSUBTRACT�PAGED�NEEDED�FROM�FREE�PAGES.‰ADD.L‚D2,FMLUSED(A4)ƒADD�PAGES�NEEDED�TO�USED.‰MOVE.L�FMLFREE(A4),D5ƒNEW�COUNT�OF�FREE�PAGES‰LSL.L‚#8,D5ŒFREE�BYTES-‰LEA„0(A4,D5.L),A3†ADDRESS�OF�SPACE�ALLOCATED+‰BNE.S‚PAGAT4‹BRANCH�IF�NOT�ALL�SPACE�TAKEN  *:*‹FREE�SPACE�IN�THIS�LINK�IS�ALL�USED�UP-DISOLVE�THIS�LINK* !‰MOVE.L�FMLUSED(A4),D5ƒPAGES�USED‰MOVE.L�(A4),A2ŠFORWARD�POINTER%‰MOVE.L�FMLBP(A4),D0…BACKWARD�POINTER+‰BEQ.S‚PAGAT6‹BRANCH�IF�NO�BACKWARD�POINTER  **ŒMERGE�WITH�BACKWARD�LINK* ‰MOVE.L�D0,A1�BACKWARD�POINTERA‰ADD.L‚D5,FMLUSED(A1)„ADD�WHAT�GETS�DISSOLVED�TO�TOTAL�PAGES�USED&‰MOVE.L�A2,(A1)‹BACK'S�NEW�FWD�POINTER‰BEQ.S‚PAGAT4ŒIF�NONE�-�RETURN +‰MOVE.L�A1,FMLBP(A2)†FWD'S�NEW�BACK�POINTER PAGAT4: ‰RTS–SUCCESS  ***ŒNO�BACK�POINTER�--�CHANGE�MASTER�POINTER* PAGAT6:'‰MOVE.L�A2,LOWFREE(A5)„NEW�LOWEST�ENTRY%‰BEQ„PAGAT4ŒRETURN�IF�ALL�MEMORY�GONE #‰CLR.L‚FMLBP(A2)‰CLEAR�BACK�POINTER‰RTS‰PAGE*>*„SAVE�STACK�AND�REGISTERS�IN�CASE�'WAIT�FOR�MEMORY'�IS�NEEDED* ‰IFNE‚WAITMEM PAGASVST:%‰BSR…SVXSTAK†SAVE�STACK�AND�REGISTERS ;‰MOVE.B‚TCBXREGS+3(A6),TCBRPRI(A6)�RESTORE�CURRENT�PRIORITY‰RTS‰ENDC  *%*„RELEASE�FREE�MEMORY�LIST�SEMAPHORES* ‰IFNE„SHARMEMPAGARSM:‰MOVE.L‚(A7)+,A1…SAVE�RETURN PAGARS1:-‰MOVE.L‚(A7)+,D0…GET�ONE�FREE�MEM�LIST�HEADER%‰BEQ.SƒPAGARS2†BRANCH�IF�ALL�RELEASED &‰MOVE.L‚D0,A0ˆPUT�HDR�ADDR�IN�ADDR�REG‰TR0.VƒSEMFRMEM(A0)‰BRA…PAGARS1†GO�GET�NEXT�ONE PAGARS2:‰JMP…(A1)‰RETURN‰ENDC‰PAGE*>*„SEARCH�MEMORY�LIST�FOR�PARTITION�CONTAINING�PHYSICAL�ADDRESS* PAGPHYA:*‰CMP.Bƒ#1,MAPMTYP(A1)ƒCHECK�FOR�NULL�ENTRY‰BEQ…PAGPHY9ŠBRANCH�TO�SKIP '‰TST.WƒMAPMTYP(A1)†MEMORY�TYPE,�IS�ROM?)‰BMI.SƒPAGPA0‹IF�YES,�NO�FML�HEADER�STUFF (‰MOVE.L‚MAPFMLP(A1),A0„A0�-->�FML�HEADER(‰CMP.LƒENDAVAIL(A0),A2ƒPHYS�ADDR�<�TOP�?‰BGE…PAGPHY9ŠBRANCH�IF�NO"‰BRA.SƒPAGPA1‹YES,�GO�CHECK�BOTTOM .PAGPA0:‚CMP.LƒMAPENDA(A1),A2ƒPHYS�ADDR�>�TOP�?‰BGE…PAGPHY9ŠBRANCH�IF�YES 1PAGPA1:‚CMP.LƒMAPSTRA(A1),A2ƒPHYS�ADDR�>=�BOTTOM?+‰BLT…PAGPHY10‰BRANCH�IF�NO�-�CAN'T�ALLOCATE -‰BTST„#SGPBOATR,D1…IS�REQ�FOR�MEM�MAPPED�I/O?(‰BNE' …PAGAER2ŠBRANCH�IF�YES�-�BAD�REQUEST $‰TST.WƒMAPMTYP(A1)†CHECK�MEMORY�TYPE2‰BMI…PAGPHY12‰BRANCH�IF�ROM�-�NO�ALLOCATION�NEEDED 0‰MOVE.L‚MAPFMLP(A1),A5ƒA5�=�FREE�MEM�LIST�HEADER ‰IFNE„SHARMEM‰PEA…(A5)�SAVE�HEADER�ON�STACK‰TR0.PƒSEMFRMEM(A5)‰ENDC  **†FIND�FML�ENTRY* &‰MOVE.L‚LOWFREE(A5),D0‚FIRST�FML�ENTRY.‰BEQ…PAGALC9†BRANCH�IF�NO�MEMORY�AVAILABLE�NOW ‰LSL.Lƒ#8,D2†D2=#�BYTES�NEEDED+‰MOVE.L‚A2,A3†A2=STARTING�ADDRESS�REQUESTED‰ADD.LƒD2,A3†A3=TOP�BOUNDRY‰LSR.Lƒ#8,D2†D2=#PAGES PAGPHY1:#‰MOVE.L‚D0,A4†CURRENT�ENTRY�POINTER*‰CMP.LƒA2,D0†IS�CURRENT�ENTRY�ABOVE�START?,‰BGT…PAGALC9„BRANCH�IF�YES-�MEMORY�NOT�AVAIL #‰MOVE.L‚FMLFREE(A4),D0‚#�FREE�PAGES"‰LSL.Lƒ#8,D0†CHANGE�PAGES�TO�BYTES‰ADD.LƒA4,D0†TOP�BOUNDRY$‰CMP.LƒA2,D0†ADDR�WITHIN�FREE�SPACE?-‰BGT.SƒPAGPHY3„BRANCH�IF�YES�-�USE�THIS�ENTRY ‰MOVE.L‚(A4),D0„FORWARD�POINTER%‰BNE…PAGPHY1„LOOP�BACK�FOR�NEXT�ENTRY %‰BRA…PAGALC9„BRANCH�IF�NO�MORE�MEMORY  *)*…STARTING�ADDRESS�IS�WITHIN�CURRENT�LINK* PAGPHY3:(‰CMP.LƒA3,D0†ENDING�ADDRESS�WITHIN�LINK?"‰BEQ…PAGALC3„BRANCH�IF�PERFECT�FIT )‰BGT.SƒPAGPHY6„BRANCH�IF�MORE�THAN�NEEDED ‰BTST„#SGPBOLES,D1ƒACCEPT�LESS?‰BEQ…PAGALC9„BRANCH�IF�NO &‰SUB.LƒA2,D0†SUBTRACT�ADDRESS�FROM�TOP‰LSR.Lƒ#8,D0†CONVERT�TO�PAGES!‰MOVE.L‚D0,D2†CHANGE�PAGES�NEEDED&‰BRA…PAGALC3„BRANCH�TO�ALLOCATE�MEMORY  *(*†BUILD�ANOTHER�LINK�IN�FREE�MEMORY�LIST3*‰A4=POINTER�TO�CURRENT�LINK…A3=POINTER�TO�NEW�LINK* PAGPHY6:%‰MOVE.L‚(A4),(A3)ƒNEW�FORWARD�POINTER‰BEQ.SƒPAGPHY7…BRANCH�IF�FP=0 ‰MOVE.L‚(A4),A1…FORWARD�ENTRY9‰MOVE.L‚A3,FMLBP(A1)�CHANGE�BACK�POINTER�IN�FORWARD�ENTRY PAGPHY7:*‰MOVE.L‚A3,(A4)…PREV�ENTRY�FORWARD�POINTER+‰MOVE.L‚A4,FMLBP(A3)‚NEW�ENTRY�BACK�POINTER+‰MOVE.L‚FMLUSED(A4),FMLUSED(A3)‚MEMORY�USED*‰CLR.LƒFMLUSED(A4)ƒNONE�USED�IN�PREV�ENTRY'‰SUB.LƒA3,D0‰#�BYTES�FREE�FOR�NEW�ENTRY‰LSR.Lƒ#8,D0‰CONVERT�TO�PAGES(‰MOVE.L‚D0,FMLFREE(A3)‚SAVE�IN�NEW�ENTRY,‰SUB.LƒD0,FMLFREE(A4)‚DEDUCT�FROM�PREV�ENTRY!‰BRA…PAGALC3‡GO�FINISH�ALLOCATION  **ˆNEXT�MEMMAP�ENTRY* PAGPHY9:&‰LEA…MAPENTSZ(A1),A1ƒNEXT�MEMMAP�ENTRY,‰CMP.Wƒ#-1,MAPMTYP(A1)ƒTEST�FOR�END�OF�TABLE#‰BNE…PAGPHYA‹BRANCH�IF�MORE�ENTRIES PAGPHY10:#‰BTST„#SGPBOATR,D1†IS�REQ�FOR�MMIO?!‰BEQ…PAGAER2‹BRANCH�IF�NO�-�ERROR PAGPHY12:‰MOVE.L‚A2,A3�PHYSICAL�ADDRESS‰CLR.LƒD4�RETURN�CODE&‰BRA…PAGALC4‹BRANCH�TO�COMPLETE�RETURN‰ENDé=/*=/*†M68XXX.PAGEFREE.AF=/*-=/* Chain file to assemble M68XXX.PAGEFREE.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.PAGEFREE.LS=/*=/IFC \1ƒ=ARG�M68XXX.PAGEFREE.LS=/ENDIF=/*5=ASM M68XXX.PAGEFREE.SA,M68XXX.PAGEFREE.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.MAP.EQ=/*}=/*=ENDééé( éééó‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.MAP.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.MAP.EQ‰LIST‰PAGE4PAGEFREE‚IDNT�5,1�68xxx�TRAP�0--FREE�PHYSICAL�MEMORY *¸3-6-79�GGC3$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*%*„PAGEFREE‚--‚REV�2.00ƒ5/25/79‚(HLD6)*�2/18/81‚(HLD6)*Ž--‚TRAP�0�ROUTINE***„FREE�PAGES�EXEC�ROUTINE0*…ENTRY:�A0=STARTING�ADDRESS�OF�1ST�PAGE�TO�FREE*ŒD1=NUMBER�OF�PAGES�TO�FREE**…EXIT�:�SUCCESS‚RTS*ŒFAILEDƒRTS�TO�PC+2 *’01234567* USES REGISTERS D ****�A�*****‰SECTION�LEVEL01*‰XDEF„PAGEFREE ‰XDEF„SBPGFR ‰XREF.S‚MAPBEG‰PAGESBPGFR: PAGEFREE:#‰MOVEM.L�A4-A5,-(A7)‚SAVE�REGISTERS‰MOVE.L‚D1,D2ˆSEE�IF�PAGES�<=0‰BGT.SƒPGFRM1‡BRANCH�IF�NO PGFRER1:&‰MOVEM.L�(A7)+,A4-A5‚RESTORE�REGISTERS,‰ADD.Lƒ#2,(A7)…CHANGE�RETURN�ADDRESS�-�ERROR PGFRTN1:‰RTS PGFRM1:#‰MOVE.L‚A0,A2ˆSAVE�STARTING�ADDRESS%‰MOVE.L‚MAPBEG,A1„START�OF�MEMORY�MAP‰PAGE*3*„LOOK�FOR�MEMORY�PARTITION�CONTAINING�THIS�ADDRESS* PGFRM2:+ˆCMP.B„#-1,MAPMTYP(A1)�CHECK�FOR�NULL�ENTRY'ˆBEQ.S„PGFRM4‡BRANCH�TO�SKIP�NULL�ENTRY ,ˆMOVE.LƒMAPFMLP(A1),A5ƒADDRESS�OF�FML�HEADER'ˆCMP.L„ENDAVAIL(A5),A2ˆPHYS�ADDR�<�TOP?ˆBGE.S„PGFRM4‡BRANCH�IF�NO )ˆCMP.L„MAPSTRA(A1),A2ƒPHYS�ADDR�>=BOTTOM?#ˆBLT.S„PGFRER1†BRANCH�IF�NO�-�ERROR $ˆTST.W„MAPMTYP(A1)‚CHECK�MEMORY�TYPEˆBMI†PGFRTN1†RETURN�IF�ROM #ˆLSL.L„#8,D1ˆCONVERT�PAGES�TO�BYTES#ˆADD.L„A2,D1ˆD1=TOP�OF�AREA�TO�FREE5ˆCMP.L„ENDAVAIL(A5),D1‚IS�AREA�PAST�END�OF�PARTITION?"ˆBHI†PGFRER1†BRANCH�IF�YES�-�ERROR &ˆBRA.S„PGFRML1†GO�SEARCH�FREE�MEM�LIST PGFRM4:&ˆLEA†MAPENTSZ(A1),A1‚NEXT�MEMMAP�ENTRY$ˆCMP.W„#-1,MAPMTYP(A1)‚END�OF�TABLE?ˆBNE†PGFRM2‡BRANCH�IF�NO %ˆBRA†PGFRER1†MEMORY�NOT�FOUND�-�ERRORˆPAGE**ƒSEARCH�FREE�MEMORY�LIST* PGFRML1:7ˆLEA†0,A1…INITIALIZE�POINTER�TO�AREA�CONTAINING�ADDRESS ˆIFNE…SHARMEMˆTR0.P„SEMFRMEM(A5)ˆENDC 5ˆMOVE.L‚LOWFREE(A5),D3„START�CHECKING�AT�LOWEST�ENTRYücN :*ˆBEQ.SƒPGFRML4†THERE�IS�NO�MEMORY�FREE�NOW PGFRML2:#ˆMOVE.L‚D3,A0ˆADDRESS�OF�NEXT�ENTRY.ˆCMP.LƒD1,A0ˆIS�AREA�TO�FREE�BELOW�THIS�ENTRY?ˆBGE.SƒPGFRML3†BRANCH�IF�YES &ˆMOVE.L‚A0,A1ˆNO�-�ENTRY�PRECEDES�AREA#ˆMOVE.L‚(A0),D3†GET�FORWARD�POINTERˆBNE.SƒPGFRML2†GO�TEST�IT PGFRML3:(ˆMOVE.L‚A1,D0‡ADDRESS�OF�PRECEEDING�AREAˆBEQ.SƒPGFRML4…THERE�IS�NONE 1ˆMOVE.L‚FMLFREE(A1),D0„#�PAGES�IN�PRECEEDING�AREAˆLSL.Lƒ#8,D0‡CONVERT�TO�BYTES'ˆADD.LƒA1,D0‡END�OF�PRECEEDING�AREA�+�1!ˆCMP.LƒD0,A2‡IS�THERE�AN�OVERLAP?ˆBLT…PGFRER2…YES�--�ERRORˆPAGE*%*‚OK�TO�FREE�PAGES�--�BUILD�NEW�ENTRY$*ƒA2�=�STARTING�ADDR�OF�AREA�TO�FREE+*ƒA1�=�ADDR�OF�LINK�PRECEEDING�AREA�TO�FREE&*ƒD1�=�ENDING�ADDR�+�1�OF�AREA�TO�FREE*ƒD2�=�NUMBER�OF�PAGES�TO�( FREE8*ƒD3�=�ADDR�OF�LINK�FOLLOWING�AREA�TO�FREE�(OR�ENDAVAIL)* PGFRML4:,ˆMOVE.L‚D2,FMLFREE(A2)„NUMBER�OF�PAGES�FREEDˆMOVE.L‚D3,D0�*‚TOP�BOUNDRYˆBNE.SƒPGFRML5‹*‚IS�TOP�=�0? 3ˆMOVE.L‚ENDAVAIL(A5),D0ƒ*‚YES�-�USE�ENDAVAIL�AS�TOP PGFRML5:$ˆSUB.LƒD1,D0�*‚-�END�OF�AREA�TO�FREEˆLSR.Lƒ#8,D0�*‚CONVERT�TO�PAGES'ˆMOVE.L‚D0,FMLUSED(A2)„*‚=�#�PAGES�USEDˆMOVE.L‚D3,(A2)‹FORWARD�POINTER%ˆMOVE.L‚A1,FMLBP(A2)†BACKWARD�POINTERˆBNE.SƒPGFRML6 &ˆMOVE.L‚A2,LOWFREE(A5)„NEW�LOWEST�LINKˆBRA.SƒPGFRML7ˆPAGE*(*ƒMERGE�WITH�PRECEEDING�AREA�IF�POSSIBLE* PGFRML6:+ˆMOVE.L‚A2,(A1)ˆCHANGE�PRE-LINK�FORWARD�PTRˆMOVE.L‚A2,D0Š*‚TOP�BOUNDRYˆSUB.LƒA1,D0Š*‚-�START�OF�AREAˆLSR.Lƒ#8,D0Š*‚CONVERT�TO�PAGES$ˆSUB.LƒFMLFREE(A1),D0�*‚-�PAGES�FREE2ˆMOVE.L‚D0,FMLUSED(A1)�*�=�PAGES�USED�(PREV�ENTRY)4ˆBNE.SƒPGFRML7ˆTHERE�ARE�SOME�-�CANNOT�MERGE�ENTRIES ˆMOVE.L‚FMLFREE(A2),D0&ˆADD.LƒD0,FMLFREE(A1)�TOTAL�PAGES�FREE*ˆMOVE.L‚FMLUSED(A2),FMLUSED(A1)‚PAGES�USED%ˆMOVE.L‚(A2),(A1)…NEW�FORWARD�POINTER ˆMOVE.L‚A1,A2  *'*…MERGE�WITH�FOLLOWING�AREA�IF�POSSIBLE* PGFRML7: ˆTST.LƒD3$ˆBEQ.SƒPGFRML9†THERE�IS�NO�NEXT�LINK "ˆMOVE.L‚D3,A1ˆADDRESS�OF�NEXT�LINK,ˆMOVE.L‚A2,FMLBP(A1)�CHANGE�BACKWARD�POINTER0ˆTST.LƒFMLUSED(A2)‚ANY�PAGES�USED�BETWEEN�LINKS?"ˆBNE.SƒPGFRML9†YES�-�CAN�NOT�MERGE ˆMOVE.L‚FMLFREE(A1),D0&ˆADD.LƒD0,FMLFREE(A2)�TOTAL�PAGES�FREE*ˆMOVE.L‚FMLUSED(A1),FMLUSED(A2)‚PAGES�USED%ˆMOVE.L‚(A1),(A2)†NEW�FORWARD�POINTERˆBEQ.SƒPGFRML9ˆFORWARD�PTR�IS�0 ˆMOVE.L‚(A2),A1%ˆMOVE.L‚A2,FMLBP(A1)…NEW�BACKWARD�PTRˆPAGE*&*‚RELEASE�ALL�USERS�WAITING�FOR�MEMORY*PGFRML9: ‰IFNEƒWAITMEM‰MOVE.B�MEMTYPE(A5),D1#‰AND.B‚#$F0,D1‰GET�MEMORY�TYPE�ONLY%‰MOVE.L�MAPBEG,A1‡START�OF�MEMORY�MAP PGFREL2:/‰CMP.B‚MAPMTYP(A1),D1‚DOES�MEMORY�TYPE�COMPARE?‰BNE.S‚PGFREL6‰BRANCH�IF�NO /‰MOVE.L�MAPFMLP(A1),A4‚FREE�MEMORY�LIST�POINTER PGFREL4:%‰BTSTƒ#6,SEMWTMEM(A4)�ANYONE�WAITING?#‰BEQ.S‚PGFREL6‰BRANCH�IF�NO�WAITORS ‰TR0.V‚SEMWTMEM(A4)(‰BRA„PGFREL4‰GO�BACK�TO�FREE�ALL�WAITORS PGFREL6:&‰LEA„MAPENTSZ(A1),A1‚NEXT�MEMMAP�ENTRY$‰CMP.W‚#-1,MAPMTYP(A1)‚END�OF�TABLE?‰BNE„PGFREL2‰BRANCH�IF�NO ‰ENDC PGFRENDR: ‰IFNEƒSHARMEM‰TR0.V‚SEMFRMEM(A5)‰ENDC &‰MOVEM.L�(A7)+,A4-A5ƒRESTORE�REGISTERS ‰RTS�RETURN  **…ERROR�-�PAGES�CANNOT�BE�FREED* PGFRER2:"‰ADD.L‚#2,(A7)„INCREMENT�RETURN�PC ‰BRA„PGFRENDR‰ENDééé=/*=/*†M68XXX.PAUSE.AF=/**=/* Chain file to assemble M68XXX.PAUSE.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.PAUSE.LS=/*=/IFC \1ƒ=ARG�M68XXX.PAUSE.LS=/ENDIF=/*/=ASM M68XXX.PAUSE.SA,M68XXX.PAUSE.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDé) ééééé‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE3PAUSE„IDNTƒ5,1…68xxx�TRAP�0--PAUSE�DURING�EXEC�TOUR*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�PAUSE„2.00„**ˆ*’**ˆ*�7616ƒ06/29/79‚**ˆ*�HLD6ƒ02/08/81‚**ˆ*********************(*…PAUSE�WHILE�WAITING�FOR�IO�TO�COMPLETE*%*…REGISTER�USAGE:�ALL�REGISTERS�SAVED*‰SECTION�LEVEL00* ‰XDEFƒPAUSE ‰XDEFƒSBPAUSE ‰XREFƒDISPATCH ‰XREFƒSVXSTAK‰PAGE*.*ˆPUT�THIS�TASK�TO�SLEEP�(STORE�THE�REGISTERS)*ˆAND�JUMP�TO�THE�DISPATCHER* SBPAUSE:PAUSE:<‰MOVE.B„#EXECPRIO,TCBLPRI(A6)‰TASK�IN�TERM�-�SET�PRIORITY�HI‰BSR‡SVXSTAK—SAVE�EXEC�STACK(‰BRA‡DISPATCH–GO�START�UP�SOME�OTHER�JOB‰ENDéééé.=/*=/*†M68XXX.POWRFAIL.AF=/*-=/* Chain file to assemble M68XXX.POWRFAIL.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.POWRFAIL.LS=/*=/IFC \1ƒ=ARG�M68XXX.POWRFAIL.LS=/ENDIF) =/*5=ASM M68XXX.POWRFAIL.SA,M68XXX.POWRFAIL.RO,\1;MRZ=040=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*}=/*=ENDéééééé'‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰LIST‰PAGE4POWRFAIL�IDNTƒ5,1ƒ68xxx�POWER�FAIL�INTERRUPT�HANDLER*ˆ*********************ˆ*�POWRFAIL�1.00„**ˆ*’**ˆ*�HLD6ƒ06/24/81‚**ˆ**********************…POWER�FAIL�INTERRUPT�ROUTINE*@*…THIS�ROUTINE�IS�USED�ONLY�TO�RESPOND�TO�A�POWER�FAIL�INTERRUPT-*…ON�A�VERSAMODULE�01�(AUTO�VECTOR�-�LEVEL�7)*%*…REGISTER�USAGE:�ALL�REGISTERS�SAVED*‰SECTION�LEVEL00**‰XDEFƒPOWRFAIL‰XREF.S�CRASHSAV‰PAGE POWRFAIL:2‰MOVEM.L�D0-D7/A0-A7,CRASHSAV+8ƒSAVE�ALL�REGISTERS'‰MOVE.W‚(A7),CRASHSAV+6ŠSAVE�STATUS�REG+‰MOVE.L‚2(A7),CRASHSAV‹SAVE�PROGRAM�COUNTER  D*********************************************************************7*„CODE�TO�CALL�A�POWER�FAIL�ROUTINE�CAN�BE�ENTERED�HERE*D********************************************************************  *)*ˆIf�there�is�a�return,�reload�registers.* !‰OR.W„#$700,SR†INHIBIT�INTERRUPTS5‰MOVEM.L�CRASHSAV+8,D0-D7/A0-A7ƒRESTORE�ALL�REGISTERS ‰RTE“GO�BACK‰ENDééé* 03=/*=/*†M68XXX.PSTATE.AF=/*+=/* Chain file to assemble M68XXX.PSTATE.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.PSTATE.LS=/*=/IFC \1ƒ=ARG�M68XXX.PSTATE.LS=/ENDIF=/*1=ASM M68XXX.PSTATE.SA,M68XXX.PSTATE.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééééé9‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE;PSTATEƒIDNTƒ5,1„68xxx�DIRECTIVE--SET�STATE�OF�EXMON'ED�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡**************************2*‡*‚P�S�T�A�T�E‹*ƒSET�CURRENT�STATE�OF�TARGET�TASK*‡*‚REV�3.00�11/25/81�HLD6**‡*‹07/15/81…**‡*****************************‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A0�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�TASK�NAME�OF�TARGET�TASK*—4�-�SESSION�CODE*—8�-�ADDRESS�OF�BUFFER**‹EXIT�:�D0�HAS�RETURN�CODE*’D0�=�0„GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST5*ŠRTCDSTAT�-10ƒTARGET�TASK�NOT�WAITING�FOR�THIS�EXMON0*ŠRTCDADR1�-12ƒBUFFER�NOT�IN�CALLER'S�ADDR�SPACE**‰SECTION�LEVEL04* ‰XDEF†PSTATE ‰XREF.S„EXMONVR‰PAGEPSTATE:.‰MOVE.L„A4,A3”Save�address�of�parameter�block.-‰BTST†#TSKSWTEM,TCBSTATE(A5)ƒIS�TASK�WAITING?.‰EXIT.EQƒRTCDSTAT‘ERROR�-�Task�is�not�waiting. **ˆCheck�for�valid�request.* 1PSPBLEN‚EQU‡74’Equate�for�parameter�block�length.!‰MOVE.L„#PSPBLEN,D5‰BUFFER�LENGTH2‰BSR‡EXMONVR�DON'T�COME�BACK�UNLESS�VALID�REQUEST.  * *ˆPut�data�from�buffer�into�tcb.* ‰MOVE.L„D6,A4”ADDRESS�OF�BUFFER$‰LEA‡TCBD0(A5),A1�REGISTER�SAVE�AREA‰MOVE.W„#16-1,D0 PSTA* T6:2‰MOVE.L„(A4)+,(A1)+ŽMOVE�REGISTERS�D0-D7�AND�A0-A7,‰DBRA†D0,PSTAT6�DECREMENT�COUNT�OF�REGISTERS 6‰MOVE.L„TCBD0(A5),TCBXREGS(A5)ƒCHANGE�D0�FOR�EXEC�ALSO4‰MOVE.L„TCBA0(A5),TCBXA0(A5)…CHANGE�A0�FOR�EXEC�ALSO,‰MOVE.L„(A4)+,TCBPC(A5)ŠMOVE�PROGRAM�COUNTER%‰MOVE.W„(A4)+,D0‘MOVE�STATUS�REGISTER$‰MOVE.B„TCBEMMSK(A5),D6ŠSAVE�OPTIONS*‰MOVE.L„(A4)+,TCBEMMSK(A5)‡MOVE�EXMON�MASK'‰AND.B…#$03,TCBEMMSK(A5)ˆSAVE�ONLY�MASK‰AND.B…#$F8,D6’OPTIONS)‰OR.B†D6,TCBEMMSK(A5)ŠRESTORE�OLD�OPTIONSBSK'‰MOVE.B„D0,TCBCC(A5)�SAVE�COND�CODE�REG =‰BTST†#TSK2RTEX,TCBSTAT2(A5)ƒIf�the�task�is�not�in�the�return&‰EXIT.EQƒSUB–to�exec�state,�then�exit. -PSTATA6‚EQU‡$38–Equates�for�fields�within�the'PSTATSR‚EQU‡$44–pstate�parameter�block.PSTATPC‚EQU‡$40 *°Else,�move�the,‰MOVE.L„PSTATA6-PSPBLEN(A4),TCBSTKA6(A5)†A6,0‰MOVE.W„PSTATSR-PSPBLEN(A4),TCBSTKSR(A5)†SR,�and<‰MOVE.L„PSTATPC-PSPBLEN(A4),TCBSTKPC(A5)†PC,�from�the�pstate*°parameter�block,�to�the *°exec�stack,‰EXIT†SUB›and�exit. ‰ENDééééé‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.ENV.EQ*ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.ENV.EQ‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE‰IFEQƒCHIPTYPE-68000.PVSEM„IDNTƒ5,1†68000�TRAP�0--SEMAPHORE�ROUTINE‰ENDC‰IFEQƒCHIPTYPE-68010.PVSEM„IDNTƒ5,1†68010�TRAP�0--SEMAPHORE�ROUTINE‰ENDC*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�PSEM4‡2.00�**ˆ*�GGC3�03/02/79„**ˆ*�7616�05/18/79„**ˆ*�HLD6�02/08/81„**ˆ*********************$*ƒ'P'‚SEMAPHORE‚CHECKER�EXEC�ROUTINE@*ˆROUTINE�IS�USED�TO�QUEUE�UP�TASK�FOR�EXCLUSIVE�USE�OF�RESOURCE'*ˆENTRY:ƒA0‚POINTS�TO�SEMAPHORE�ADDRESS0*�(A0)�HAS�TEST�AND�SET�FLAG�FOR�MULTIPROCESSORS9*�(A0)�(15�BITS)�HAS�NUMBER�DEEP�IN�WAIT�LIST�0=AVAILABLE.*�2(A0)�ADDRESS�OF�1ST�TCB�IN�WAIT�LINKED�LIST#*‘A6‚HAS�ADDRESS�OF�REQUESTOR'S�TCB?*ˆEXIT:‚IF�RESOURCE�AVAILABLE-MARK�AS�BUSY�AND�RTE�BACK�TO�TASK:*�IF�BUSY-PUT�TASK�TO�SLEEP,�PUT�ON�WAIT�LIST,�BRA�TO�DISP*&*ˆREGISTER�USAGE:�NONE�LOST�OR�CHANGED*‰SECTION�LEVEL00* ‰XDEFƒSBP ‰XDEFƒPSEM ‰XREF.S�DISPATCH‰XREF.S�EXCSTACK‰XREF.S�KILLER‰PAGESBP:PSEM:-‰MOVE.W�SR,-(A7)„Save�current�interrupt�level=‰OR.Wƒ#$700,SR„TURN�OFF�INTERRUPTS‚???+ ??????????????????????? PSEM_10:*‰TAS�(A0)ŒTEST-AND-SET�MULTIPROCESSOR�FLAG0‰BMI.S�PSEM_10‡THIS�FLAG�MUST�BE�ZERO�TO�PROCEED ‰MOVE.W�(A0),D0†GET�USE�COUNT+‰LSL.W‚#1,D0ˆSHIFT�OUT�MULTI-PROCESSOR�FLAG!‰ASR.W‚#1,D0ˆMAKE�COUNT�=�16�BITS‰SUB.W‚#1,D0ˆDECREMENT�COUNT>‰MOVE.W�D0,(A0)†RESAVE�IT�(IF�POS,�ALSO�CLEAR�MULTI-PROC�FLAG)5‰BMI.S�PSEM_20‡NEGATIVE�(LESS�THAN�ZERO)�MEANS�IN�USE 1‰MOVE.W�(A7)+,SR…Restore�previous�interrupt�level‰RTS’RETURN�TO�CALLER  *1*ˆSOME�OTHER�TASK�IS�USING�THIS�CRITICAL�RESOURCE.*ˆPUT�THIS�TASK�TO�SLEEP�(STORE�THE�REGISTERS)1*ˆPUT�THE�TASK�IN�THE�WAIT�LIST�FOR�THIS�RESOURCE*ˆAND�JUMP�TO�THE�DISPATCHER* PSEM_20:'‰BSR.S‚SVXSTAK…SAVE�STACK�AND�REGISTERS SQ\QdKl-‰SUB.B‚#2,TCBSSP(A6)�Remove�SR�from�TCB�stack-‰BSR.S‚PSWAIT†PUT�TASK�ON�SEMAPHORE�WAIT�LIST +‰BCLRƒ#HIBIT,(A0)�CLEAR�MULTIPROCESSOR�FLAG!‰MOVE.W�(A7)+,SR„ALLOW�INTERRUPTS&‰TR0.READY‚(A6)…PUT�TASK�ON�READY�LIST(‰BRA�DISPATCH‚GO�START�UP�SOME�OTHER�JOB‰PAGE*6*†SUBROUTINE�PSWAIT�--�PUT�TASK�ON�SEMAPHORE�WAIT�LIST* ,‰XDEF‚PSWAIT„PUT�TASK�ON�SEMAPHORE�WAIT�LIST  PSWAIT:1‰BSET�#TSKSSMWT,TCBSTATE(A6)„BLOCKED�ON�SEMAPHORE-‰CLR.L�TCBSEM(A6)ŒNO�LINK�TO�NEXT�SEM4�WAITER&‰MOVE.L�2(A0),D0�CHECK�1ST�TCB�IN�LINK%‰BNE.S‚PSWAI_10�NONZERO=THERE�WAS�ONE 2‰MOVE.L�A6,2(A0)�CURRENT�TASK�IS�ONLY�TASK�ON�LIST‰RTS PSWAI_10: ‰MOVE.L�D0,A5�CURRENT�LIST�ENTRY7‰MOVE.L�TCBSEM(A5),D0ˆGET�LINK�TO�NEXT�TCB�IN�WAIT�LIST.‰BNE.S‚PSWAI_10�BRANCH�IF�THIS�IS�NOT�LAST�ONE :‰MOVE.L�A6,TCBSEM(A5)‚PUT�CURRENT�TASK�AT�END�OF�WAIT�LIST‰RTS‰PAGE*@*…SUBROUTINE�SVXSTAK�--�SAVE�REGISTERS�AND�EXEC�STACK�TO�PREPARE*›FOR�RETURN�TO�EXEC* +‰XDEF„SVXSTAK„SAVE�EXEC�STACK�AND�REGISTERS  SVXSTAK:$‰MOVEM.LƒA4-A5,-(A7)“Save�registers. 1‰MOVE.B„TCBRPRI(A6),D0�Save�priority�for�restore.0‰MOVE.B„#EXECPRIO,TCBRPRI(A6)‰Set�exec�priority.4‰BSET†#TSK2RTEX,TCBSTAT2(A6)ˆSet�'ret�to�exec'�flag. :‰MOVEM.LƒD0-D7/A0-A6,TCBXREGS(A6)†Save�the�exec�registers,,‰MOVE.L„USP,A4˜and�the�user's�stack�pointer.‰MOVE.L„A4,TCBUSP(A6)  **ˆCheck�stack�depth.* 5‰MOVE.L„EXCSTACK,D0‰Get�bottom�of�exec�stack�into�D0. 0‰LEA‡12(A7),A5‹Adjust�stack�for�subroutine�call.%‰SUB.L…A5,D0�D0�contains�stack�depth.;‰CMP.L…#TCBROOM,D0‰Is�there�room�in�the�tcb�for�this�stack.‰BGT.S…NO_ROOM�Branch�if�no.  **ˆSave�the�system�stack�depth,*ˆand�get�pointer�into�tcb.* 2‰MOVE.B„D0,TCBSSP(A6)‘Save�the�system�stack�depth.,‰LEA‡$100(A6),A4“Get�a�pointer�into�the�tcb,(‰SUB.L…D0,A4™equivalent�in�depth�to�ssp.  *%*ˆSave�the�system�stack�into�the�tcb.* /‰LSR.W…#2,D0�Prepare�counter�for�longword�move.,‰BCC.S…TEST�Branch�if�no�extra�word�to�move. (‰MOVE.W„(A5)+,(A4)+‰Move�the�extra�word,-‰BRA.S…TEST�and�go�to�check�for�more�to�move. LOOP:$‰MOVE.L„(A5)+,(A4)+‰Move�a�longword. TEST:%‰DBRA†D0,LOOP�Check�for�more�to�move. '‰MOVEM.Lƒ(A7)+,A4-A5†Restore�registers. ‰RTS›Done. NO_ROOM: ‰BSR‡KILLER*‰PAGE*ˆ*********************ˆ*�VSEM4‡2.00�* *ˆ*�GGC3�**ˆ*�7616�05/18/79„**ˆ*�HLD6�02/08/81„**ˆ*********************ƒ'V'‚SEMAPHORE�ROUTINE%*ˆRELEASE�EXCLUSIVE�USE�OF�A�RESOURCE*ˆENTRY:ƒA0‚POINTS�TO�SEMAPHORE0*�(A0)�HAS�TEST�AND�SET�FLAG�FOR�MULTIPROCESSORS9*�(A0)�(15�BITS)�HAS�NUMBER�DEEP�IN�WAIT�LIST�0=AVAILABLE.*�2(A0)�ADDRESS�OF�1ST�TCB�IN�WAIT�LINKED�LIST *‘A6‚HAS�ADDRESS�OF�CALLER'S�TCB(*ˆEXIT:‚IF�NO�TASK�IN�WAIT�LIST�JUST�RTE2*�IF�SOMEONE�IS�WAITING-TRANSFER�1ST�TO�READY�LIST *›01234567*ˆREGISTER�USAGE:‚D�**™A�P*‰SECTION�LEVEL00* ‰XDEFƒSBV ‰XDEFƒVSEM‰PAGESBV:VSEM:!‰MOVE.W�SR,-(A7)„SUBROUTINE�ENTRY=‰OR.Wƒ#$700,SR„TURN�OFF�INTERRUPTS‚?????????????????????????? VSEM+ _10:*‰TAS�(A0)ŒTEST-AND-SET�MULTIPROCESSOR�FLAG0‰BMI.S�VSEM_10‡THIS�FLAG�MUST�BE�ZERO�TO�PROCEED ‰MOVE.W�(A0),D0†USE�COUNT+‰LSL.W‚#1,D0ˆSHIFT�OUT�MULTI-PROCESSOR�FLAG‰ASR.W‚#1,D0ˆMAKE�COUNT=16�BITS ‰ADD.W�#1,D0‰INCREMENT�USE�COUNT'‰BLE.S�VSEM_20‡BRANCH�IF�TASK�TO�ENABLE :‰MOVE.W�D0,(A0)†RESAVE�USE�COUNT�AND�RESET�MULTI-PROC�FLAG1‰MOVE.W�(A7)+,SR…Restore�previous�interrupt�level‰RTS‘RETURN�TO�CALLER  *7*ˆSOME�OTHER�TASK�IS�WAITING�FOR�THIS�CRITICAL�RESOURCE7*ˆTHE�CURRENT�TASK�WE�ARE�RUNNING�IS�GIVING�IT�UP�SO...4*ˆFIND�THE�1ST�WAITER�AND�TRANSFER�IT�TO�READY�QUEUE* VSEM_20:!‰MOVE.L�A1,-(A7)…SAVE�CALLER'S�A11‰MOVE.L�2(A0),A1…GET�THE�1ST�TCB�IN�THE�WAIT�LIST5‰MOVE.L�TCBSEM(A1),2(A0)‚UNLINK...NEW�1ST�ONE�IN�LIST)‰BCLRƒ#HIBIT,D0ƒCLEAR�MULTIPROCESSOR�FLAG‰MOVE.W�D0,(A0)…SAVE�USE�COUNT'‰CLR.L‚TCBSEM(A1)ƒSET�NO�SEMAPHORE�LINK;‰BCLRƒ#TSKSSMWT,TCBSTATE(A1)„CLEAR�'WAIT�ON�SEMAPHORE'�FLAG#‰MOVE.L�(A7)+,A1…RESTORE�CALLERS�A1+‰MOVE.W�(A7)+,SR…Restore�previous�interrupt‰RTS‘CONTINUE�ON�WITH�TASK‰ENDééééééé„'M68XXX RCVSA AF€€qqRCVSA SA‰‰ ŠqqRDTIMER AFššqqRDTIMER SA££ \qqREADY AF´´qqREADY SA½½ÃqqRELINQ AFÖÖqqRELINQ SAßß*qqRESUME AFèèqqRESUME SAññ9qqREXMON AFúúqqREXMON SA �qqRMS AFqqRMS SA|qqRMSPATCHAF..qqRMSPATCHSA77$qqRQSTPA AF@@qqRQSTPA SAII"PqqRSTATE AFrrqqRSTATE SA{{ dqq, =/*=/*†M68XXX.RCVSA.AF=/**=/* Chain file to assemble M68XXX.RCVSA.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.RCVSA.LS=/*=/IFC \1ƒ=ARG�M68XXX.RCVSA.LS=/ENDIF=/*/=ASM M68XXX.RCVSA.SA,M68XXX.RCVSA.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.SEG.EQ=/*}=/*=ENDééééééx‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.SEG.EQ‰LIST‰PAGE:RCVSA„IDNTƒ5,1„68xxx�DIRECTIVE--RECEIVE�SEGMENT�ATTRIBUTES*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*„RCVSAƒ--�REV�2.00ƒ09/30/81‚(HLD6)*Œ--�TRAP�1�ROUTINE*%*…PURPOSE:‚RECEIVE�SEGMENT�ATTRIBUTES*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS(*‘A4�HAS�SEGMENT�PARAMETER�BLOCK�ADDRESS*–0�-�TARGET�TASK�NAME*–4�-�SESSION�CODE *–8�-�OPTIONS/*šBIT�14,�SEGMENT�IDENTIFIED�BY�LOGICAL�ADDRESS#*¢(ELSE�IDENTIFIED�BY�SEGMENT�NAME)+*šBIT�13,�RETURN�ONLY�LOGICAL�ADDRESS�IN�A0*¢(NO�BUFFER�PROVIDED)*•12�-�SEGMENT�NAME*•16�-�LOGICAL�ADDRESS#*•24�-�BUFFER�ADDRESS‚(IF�BIT�13=0)*ŠEXIT:ƒD0�HAS�RETURN�CODE)*’D0�=�0‚GOOD�RETURN,�SEGMENT�DEALLOCATED*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST'*ŠRTCDNFND�-�7ƒSEGMENT�NOT�FOUND�IN�TST;*ŠRTCDADR1�-12ƒBUFFER�ADDRESS�NOT�IN�CALLER'S�ADDRESS�SPACE*‰SECTION�LEVEL03* ‰XDEF„RCVSA‰PAGERCVSA:"‰MOVE.W‚SGPBOPT(A4),D7„GET�OPTIONS.‰BTST„#SGPBOPAD,D7†WANT�PHYSICAL�ADDRESS�ONLY?‰BNE.SƒRCVSA5A  **ˆGet�output�buffer�address.* +‰TR0.LOGPHY‚,SGPBBUFF(A4),#18%‰BRA.SƒRCVSA5ŠBRANCH�IF�ADDRESS�FOUND ‰NOP&‰EXIT„RTCDADR1ŠERROR�-�BAD�BUFFER�ADDR  **ˆFind�segment�in�target�tst.* RCVSA5:!‰MOVE.L‚D6,A2‰SAVE�BUFFER�ADDRESS RCVSA5A:.‰BTSTƒ#SGPBOLAD,SGPBOPT(A4)‚IS�LOG�ADDR�GIVEN?‰BEQ.SƒRCVSA6�BRANCH, �IF�NO (‰TR0.LOGPHY‚,SGPBLA(A4),#4 ‰BRA.SƒRCVSA8 ‰BRA.SƒRCVSA5E ‰TST.WƒD5‰NOTHING�FOUND? ‰BEQ.SƒRCVSA5E„BRANCH�IF�NOTHING *‰TST.BƒTSTCTL+1(A0,A5)„IS�IT�MMIO�SEGMENT?‰BNE.SƒRCVSA8†BRANCH�IF�YES RCVSA5E:�]Š.(‰EXIT„RTCDNFND�ERROR�-�SEGMENT�NOT�FOUND  *"*ˆFind�segment�using�segment�name.* RCVSA6:'‰TR0.FNDSEG‚,SGPBNAME(A4)%‰BRA.S…RCVSA8ŠBRANCH�IF�SEGMENT�FOUND ‰BRA‡RCVSA5E  *%*ˆMove�segment�information�to�buffer.*  RCVSA8ƒCLR.LƒD0)‰MOVE.W‚TSTLB(A0,D5),D0ˆPHYS�OFFSET�TO�D07‰BTST„#SGPBOPAD,SGPBOPT(A4)‚WANT�PHYSICAL�ADDRESS�ONLY?‰BNE.SƒRCVSA10�BRANCH�IF�YES "‰ADD.WƒTSTPO(A0,D5),D0ˆ+�LOG�BEGIN‰LSL.L‚#8,D0“*�256�=�PHYS�ADDR*‰MOVE.L‚D0,14(A2)�SAVE�PHYS�ADDR�IN�BUFFER‰CLR.LƒD0ˆCLEAR�FOR�SHORT�LOAD4‰MOVE.L‚TSTANAME(A0,D5),0(A2)ƒSEGMENT�NAME�IN�BUFFER(‰MOVE.W‚TSTAATTR(A0,D5),4(A2)ƒATTRIBUTES1‰BCLR„#SEGAUSED,4(A2)ˆCLEAR�'RESVED�FOR�EXEC'�BIT%‰MOVE.W‚TSTLB(A0,D5),D0ˆLOGICAL�BEGIN‰LSL.Lƒ#8,D0’CHANGE�TO�BYTES'‰MOVE.LƒD0,6(A2)ŽSAVE�BEGINNING�ADDRESS ‰CLR.LƒD0#‰MOVE.W‚TSTLE(A0,D5),D0ˆLOGICAL�END‰LSL.L‚#8,D0“CHANGE�TO�BYTES‰ADD.Bƒ#$FF,D0�END�OF�PAGE$‰MOVE.L‚D0,10(A2)ŽMOVE�END�TO�BUFFER!‰EXIT†SUB’exit�(subroutine�exit); RCVSA10:$‰LSL.Lƒ#8,D0’CONVERT�PAGE�TO�ADDRESS.‰MOVE.L‚D0,TCBA0(A6)‹PUT�LOGICAL‚ADDRESS�IN�A0!‰EXIT†SUB’exit�(subroutine�exit);‰ENDééé=/*=/*†M68XXX.RDTIMER.AF=/*,=/* Chain file to assemble M68XXX.RDTIMER.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.RDTIMER.LS=/*=/IFC \1ƒ=ARG�M68XXX.RDTIMER.LS=/ENDIF=/*1=ASM M68XXX.RDTIMER.SA,M68XXX.RDTIMER.RO,\1;RZ=46=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDéééé- éé’-RDTIMERƒIDNTƒ5,1�M68xxx�--�Reads�system�time.O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***<***…FILE:‚RDTIMER�--�GETS�THE�CURRENT�TIME�OUT�OF�SYSPAR�******É***D***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000.‡***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***G***…FUNCTION:‚This�routine�returns�the�time�maintained�by�the�timer„******‡logic.‚On�return,°***C***‰D1�=�the�#�of�milliseconds�since�midnight�at�which�the�last…******Žtimer�tick�occurred.§***C***‰D0�=�0.‚This�used�to�be�the�#�of�microseconds,�but�it�isn't„***?***Žrealistic�to�think�that�the�figure�was�ever�meaningful.„******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------?*…11/27/84‚Steve�FranckƒCreated�from�a�device-specific�version.* * *‚XDEF's.*$ŠXDEFƒRDTIMERŒEntry�pt.�for�TRAP�#0.(ŠXDEFƒSBRDTIMŒEntry�pt.�for�subroutines.  **‚XREF's�from�SYSPAR.*ŠXREF.S�MIDNIGHT ŠXREF.S�NSEŠXREF.S�TIME_LEFT  **‚Included�files:*„9995.&.STR.EQ*„9995.&.UTILITY.MC*„9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGE ŠSECTION�LEVEL00  SBRDTIM:RDTIMER: 0ŠPUSHƒSR‘We�must�do�this�with�interrupts�masked,6ŠDISABLE_INTERRUPTSˆin�case�we�take�a�timer�interrupt. *5*‚Calculate‚(#�of�milliseconds�since�last�midnight)�==*�[�(time�of�NSE�in�msecs)�-�(time�left�until�NSE�in�msecs)�]#*ª-�(time�of�last�midnight�in�msec)›E¤G*‚NSE�stands�for�Next�Significant�Event,�and�is�the�absolute�time�valueJ*‚in�msecs�when�we�next�need�to�take�something�off�the�Periodic�ActivationK*‚Table�(PAT).‚Recall�that�the�clock�is�a�31-bit�(not�32-bit!)�number�whichB*‚wraps�around�at�2**31�=�0,�so�we�have�to�do�"31-bit�arithmetic."*%ŠMOVE.L�NSE,D1�D1�<--�msec�time�now�=:ŠSUB.L‚TIME_LEFT,D1‡(time�of�NSE)�-�(time�left�until�NSE)./ŠSUB.L‚MIDNIGHT,D1ˆD1�<--�msec�since�midnight�=1*Ÿ(msec�time�now)�-�(msec�time�at�last�midnight).3ŠBCLRƒ#31,D1�The�result�is�a�31-bit�number,�so�zero%*§out�the�high�bit,�which�is�garbage. *J*‚Always�set�#�of�microseconds�to�zero,�since�we�are�really�only�returning6* the millisecond time of the last tick that occurred.*#ŠMOVEQ‚#0,D0ŽD0�<--�0�microseconds.  +ŠPOP„SR‘Restore�interrupt�level�and�return.ŠRTS—*  ŠEND- éééé=/*=/*†M68XXX.READY.AF=/**=/* Chain file to assemble M68XXX.READY.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.READY.LS=/*=/IFC \1ƒ=ARG�M68XXX.READY.LS=/ENDIF=/*.=ASM M68XXX.READY.SA,M68XXX.READY.RO,\1;RZ=055=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.INTERRUP.MC=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééééé¬8READY…IDNTƒ5,1�M68xxx�RMS�TRAP�0�Put�task�on�ready�list.O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***4***…FILE:‚READY�--�PUT�A�TASK�ON�THE�READY�LIST.—******É***D***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000.‡***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***H***…FUNCTION:‚Takes�the�TCB�for�a�task�and�puts�it�on�the�ready�listƒ***E***‡according�to�its�run�priority.‚There�are�various�entry�points„***D***‡to�this�module�which�provide�minor�variations�on�this�theme.†******É******…NOTES:¾******É***E***…REGISTER�U. SAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒDƒPƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒAƒ.ƒPƒ.ƒ.ƒ.ƒ.ƒP ******É******É******…ENTRY�CONDITIONS:³***>***‡A0ƒ=�ptr�to�TCB�of�the�task�to�be�added�to�ready�list.Š******É***-***…EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:Ÿ******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------G*†8/15/83‚Steve�FranckƒMade�COMINT�entry�point�set�the�running�priority1*žlike�most�of�the�other�routines�do.‚Rewrote�the2*žTCB�search�routine�to�execute�faster�(interrupts*žare�masked�during�search).*†2/08/81‚HLD6*†5/18/79‚7616*†3/06/79‚GGC3* * *‚XDEF's.*8ŠXDEFƒREADY,SBREADY†Normal�entry�points�to�this�routine. 'ŠXDEFƒSBRYRELQ‹Entry�point�from�RELINQ.5ŠXDEFƒSBRYEXT1‹Entry�point�from�EXIT2�(TRAP�#1�exit).:ŠXDEFƒSBRYEXIR‹Entry�point�from�EXITR�(exit�from�exception*§processing).µ5¾VÆ96ŠXDEFƒSBRYXMON‹Entry�point�from�EXMON�return�(REXMON).(ŠXDEFƒSBRYDLAY‹Entry�point�from�CKDELAY.&ŠXDEFƒSBRYACKŒEntry�point�from�AKRQST.)ŠXDEFƒSBRYSTRT‹Entry�point�from�TSTSTART.0ŠXDEFƒSBRYWAKE‹Entry�point�from�WAKEUP�and�WAIT.2ŠXDEFƒSBRYASRŒEntry�point�from�ASRINT�and�WTEVENT.+ŠXDEFƒSBRYGETŒEntry�point�from�ASQ�=�GT_EN.'ŠXDEFƒSBRYCINT‹Entry�point�from�COMINT. * *‚XREF's.*9ŠXREF.S�PREEMPT_FLAG‡SYSPAR�flag�which�signals�a�preempt.;ŠXREF.S�READYHDŒSYSPAR�pointer�to�head�entry�in�ready�list..ŠXREF.S�RUNNER�SYSPAR�pointer�to�running�task.   **‚Included�files:*8*‰UTILITY.MC�Macros�of�general�utility�(e.g.�PUSH,�POP).7*‰INTERRUP.MC�Macros�useful�in�dealing�with�interrupts.2*‰STR.EQ”Equates�for�supervisor�code�under�RMS68K.4*‰TCB.EQ”Equates�relating�to�the�Task�Control�Block.*ŠNOLISTŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.INTERRUP.MCŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TCB.EQŠLIST  ŠSECTION�LEVEL00ŠOPT„BRSŠPAGE*J*‚These�are�the�specialized�entry�points�for�all�the�various�routines�thatL*‚want�to�put�a�task�on�the�ready�list,�but�want�to�fiddle�with�the�priority*‚first.* SBRYRELQ: 2ŠMOVEQI�$F0,D0�Set�the�run�priority�of�the�task�to>ŠAND.B‚TCBCPRI(A0),D0…the�current�priority�with�the�low�4�bits#ŠMOVE.B�D0,TCBRPRI(A0)…set�to�zero.6ŠBRA„SBREADYŒThen�just�go�to�the�normal�READY�routine.  SBRYEXT1: SBRYEXIR: SBRYXMON: SBRYDLAY:SBRYACK: SBRYSTRT: SBRYWAKE:SBRYASR:SBRYGET: SBRYCINT: CŠMOVE.B�TCBCPRI(A0),TCBRPRI(A0)ƒReset�the�run�priority�for�the�task*§to�its�current�priority.  *,*…FALL�THROUGH�to�the�main�READY�routine!!!!*ŠPAGE*>*…NOTE�--�Other�routines�fall�into�this�routine�from�above!!!!* READY:SBREADY:  *(*‚See�if�he's�already�on�the�ready�list.* *ŠPUSHƒSR‘Save�the�SR�we�were�entered�with.9ŠDISABLE_INTERRUPTSˆDisable�interrupts�while�we�work�with*§the�volatile�TCB�chain.>ŠBSETƒ#TSK2NRDY,TCBSTAT2(A0)‚Set�the�bit�that�says�this�guy�is6ŠIF…�THENŠon�the�ready�list.‚If�he�wasn't�already,  *.*‚He's�not;�get�set�up�to�put�him�on�the�list.* +ŠSAVEƒD1/A2ŽSave�registers�we'll�blow�away.>ŠLEA„READYHD-TCBREADY,A2‚A2�<--�address�such�that�TCBREADY(A2)(*§refers�to�the�ready�list�head�pointer.@ŠMOVE.B�TCBRPRI(A0),D0…D0.B�<--�priority�of�task�to�put�on�list.  *>*‚Search�the�list�for�a�TCB�of�lower�priority�than�this�guy's.* ŠREPEAT <ŠMOVE.L�TCBREADY(A2),D1„D1�<--�ptr�to�next�TCB�in�the�chain.6ŠBEQ„ADD. _HIMŒIf�we�hit�the�end�of�the�list,�just�exit. 4ŠEXG.L‚D1,A2ŽA2�<--�ptr�to�the�TCB�we're�looking�at.#*§D1�<--�ptr�to�TCB�just�before�it.BŠUNTIL.B�D0��TCBRPRI(A2)‚Keep�looping�until�we�find�a�TCB�with'*§a�priority�lower�than�our�guy�to�add. 5ŠEXG.L‚D1,A2ŽD1�<--�ptr�to�the�TCB�of�lower�priority.#*§A2�<--�ptr�to�TCB�just�before�it.ŠPAGE*M*‚Either�we�found�somebody�of�lower�priority�than�the�guy�we're�trying�to�addK*‚or�we�hit�the�end�of�the�chain.‚Either�way,�we�want�to�add�the�new�guy�to5*‚the�list�between�the�TCB's�pointed�to�by�A2�and�D1.* ADD_HIM:CŠMOVE.L�D1,TCBREADY(A0)„Set�our�forward�link�to�point�to�the�guy�we'*§found�to�be�of�lower�priority�(or�0).AŠMOVE.L�A0,TCBREADY(A2)„Set�forward�link�of�the�guy�we�want�to�be *§after�so�that�it�points�to�us.ŠMOVE.L‚RUNNER,A2ŠIF.B„D0��TCBRPRI(A2)�THENŠST†PREEMPT_FLAGŠENDI !ŠRESTORE�D1/A2�Restore�registers. ŠENDI 2ŠPOP„SR‘Restore�the�SR�we�saved�on�entry�&�return.ŠRTS—*    ŠENDéé=/*=/*†M68XXX.RELINQ.AF=/*+=/* Chain file to assemble M68XXX.RELINQ.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.RELINQ.LS=/*=/IFC \1ƒ=ARG�M68XXX.RELINQ.LS=/ENDIF=/*1=ASM M68XXX.RELINQ.SA,M68XXX.RELINQ.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDééééééΉPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE5RELINQƒIDNT‚5,1�68xxx�DIRECTIVE-/ -RELINQUISH�EXECUTION*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�RELINQ†2.00�**ˆ*’**ˆ*�03/23/81ƒHLD6‚**ˆ*********************(*ˆTASK�WANTS�TO�RELINQUISH�EXECUTION�AND$*ˆGO�TO�THE�BOTTOM�OF�THE�READY�LIST**ˆENTRY:‚A6�ADDRESS�OF�TCB*ˆEXIT�:‚NO�REGISTERS�ALTERED* *›01234567*ˆUSES�REGISTERS‚D*˜AˆP*‰SECTION�LEVEL04* ‰XDEF†RELINQ*RELINQ:(‰TR0.RYRELQ‚(A6)ŽPut�task�on�ready�list,%*¦(mask�off�last�4�bits�of�priority);+‰EXIT†POSTEMPTŒexit�(postempt�client�task);‰ENDéééé×+=/*=/*†M68XXX.RESUME.AF=/*+=/* Chain file to assemble M68XXX.RESUME.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.RESUME.LS=/*=/IFC \1ƒ=ARG�M68XXX.RESUME.LS=/ENDIF=/*1=ASM M68XXX.RESUME.SA,M68XXX.RESUME.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééééé/ à‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE8RESUMEƒIDNT‚5,1ƒ68xxx�DIRECTIVE--RESUME�A�SUSPENDED�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**…*****************)*…*‚R�E�S�U�M�E‚*ƒRESUME�A�SUSPENDED�TASK*…******************#*„ENTRY:‚A6‚REQUESTOR'S�TCB�ADDRESS*ŒA4‚PARAMETER�BLOCK�ADDRESS!*‹(A4)�TARGET�TASK�NAME�TO�RESUME#*Š4(A4)�SESSION�CODE�OF�TARGET�TASK*ŒA5‚TARGET�TCB�ADDRESS*$*…EXIT:‚D0�=�0�IF�CALL�IS�SUCCESSFUL*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST+*ŠRTCDSTAT�-10ƒTARGET�TASK�IS�NOT�SUSPENDED*‰SECTION�LEVEL04* ‰XDEF†RESUME‰PAGE*"*ˆSee�if�target�task�is�suspended.!*ˆ(Fail�if�target�not�suspended).* RESUME:8‰BCLR†#TSKSSUSP,TCBSTATE(A5)ˆif�(task�was�not�suspended))‰EXIT.EQƒRTCDSTAT–then�return�(error_10);  **ˆPut�target�on�ready�list, *ˆand�return.* "‰TR0.READY�(A5)šput�on�ready�list;!‰EXIT†SUB›exit�(subroutine�exit);‰ENDéééé:=/*=/*†M68XXX.REXMON.AF=/*+=/* Chain file to assemble M68XXX.REXMON.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.REXMON.LS=/*=/IFC \1ƒ=ARG�M68XXX.REXMON.LS=/ENDIF=/*1=ASM M68XXX.REXMON.SA,M68XXX.REXMON.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééé0 ééò‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGEAREXMONƒIDNT„5,1†68xxx�DIRECTIVE--EXECUTE�TASK�UNDER�EXMON�CONTROL*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡***************************2*‡*‚R�E�X�M�O�NŒ*ƒEXECUTE�TASK�UNDER�EXMON�CONTROL*‡*‚REV�3.00‚11/25/81�HLD6**‡*Œ03/23/81�HLD6**‡******************************‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A4�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�TASK�NAME�OF�TARGET�TASK*—4�-�SESSION�CODE,*—8�-�BUFFER�ADDRESS,�POINTER�TO�RUN�OPTIONS*›RUN�OPTIONS:**œ0-OPTIONS,BITS�15-12=TYPE�BIT�11=MAX�CNT"*œ2-LOCATION�OF�VALUE�TO�BE�TESTED *œ6-VALUE*›10-VALUE�MASK*›14-MAX�INSTRUCTION�COUNT**‹EXIT�:�D0�HAS�RETURN�CODE*’D0�=�0„GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST5*ŠRTCDSTAT�-10ƒTARGET�TASK�NOT�WAITING�FOR�THIS�EXMON0*ŠRTCDADR1�-12ƒBUFFER�NOT�IN�CALLER'S�ADDR�SPACE6*ŠRTCDOPT‚-15ƒVALUE�OPT�-�GOOD�ADDR�OF�VALUE�NOT�GIVEN**‰SECTION�LEVEL04* ‰XDEF„REXMON ‰XREF.S‚EXMONVR‰PAGEREXMON:-‰MOVE.L„A4,A3”SAVE�ADDRESS�OF�PARAMETER�BLOCK-‰BTST†#TSKSWTEM,TCBSTATE(A5)ƒIS�TASK�WAITING?+‰EXIT.EQƒRTCDSTAT‘ERROR�-�Task�not�waiting.  **ˆCheck�for�valid�request.* ‰MOVE.L„#18,D5ŽBUFFER�LENGTH2‰BSR‡EXMONVR�DON'T�COME�BACK�UNLESS�VALID�REQUEST.‰MOVE.L„D6,A4�BUFFER�ADDRESS  *-*ˆSave�execution�options�and�make�task�ready.* 5‰BTST†#TSK2RTEX,TCBSTAT2(A5)ƒClear�the�trace�mode�bit‰IF‚‚THEN.S2‰BCLR†#TRMODE,TCBSR(A5)ˆin�the�appropriate�copy�of‰ELSE.S"‰BCLR†#TRMODE,TCBSTKSR(A5)…the�SR.‰ENDI .‰MOVE.L„2(A4),TCBEVLOC(A5)‡MOVE�VALUE�LOCATION%‰MOVE.L„6(A4),TCBEVALU(A5)‡MOVE�VALUE+‰MOVE.L„10(A4),TCBEVMSK(A5)†MOVE�VALUE�MASK)‰MOVE.L„14(A4),TCBECNT(A5)‡MOVE�MAX�COUNTûU-0‰CLR.W…TCBECNT(A5)ŽCLEAR�UPPER�1/2�OF�COUNT�WORD9‰AND.B…#$03,TCBEMMSK(A5)ˆCLEAR�EXEC�OPTIONS�FIELD�IN�MASK!‰MOVE.B„(A4),D7’GET�OPTIONS�IN�D7$‰AND.B…#$38,D7’ISOLATE�OPTIONS�FIELD0‰OR.B†D7,TCBEMMSK(A5)ŠSAVE�OPTIONS�IN�EXMON�MASK‰TST.B…D7—GET�EXECUTION�TYPE'‰BEQ.S…REXMN6“BRANCH�IF�NO�TRACE�NEEDED 3‰BTST†#TSK2RTEX,TCBSTAT2(A5)ƒSet�the�trace�mode�bit‰IF‚‚THEN.S2‰BSET†#TRMODE,TCBSR(A5)ˆin�the�appropriate�copy�of‰ELSE.S"‰BSET†#TRMODE,TCBSTKSR(A5)…the�SR.‰ENDI .‰MOVE.L„TCBEMMSK(A5),D7ŠMOVE�ENTIRE�MASK�TO�D7*‰BTST†#TEMVCHG,D7ŽIS�VALUE�CHANGE�BIT�SET?‰BEQ.S…REXMN6“BRANCH�IF�NO >‰TR0.LOGPHY‚,TCBEVLOC(A5),#4ˆGET�P�ADDR�FOR�VLOC‰BRA.S…REXMN5“GOOD�RETURN ‰NOP‰EXIT†RTCDOPT’BAD�RETURN. REXMN5:#‰BCLR†#0,D6”BE�SURE�ADDRESS�IS�EVEN+‰MOVE.L„D6,A4”MOVE�VALUE�LOC�TO�ADDRESS�REG-‰BTST†#TEMVEQU,D7ŽIS�'VALUE�EQUAL'�REQUESTED?‰BNE.S…REXMN6“BRANCH�IF�YES +‰MOVE.L„(A4),TCBEVALU(A5)ˆGET�CURRENT�VALUE  REXMN6:-‰BCLR†#TSKSWTEM,TCBSTATE(A5)ƒCLE0 AR�'WAIT'�BIT‰MOVE.W„TCBSTATE(A5),D0.‰AND.W…#TSKSWMSK,D0�WAITING�FOR�ANYTHING�ELSE?‰BNE.S…REXMN7“BRANCH�IF�YES '‰TR0.RYXMON�(A5)”PUT�TASK�ON�READY�LIST REXMN7:!‰EXIT†SUB–exit�(subroutine�exit);‰ENDééé=/*=/*†M68XXX.RMS.AF=/*(=/* Chain file to assemble M68XXX.RMS.SA=/*:=/* If no output argument is specified for the listing the,=/* chain file will default to M68XXX.RMS.LS=/*=/IFC \1ƒ=ARG�M68XXX.RMS.LS=/ENDIF=/*+=ASM M68XXX.RMS.SA,M68XXX.RMS.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDéééééé ŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGE*RMS‡IDNTƒ5,1�68xxx�RMS�INITIAL�ENTRY�POINT*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆRMS‚IS�ENTERED�HERE*ŠSECTION�LEVEL00* ŠXDEFƒRMS ŠXREF.L�DISPATCHŠXREF.L�FLUSH_ALL_CACHEŠXREF.L�PROGINT9ŠXREF.S�PATBEGŠXREF.L�SCHED_DATEUP‰PAGE*,*ˆHere�to�start�up�RMS�after�initialization:*�Flush�the�cache,*�and�go�to�dispatch.* RMS: &ŠBSR„FLU1 SH_ALL_CACHE„Flush�all�caches. K*�Schedule�the�node�to�force�the�date�to�'rollover'�at�midnight.‚A�new�nodeF*ƒis�normally�scheduled�when�the�user�enters�the�time�and�date�throughH*ƒsession�control.‚If�the�system�has�a�battery�backed�timer,�however,�itJ*ƒmay�happen�that�the�user�may�not�enter�the�date�and�time�but�depend�uponK*ƒit�being�picked�up�from�the�timer�itself.‚By�the�time�we�reach�this�code,B*ƒthe�system�initializer�has�all�ready�adjusted�NSE,�MIDNIGHT,�andH*ƒTIMELEFT�have�been�initialized�properly�to�reflect�the�system�time�andF*ƒthe�BIGDELTA�node�that�is�next�on�the�PAT�list.‚In�the�case�where�weD*ƒdon't�have�a�battery�backed�up�timer,�we�will�schedule�a�'garbage'G*ƒrollover�node�but�we�really�don't�care�since�it�will�be�cancelled�and?*ƒthe�correct�rollover�node�scheduled�when�the�time�is�manually *ƒentered.*K* We do not mask interrupts to schedule the new node because we are entered5*ƒfrom�the�system�initializer�with�interrupts�masked.*ŠBSR„SCHED_DATEUP ŠBRA„DISPATCH  **ˆJump�here�to�call�killer.*ŠXDEFƒCALLKILLŠXREF.L�KILLER CALLKILL: ŠJSR„KILLER‰PAGE*I* This is the exec routine scheduled originally by the system initializerN/I*ƒthat�puts�a�dummy�node�with�a�large�delta�onto�the�end�of�the�PAT�list.D*ƒThis�insures�that�the�PAT�list�is�never�empty�which�simplifies�theB*ƒPAT�processing�in�many�areas.‚Note�that�we�do�not�go�through�theF*ƒnormal�schedule�node�routine�PAT_SCHED_NEW_NODE.‚We�couldn't�do�this/*ƒand�guarantee�the�large�delta�that�we�desire.*/ŠDC.Lƒ'DUMY'�Bit�pattern�that�INIT�searches�for$*£in�order�to�find�procedure�address* DUMY:ŠMOVE.L�PATBEG,A1 ŠDISABLE_INTERRUPTSˆMask 2ŠMOVE.L�PATFHDR(A1),A2…A2�points�to�free�PAT�entry ŠIF.L�A2��#0�THEN.S+�BSR�KILLER�Kill�system�of�no�free�PAT�nodeŠELSE.S@�MOVE.L�PATNEXT(A2),PATFHDR(A1)�Unlink�this�entry�from�free�list$�ENABLE_INTERRUPTS‰Unmask�interrupts*¦Initialize�PAT�entries�CLR.L‚PATNEXT(A2)$�CLR.L‚PATTCB(A2)‰Indicate�exec�node5�MOVE.L�#PATBIGDELTA,PATDELTA(A2)�Make�delta�very�big�CLR.L‚PATINTV(A2)3�LEA„DUMY(PC),A3ˆAddress�of�procedure�to�reschedule'�MOVE.L�A3,PATASR(A2)†Execution�address(�CLR.W‚PATOPT(A2)‰Options�-�not�periodic4�MOVE.L�#PATDUMMYID,PATARID(A2)�Plug�in�the�dummy�ID4�MOVE.W�#$FFFF-$0700,PATILVL(A2)�Interrupt�level�=�0#�DISABLE_INTERRUPTSˆMask�interrupts7�MOVE.L�PATHDR(A1),A3†A3�points�to�1st�node�on�PAT�list !�WHILE.L�PATNEXT(A3)��#0�DO.S*�LEA‚PATNEXT(A3),A3ƒFind�last�node�on�list�ENDW 7�MOVE.L�A2,PATNEXT(A3)„Link�this�entry�onto�end�of�listŠENDI%ŠENABLE_INTERRUPTS‰Unmask�and�lose�SR(ŠRTE—Back�to�PAT�scheduler�(we�really�go(*£back�to�a�background�routine�scheduled%*£by�TIMEINT.‚This�background�routine *£was�the�one�that�scheduled�us.ŠENDé=/*=/*†M68XXX.RMSPATCH.AF=/*-=/* Chain file to assemble M68XXX.RMSPATCH.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.RMSPATCH.LS=/*=/IFC \1ƒ=ARG�M68XXX.RMSPATCH.LS=/ENDIF=/*4=ASM M68XXX.RMSPATCH.SA,M68XXX.RMSPATCH.RO,\1;RZ=045=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*}=/*=END1 éééééé&(RMSPATCH‚IDNTƒ5,1�Patch�area�for�RMS68K.O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***3***…ROUTINE:‚RMSPATCH�--�PATCH�AREA�FOR�RMS68K.˜******É***J***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000�family.***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***F***…FUNCTION:‚If�a�bug�is�found�in�RMS68K,�this�space�is�available…***;***‡to�Motorola�Microsystems�for�incorporating�patches.�******É***O*******************************************************************************O*******************************************************************************O*^*****************************************************************************  7ŠXDEFƒRMSPATCH‹Location�of�the�patch�area;�it�is�XDEFed&*§so�that�it�will�be�easier�to�find�in*§the�link�map. **‚Included�files:5*‰9995.&.STR.EQ�The�section�number�to�use�is�in�here.*ŠINCLUDE�9995.&.STR.EQ  ŠSECTION�PATCHES RMSPATCH: )ŠDS.Bƒ256�Reserve�some�space�for�patches.  ŠENDééé/%2 =/*=/*†M68XXX.RQSTPA.AF=/*+=/* Chain file to assemble M68XXX.RQSTPA.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.RQSTPA.LS=/*=/IFC \1ƒ=ARG�M68XXX.RQSTPA.LS=/ENDIF=/*1=ASM M68XXX.RQSTPA.SA,M68XXX.RQSTPA.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDéééééé8ŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINLCUDEƒ9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGE�A0�THEN.S�MOVE.L�PATDELTA(A0),D0.�ADD.L‚D0,TIME_LEFT„1st�node,�update�TIME_LEFT �ADD.L‚D0,NSE$�BCLRƒ#31,NSE‰Insure�positive�numberŠELSE.S‘Not�1st�node2�MOVE.L�PATDELTA(A2),D0�Delta�of�node�just�removed5�ADD.L‚D0,PATDELTA(A0)�update�delta�of�following�nodeŠENDIŠMOVE.W�(A7),SRŒUnmask ŠTST.L‚D6‘ADD�OR�CANCEL�?ŠBNE.S‚RQST9ŽBRANCH�IF�CANCEL  **†ADD�ENTRY�--�NEW�REQUEST* 'RQSTAN„MOVE.L�A5,PATTCB(A2)†TCB�ADDRESS(ŠBCLRƒ#31,D4�Insure�interval�is�positiveŠMOVE.L�D4,PATINTV(A2)…INTERVAL%ŠMOVE.L�18(A4),PATASR(A2)‚ASR�ADDRESS&ŠCLR.W‚PATCNT(A2)‰CLEAR�SEQUENCE�COUNT!ŠMOVE.L�D5,PATARID(A2)…REQUEST�ID.ŠBSETƒ#PATO1STE,D3‡FLAG�1ST�ACTIV�NOT�EXECUTEDŠMOVE.W�D3,PATOPT(A2)†OPTIONS2ŠSUB.L‚D1,D2ŽD2�=�ms�from�now�that�we�want�to�fireŠDISABLE_INTERRUPTSˆMaskŠBSR„PAT_SCHED_NEW_NODEŠMOVE.W�(A7),SRŒUnmaskŠBRA„RQST15�Go�return  #RQST9…ADD.W‚#1,D6ŽCOUNT�#�CANCELLED.ŠAND.W‚#PATOCMSK,D3‡CALLER�WANT�FINAL�MESSAGE?ŠBNE.S‚RQST9A�BRANCH�IF�YES 1ŠBTSTƒ#9,PATOPT(A2)†FINAL�REQUESTED�WHEN�STARTED?ŠBEQ.S‚RQST10�BRANCH�IF�NO  *#*†ADD�ENTRY�--�FINAL�CANCEL�MESSAGE* 5RQST9A„BSETƒ#7,PATCNT(A2)†SET�SEQUENCE�COUNT�NEGATIVE5ŠBCLRƒ#PATOINTV,PATOPT(A2)�STOP�CONTINUOUS�ACTIVATION0ŠBSETƒ#PATOFINL,PATOPT+1(A2)�FLAG�AS�FINAL�ENTRY !ŠCLR.L‚D2‘Fire�on�next�clock�tick-ŠMOVEM.L�D1-D6/A3,-(A7)„Save�registers�I�needŠDISABLE_INTERRUPTSˆMask ŠBSR„PAT_SCHED_NEW_NODE SRSTACKƒSET„7*4ŠMOVE.W�SRSTACK(A7),SR…UnmaskŠMOVEM.L�(A7)+,D1-D6/A3 ŠTST.L‚D6‘IS�IT�CANCEL�ALL?ŠBMI„RQST8A�BRANCH�IF�YES ŠBRA.S‚RQST15�Go�return  **ˆRETURN�ENTRY�TO�FREE�LIST* RQST10„DISABLE_INTERRUPTSˆMask$ŠPAT_FREE_NODE�Put�node�on�free�listŠMOVE.W�(A7),SRŒUnmask ŠTST.L‚D6‘IS�IT�CANCEL�ALL?ŠBMI„RQST8A�BRANCH�IF�YES ŠBRA.S‚RQST15�Go�return  **„ENTIRE�LIST�SEARCHED*  'RQST12„TST.L‚D6‘WAS�IT�A�CANCEL�REQUESTŠBNE.S‚RQST14�BRANCH�IF�YES &ŠDISABLE_INTERRUPTSˆINHIBIT�INTERRUPTS%ŠMOVE.L�PATFHDR(A1),D0…GET�FREE�ENTRY&ŠBEQ.S‚RQST13�BRANCH�IF�NONE�AVAILABLE ŠMOVE.L�D0,A2ŽENTRY�ADDRESS4ŠMOVE.L�PATNEXT(A2),PATFHDR(A1)�SAVE�NEW�FREE�HEADERŠMOVE.W�(A7),SRŒUnmaskŠBRA„RQSTAN�GO�ADD�ENTRY  .RQST13„MOVE.W�(A7)+,SR‹RESTORE�INTERRUPT�LEVEL"ŠEXITƒRTCDTFUL‹ERROR�IF�TABLE�FULL  $RQST14„SUB.W‚#1,D6ŽWAS�CANCEL�FOUND?ŠBGT.S‚RQST15�BRANCH�IF�YES ŠMOVE.W�(A7)+,SR(ŠEXITƒRTCDNFND‹ERROR�-�NOTHING�TO�CANCEL 4RQST15„MOVE.W�(A7)+,SR‹Unmask�and�lose�SR�from�stack!ŠEXIT…SUBŽexit�(subroutine�exit);ŠENDééé3 éé=/*=/*†M68XXX.RSTATE.AF=/*+=/* Chain file to assemble M68XXX.RSTATE.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.RSTATE.LS=/*=/IFC \1ƒ=ARG�M68XXX.RSTATE.LS=/ENDIF=/*1=ASM M68XXX.RSTATE.SA,M68XXX.RSTATE.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDééééééj‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LISTˆPAGE�0�Failure;²******É***5***ŠThe�following�error�codes�are�returned�in�D0:’******É***4***ŒRTCDNTBL�-�04‚Required�table�does�not�exist.�******É***7***ŒRTCDNFND�-�07‚Entry�not�found�in�table�or�list.�******É******É***O*******************************************************************************O*******************************************************************************O*^********************************************************************5 *********‰PAGE*,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------)*…09/02/84‚MSLŒRe-wrote�as�state�machine.*…11/06/81‚HLD6‹REV�3.00‘7š_¢Rª�²E*…05/01/79‚HLD6‹REV�2.00* * *‚XDEF's.* ‰XDEF†RTEVENT * *‚XREF's.*‰XREF.S„A_EXPORT‰XREF.S„DISP_ASR‰XREF.S„KILLER **‚Included�files:**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.ASQ.EQ*ˆINCLUDEƒ9995.&.ASQ.MC*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.ASQ.EQ‰INCLUDEƒ9995.&.ASQ.MC‰LIST‰SECTION�LEVEL04‰PAGE(*rtevent: proc (client_tcb_ptr, en_asr);  *„dcl‚en_asr�bit_0�(A0);#*„dcl‚client_tcb_ptr�longword�(A6);  $*ˆtarget_tcb_ptr�<==�client_tcb_ptr; '*ˆasq_ptr�<==�tcb_asq�(client_tcb_ptr);*ˆif�(asq_ptr�=�0)*ˆthen�return�(error_04) *ˆelse�do;-*�if�(asr_nval�(asq_st_mode�(asq_ptr))�=�set)*�then�return�(error_07); *�else�do;*’log_usp�<==�usp�(proc);*’stack_depth�<==�len�(sr,�pc);/*’if�(no_stack�(asq_st_mode�(asq_ptr))�=�reset)0*’then�stack_depth�<==�stack_depth�+�len�(regs);0*’if�(client_tcb_ptr�<>�real_time�task)�then�do;(*—phy_usp�<==�logphy�(usp,�stack_depth); *—if�(error)*—then�call�exec_abort�($8099);*’end;*’else�phy_usp�<==�log_usp;!*’if�(stack_depth�>�len�(sr,�pc))5*’then�tcb_regs�(client_tcb_ptr)�<==�regs�(phy_usp)+;*’sr�(super_stack)�<==*™(word�(phy_usp)�&�$00FF)�|!*™(trace_bit�(sr�(super_stack)));+*’pc�(super_stack)�<==�longword�(phy_usp)+;5*’tcb_usp�(client_tcb_ptr)�<==�log_usp�+�stack_depth; *’freeze�(asq);$*’do�case�(asq_state,�asq_sw_modes); *�end;*ˆend;  *end rtevent;‰PAGE(*rtevent: proc (client_tcb_ptr, en_asr);  $*ˆtarget_tcb_ptr�<==�client_tcb_ptr; '*ˆasq_ptr�<==�tcb_asq�(client_tcb_ptr);*ˆif�(asq_ptr�=�0)*ˆthen�return�(error_04) RTEVENT:0‰MOVE.L„A6,A5�target_tcb_ptr�<==�client_tcb_ptr; &‰MOVE.L„A0,D1�(save�option�bit�in�D1);;‰MOVE.L„TCBASQ(A6),A4‡asq_ptr�<==�tcb_asq�(client_tcb_ptr);‰MOVE.L„A4,D0�if�(asq_ptr�=�0)'‰BEQ.S…RTEVER04Œthen�return�(error_04);  *ˆelse�do;-*�if�(asr_nval�(asq_st_mode�(asq_ptr))�=�set)*�then�return�(error_07); :‰BTST†#ASQS_RNV,ASQSTMD2(A4)ƒif�(asr_nval�(asq_ptr)�=�set)'‰BNE.S…RTEVER07‘then�return�(error_07);  *�else�do;*’log_usp�<==�usp�(proc);*’stack_depth�<==�len�(sr,�pc);/*’if�(no_stack�(asq_st_mode�(asq_ptr))�=�reset)0*’then�stack_depth�<==�stack_depth�+�len�(regs);  &‰MOVE.L„USP,A2“log_usp�<==�usp�(proc);7‰MOVE.L„#SR_LEN+PC_LEN,D7ˆstack_depth�<==�len�(sr,�pc);@‰BTST†#ASQSKDIS,ASQSTMD2(A4)ƒif�(no_stack�(asq_st_mode)�=�reset)#‰BNE.S…RTEV_01’then�stack_depth�<== -‰ADD.L…#REGS_LEN,D7’stack_depth�+�len�(regs);  0*’if�(client_tcb_ptr�<>�real_time�task)�then�do;(*—phy_usp�<==�logphy�(usp,�stack_depth); *—if�(error)*—then�call�exec_abort�($8099);*’end;*’else�phy_usp�<==�log_usp;  RTEV_01:>‰BTSTW…#TSKARTIM,TCBATTR(A6)„if�(client�<>�real-time)�then�do;‰BNE.S…RTEV_03—phy_usp�<==*°log_phy�(usp,�stack_depth�; ‰TR0.LOGPHY�,A2,D7‰BRA.S…RTEV_02—if�(error) "‰NOP¥then�call�exec_abort�($8099);‰MOVE.W„#$8099,D7�end;‰TR0.EXABRT�(A6)  RTEVER04:!‰EXIT†RTCDNTBL–return�(error_04);  RTEVER07:!‰EXIT†RTCDNFND–return�(error_07);  RTEV_02: ‰MOVE.L„D6,A3‰BRA.S…RTEV_04 RTEV_03:'‰MOVE.L„A2,A3”else�phy_usp�<==�log_usp;  !*’if�(stack_depth�>�len�(sr,�pc))5*’then�tcb_regs�(client_tcb_ptr)�<==�regs�(phy_usp)+;  RTEV_04:8‰CMP.L…#SR_LEN+PC_LEN,D7ƒif�(stack_depth)�>�len�(sr,�pc)‰BLE.S…RTEV_05 <‰MOVEM.Lƒ(A3)+,D0/D2-D5 6/A0-A1�then�tcb_regs�(client_tcb_ptr)6‰MOVEM.LƒD0/D2-D6/A0-A1,TCBD0(A6)Š<==�regs�(phy_usp)+;‰MOVEM.Lƒ(A3)+,D2-D6/A0-A1‰MOVEM.LƒD2-D6/A0,TCBA0(A6)‰MOVE.L„A1,(SP)  *’tcb_sr�(client_tcb_ptr)�<==*™(word�(phy_usp)�&�$00FF)�|!*™(trace_bit�(sr�(super_stack)));+*’pc�(super_stack)�<==�longword�(phy_usp)+;5*’tcb_usp�(client_tcb_ptr)�<==�log_usp�+�stack_depth; RTEV_05:%‰MOVE.W„(A3)+,D0Œsr�(super_stack)�<==+‰AND.W…#$00FF,D0’(word�(phy_usp)�&�$00FF)�|/‰BTST†#15,4(A7)’(trace_bit�(sr�(super_stack)));‰BEQ.S…RTEV_06 ‰BSET†#15,D0 RTEV_06:‰MOVE.W„D0,A6_LEN(SP) **¦pc�(super_stack)�<==�longword�(phy_usp); ‰MOVE.L„(A3)+,A6_LEN+SR_LEN(SP) )‰ADD.W…D7,A2�tcb_usp�(client_tcb_ptr)�<==%‰MOVE.L„A2,USP–log_usp�+�stack_depth;  *’freeze�(asq);$*’do�case�(asq_state,�asq_sw_modes); *¦freeze�(asq); ‰FREEZE_ASQ9‰MOVE.W„ASQSTATE(A4),D2…do�case�(asq_state,�asq_sw_mode);‰MOVE.W„RTEV_TBL(PC,D2.W),A2‰JMP‡RTEV_TBL(PC,A2.W) *�end;*ˆend;  *end rtevent;‰PAGE RTEV_TBL: ‰DC.W†RQ_DIS00-RTEV_TBL‰DC.W†RQ_DIS01-RTEV_TBL‰DC.W†RQ_DIS10-RTEV_TBL‰DC.W†RQ_DIS11-RTEV_TBL ‰DC.W†Q_EN_00-RTEV_TBL‰DC.W†Q_EN_01-RTEV_TBL‰DC.W†Q_EN_10-RTEV_TBL‰DC.W†Q_EN_11-RTEV_TBL ‰DC.W†R_EN_00-RTEV_TBL‰DC.W†R_EN_01-RTEV_TBL‰DC.W†R_EN_10-RTEV_TBL‰DC.W†R_EN_11-RTEV_TBL ‰DC.W†RQ_EN_00-RTEV_TBL‰DC.W†RQ_EN_01-RTEV_TBL‰DC.W†RQ_EN_10-RTEV_TBL‰DC.W†RQ_EN_11-RTEV_TBL ‰DC.W†WT_EN_00-RTEV_TBL‰DC.W†WT_EN_01-RTEV_TBL‰DC.W†WT_EN_10-RTEV_TBL‰DC.W†WT_EN_11-RTEV_TBL ‰DC.W†GT_EN_00-RTEV_TBL‰DC.W†GT_EN_01-RTEV_TBL‰DC.W†GT_EN_10-RTEV_TBL‰DC.W†GT_EN_11-RTEV_TBL‰PAGE WT_EN_00: WT_EN_01: WT_EN_10: WT_EN_11: GT_EN_00: GT_EN_01: GT_EN_10: GT_EN_11: R_EN_00:R_EN_10: RQ_EN_00: RQ_EN_10: *ˆrelease�(asq);*ˆcall�killer; ‰RELEASE_ASQ ‰BSR‡KILLER        R_EN_01:R_EN_11: RQ_EN_01: RQ_EN_11: *ˆrelease�(asq);*ˆexit�(D0_sub); ‰RELEASE_ASQ ‰EXIT†D0_SUB        RQ_DIS00:Q_EN_00: *ˆrelease�(asq);*ˆif�(en_asr�(A0)�=�reset)*ˆthen�exit�(D0_sub); *ˆelse�do;*�get�(asq_xfr�vector);*�call�disp_asr;*�exit�(D0_asr);*ˆend; ‰RELEASE_ASQ ‰BTST†#0,D1‰EXIT.EQƒD0_SUB ‰GET_ASQXFR ‰BSR‡DISP_ASR ‰EXIT†D0_ASR        RQ_DIS01: RQ_DIS11: *ˆif�(en_asr�(option)�=�set)*ˆthen�asq_state�<==�r_en;*ˆrelease�(asq);*ˆexit�(D0_sub); ‰BTST†#0,D1‰BEQ.S…RTEV_20 ‰AND.W…#SWMD_MASK,D2‰OR.B†#R_EN,D2‰MOVE.W„D2,ASQSTATE(A4) RTEV_20: ‰RELEASE_ASQ ‰EXIT†D0_SUB        Q_EN_01:Q_EN_11: *ˆif�(en_asr�(option)�=�set)*ˆthen�asq_state�<==�rq_en;*ˆrelease�(asq);*ˆexit�(D0_sub); ‰BTST†#0,D1‰BEQ.S…RTEV_30 ‰AND.W…#SWMD_MASK,D2‰OR.B†#RQ_EN,D2‰MOVE.W„D2,ASQSTATE(A4) RTEV_30: ‰RELEASE_ASQ ‰EXIT†D0_SUB        RQ_DIS10:Q_EN_10: *ˆrelease�(asq);*ˆif�(en_asr�(option)�=�reset)*ˆthen�exit�(D0_sub); *ˆelse�do;!*�dest_ptr�<==�def_buf�(asq_ptr);*�call�a_export�(dest_ptr);*�call�disp_asr;*ˆexit�(D0_asr);*ˆend; ‰RELEASE_ASQ ‰BTST†#0,D1‰EXIT.EQƒD0_SUB ‰MOVE.L„ASQDBUF(A4),A0 ‰BSR‡A_EXPORT ‰BSR‡DISP_ASR ‰EXIT†D0_ASR ‰ENDéé6 éé=/*=/*†M68XXX.SEGALOC.AF=/*,=/* Chain file to assemble M68XXX.SEGALOC.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.SEGALOC.LS=/*=/IFC \1ƒ=ARG�M68XXX.SEGALOC.LS=/ENDIF=/*3=ASM M68XXX.SEGALOC.SA,M68XXX.SEGALOC.RO,\1;MRZ=070=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.SEG.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDééééé麉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.SEG.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE;SEGALOC‚IDNTƒ5,1ƒ68xxx�DIRECTIVE--ALLOCATE�A�MEMORY�SEGMENT*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�SEGALOC…3.00�**ˆ*’**ˆ*�7616�04/23/79„**ˆ*�HLD6�09/18/79„**ˆ*�HLD6�12/12/81„**ˆ**********************ˆALLOCATE�A�SEGMENT�TO�A�TASK*8*ENTRYƒA4…POINTS�TO�PARAMETER�BLOCK�IN�REQUESTOR'S�SPACE!*ˆA5…POINTER�TO�TARGET�TASK'S�TCB*2*�EXITƒA0…PHYSICAL�ADDRESS�OF�SEGMENT�IF�SUCCESFUL*ˆD0…RETURN�CODE*�0--SUCCESSFUL*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST9*ŠRTCDTFUL�-�5ƒTARGET�TST�IS�FULL�-�NO�ROOM�FOR�NEW�ENTRY8*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�SEG�EXISTS,�SAME�NAME.*ŠRTCDNFND�-�7ƒMEMORY�REQUESTED�DOES�NOT�EXIST)*ŠRTCDNMEM�-�8ƒMEMORY�SPACE�NOT�AVAILABLE!*ŠRTCDSTAT�-10ƒTARGET�NOT�DORMANT8*ŠRTCDLGCF�-11ƒLOGICAL�ADDR�CONFLICTS�WITH�EXISTING�ADDR** 6 PARAMETER BLOCK IS SGPB**ˆ0(A4)‚TARGET�TASK�NAME *ˆ4(A4)‚TARGET�TASK�SESSION�CODE*ˆ8(A4)‚DIRECTIVE�OPTIONS*‡10(A4)‚SEGMENT�ATTRIBUTES*‡12(A4)‚SEGMENT�NAME"*‡16(A4)‚BEGINNING�LOGICAL�ADDRESS*‡20(A4)‚SEGMENT�LENGTH�(BYTES)*‰SECTION�LEVEL03*‰XREF.S�KILLER ‰XREF.S�LAM‰XREF.S�NOTLAM‰XREF.S�SDEFTYP‰XREF.S�MMUHERE ‰XREFƒLOADMMU ‰XDEFƒSEGALOC‰PAGE**ˆCheck�target.* SEGALOC:&‰CMP.L…A6,A5ˆSEE�IF�TARGET�=�REQUESTOR‰BEQ.S�SEGAL2…BRANCH�IF�YES 9‰BTST�#TSKSDORM,TCBSTATE(A5)�NOT�THE�SAME--IS�HE�DORMANT?‰BNE.S‚SEGAL2…OK�IF�DORMANT  **‡ERROR�RETURNS* "ˆEXITƒRTCDSTAT�ERROR�-�NOT�DORMANT SEGALE3:ˆEXIT‚RTCDTFUL‘NO�ROOM�IN�TST SEGALE4:Ã^ÌZÔVÜI!ˆEXIT‚RTCDDPRQ‘SEG�ALREADY�EXISTS  **ˆCheck�for�name�conflict.* SEGAL2:‰IFNE„MULTPROC‰TR0.PƒTCBTSTSM(A5)‰ENDC '‰TR0.FNDSEG�,SGPBNAME(A4) ‰BRA‚SEGALE4 ‰TST.L‚D5‡ANY�EMPTY�ENTRIES?"‰BEQ‚SEGALE3„BRANCH�TO�ERROR�IF�NO  **ˆTest�options�for�pagal.* "‰MOVE.W�SGPBATTR(A4),D0‰ATTRIBUTES‰MOVE.W�SGPBOPT(A4),D1ŠOPTIONS(‰AND.W‚#$27FF,D1�SAVE�ONLY�LEGAL�OPTIONS  1‰BTSTƒ#SGPBOPHY,D1ŒIS�REQUEST�FOR�'AT�PHYS�ADDR'?‰BEQ.S‚SEGAL5’BRANCH�IF�NO -‰BCLRƒ#SGPBOTYP,D1ŒCLEAR�TYPE�IF�AT�PHYS�ADDR SEGAL5:+‰BTSTƒ#SEGAPROM,D0ŒIS�REQUEST�FOR�PHYS�ROM?‰BNE.S‚SEGAL5A‘BRANCH�IF�YES '‰BTSTƒ#SEGAMMIO,D0ŒIS�REQUEST�FOR�MMIO?‰BEQ.S‚SEGAL5B‘BRANCH�IF�NO "‰BSETƒ#SGPBOATR,D1ŒSET�MMIO�OPTION SEGAL5A:/‰BSETƒ#SGPBOPHY,D1ŒSET�'ALLOC�AT�PHYS�ADDR'�OPT#‰BSETƒ#SGPBOTYP,D1ŒSET�'ROM'�OPTION*‰BCLRƒ#SGPBOPAD,D1ŒCLEAR�'LOG=PHYS'�OPTION SEGAL5B:‰CLR.L‚D7–WILL�CONTAIN�#�PAGES&‰MOVE.L�SGPBLA(A4),D6‹STARTING�ADDRESS-‰BTSTƒ#SGPBOPHY,D1ŒIS�'ALLOCATE�AT�PHYS'�SET?‰BEQ.S‚SEGAL5C‘BRANCH�IF�NO #‰BCLRƒ#SGPBOPAD,D1ŒCLEAR�'LOG=PHYS' SEGAL5C:(‰BTSTƒ#SGPBOPAD,D1ŒEXEC�SUPPLY�LOG�ADDR?‰BEQ.S‚SEGAL5CC�BRANCH�IF�NO ‰CLR.L‚D6–NO�ADDRESS‚GIVEN SEGAL5CC: *6*ˆIF�log=phy�bit�not�set�AND�phy�addr�bit�not�set�THEN#*’IF�no�mmu�OR�real-time�tasks�THEN*œset�phy�addr�bit*’ENDIF*ˆENDIF* #‰BTSTƒ#SGPBOPAD,D1ŒIS�LOG=PHY�SET�?‰BNE.S‚SEGAL5CX�YES,�BRANCH *‰BTSTƒ#SGPBOPHY,D1ŒIS�'AT�PHYS�ADDR'�SET�?‰BNE.S‚SEGAL5CX�YES,�BRANCH 3‰BTSTW‚#TSKARTIM,TCBATTR(A5)ƒIS�IT�REAL-TIME�TASK�??‰IF.W��OR.L�MMUHERE��#0�THEN.SƒYES,�A�REAL-TIME�TASK�OR*°NO�MMU�IN�THE�SYSTEM.�BSET‚#SGPBOPHY,D1†IT�MUST�BE�PHYSICAL�ADDRESS‰ENDI SEGAL5CX:-‰MOVE.L�NOTLAM,D7�Get�page�address�range�mask1‰AND.L‚D6,D7“Retain�starting�address�displacement$‰ADD.L‚SGPBSL(A4),D7‹LENGTH�IN�BYTES6‰ADD.L‚NOTLAM,D7�Add�pagesize�for�rounding�to�boundary‰AND.L‚LAM,D7’Round�to�boundary&‰LSR.L‚#8,D7“Convert�to�256-byte�pages:*ˆAND.L‚#$FFFF00,D6�Legal�limit�of�address�(68000�and�010)#‰MOVE.L�D6,A1“GIVE�ADDRESS�TO�PAGAL  **ˆAllocate�memory�for�segment.* .‰BTSTƒ#SGPBOPHY,D1‡IS�REQUEST�AT�PHYS�ADDRESS?*‰BNE.S‚SEGAL5FŒBRANCH�IF�YES�TO�PAGAL�CALL -‰BCLRƒ#SGPBOTYP,D1‡CLEAR�AND�TEST�TYPE�OPTION2‰BNE.S‚SEGAL5FŒBRANCH�IF�CALLER�SPECIFIED�MEM�TYPE .‰LEA„SDEFTYP,A0‰START�OF�DEFAULT�SEGMENT�TYPES'‰BTSTƒ#SEGAROM,D0ˆIS�SEGMENT�READ�ONLY?‰BNE.S‚SEGAL5DŒBRANCH�IF�YES %‰ADD.L‚#1,A0Ž1=OFFSET�FOR�R/W�SEGMENT SEGAL5D:2‰BTSTƒ#TSKASYST,TCBATTR(A5)‚IS�THIS�A�SYSTEM�TASK?‰BNE.S‚SEGAL5EŒBRANCH�IF�YES ,‰ADD.L‚#2,A0ŽINCREMENT�POINTER�FOR�USER�TASK SEGAL5E:,‰MOVE.B�(A0),D1ŒPUT�DEFAULT�TYPE�IN�REGISTER SEGAL5F:.‰SWAPƒD7‘SAVE�#�PAGES�IN�UPPER�1/2�TEMPORARILY‰MOVE.W�D1,D7ŽREQUEST�OPTIONS.‰AND.W‚#$87FF,D7ŠSAVE�ONLY�THOSE�USED�BY�PAGAL'‰MOVE.W�D1,-(A7)‹SAVE�OPTIONS�FOR�LATER%‰SWAPƒD7‘EXCHANGE�#�PAGES�AND�OPTIONS‰TR0.PAGAL‚D7�ALLOCATE�MEMORY%‰BRA.S‚SEGALFMŒBRANCH�IF�MEMORY�FOUND  7 **ˆMemory�not�found�-�error.* ‰ADD.L‚#2,A7'‰SUB.L‚#1,D0ŽCHECK�TYPE�OF�ERROR�RETURN-‰BEQ.S‚SEGALE8ŒBRANCH�IF�MEMORY�NOT�AVAILABLE  **ˆError�returns.* SEGALE7:.‰EXITƒRTCDNFND�MEMORY�REQUESTED�DOES�NOT�EXIST SEGALE8:0‰EXITƒRTCDNMEM�MEMORY�REQUESTED�IS�NOT�AVAILABLE SEGALE11:‰MOVE.W�(A7)+,D1:‰BTSTW‚#SGPBOTYP,D1‹ARE�EITHER�MMIO�OR�PROM�SET?‚Note�that&*§we�are�using�the�stacked�copy�of�the*§options�word.3‰BNE.SƒSEGALE12ŽBRANCH�IF�YES�-�NO�MEMORY�ALLOCATED ‰TR0.PGFR‚(A3),D7�FREE�MEMORY'‰BRA.SƒSEGALE12ŽBRANCH�TO�NORMAL�RETURN ‰BSR…KILLER�SHOULD�NEVER�FAIL SEGALE12:‰EXIT„RTCDLGCFŽADDRESS�CONFLICT  *-*ˆFound�memory�--�Chekc�for�address�conflict.* SEGALFM:#ˆMOVE.L‚A0,A3‰SAVE�PHYSICAL�ADDRESSˆMOVE.L‚D2,D7‰SAVE�#�PAGES%ˆMOVE.L‚D2,D5‰NEED�#�BYTES�FOR�LOGPHY#ˆLSL.Lƒ#8,D5‰CONVERT�PAGES�TO�BYTES6ˆBTSTWƒ#SGPBOPAD,(A7)‚SHOULD�EXEC�SUPPLY�LOGICAL�ADDR?ˆBEQ.SƒSEGALF2‡BRANCH�IF�NO -ˆMOVE.L‚A3,D6‰USE�PHYSICAL�ADDRESS�AS�LOGICAL SEGALF2:"ˆMOVE.L‚D6,A1‰SAVE�LOGICAL�ADDRESSˆTR0.LOGPHYƒ3ˆBRA.S‚SEGALE11‡ADDRESS�CONFLICTS�WITH�EXISTING�SEG3ˆBRA.S‚SEGALE11‡ADDRESS�CONFLICTS�WITH�EXISTING�SEG 2ˆTST.B‚TSTCTL+1(A0,D5)‚IS�THIS�ENTRY�REALLY�EMPTY?6ˆBNE.S‚SEGALE11‰BRANCH�IF�NO�--�CONFLICT�WITH�MMIO�SEG  *#*ˆChecks�out�ok�--�Build�tst�entry.* 3CLRMSKƒEQU„$FFFF-1<=�BEGIN?‰BCS.S„SEGDE_40ŒBRANCH�IF�NO  * *ˆUser�stack�pointer�in�segment."*ˆRelease�exclusive�access�to�TST,*ˆand�exit�with�error;* %‰CMP.W„TSTLE(A5,D5),D0…IS�USP�<=�END?‰BHI.S„SEGDE_40ŒBRANCH�IF�NO ‰IFNE„MULTPROC)‰TR0.VƒTCBTSTSM(A4)ˆTST�SEMAPHORE�ADDRESS‰ENDC %‰EXIT…RTCDALOWŒERROR�-�USP�IN�SEGMENT **ˆUSP�not�in�segment."*ˆRelease�exclusive�access�to�TST,*ˆand�exit�(subroutine�exit);* SEGDE_40: ‰BSR.S…DESEG_SUB‹call�deseg_sub; ‰IFNE„MULTPROC)‰TR0.VƒTCBTSTSM(A4)ˆTST�SEMAPHORE�ADDRESS‰ENDC !‰EXIT†SUB‘exit�(subroutine_exit);‰PAGE=***************************************************************'**‡Subroutine�to�de-allocate�a�segment.**‡Called�by�SEGDEAL�and�DSEGX.**=*************************************************************  *%*ˆCheck�for�global�or�shared�segment.* "SHARMSK‚EQU„1<,,TCBSESSN(A4)‰BRA.SƒDESEG_07ŽFOUND�ENTRY +‰BSR…KILLER�NO�ENTRY�--�THERE�SHOULD�BE�ONE  **ˆUPDATE�GST�ENTRY* DESEG_07:'‰MOVE.W‚GSTNP(A0),D6…GET�#�PAGES�IN�SEG‰SUB.Wƒ#1,D6ŒSUBTRACT�1'‰ADD.WƒTSTLB(A5,D5),D6‚PLUS�BEGIN�=�END ‰MOVE.W‚D6,TSTLE(A5,D5)‚SAVE�END&‰SUB.Wƒ#1,GSTCNT(A0)„DECREMENT�#�USERS ‰CLR.LƒD6 ‰MOVE.W‚GSTCNT(A0),D6…SAVE�COUNT3‰BTST„#SGPBORMV,D4†CHECK�OPTION�-�CLEAR�PERM�STATUS!‰BEQ.SƒDESEG_7AŠBRANCH�IF�NOT�SET "‰BCLR„#15,D6ŒCLEAR�PERM�STATUS�BIT"‰MOVE.W‚D6,GSTCNT(A0)…RESAVE�COUNT  *"*ˆGive�up�exclusive�addess�to�gst.* DESEG_7A:‰IFNE„MULTPROC ‰TR0.VƒSEMGST‰ENDC  *(*ˆCheck�to�see�if�pages�should�be�freed.* ‰TST.WƒD6”CHECK�COUNT.‰BNE.SƒDESEG_09ŽIF�NOT�ZERO�-DO�NOT�FREE�PAGES  *+*ˆFree�the�pages�belonging�to�this�segment.* #SPSEGMK‚EQU„1< ‰BRA.SƒDESEG_09†OK�-�PAGES�FREED ‰BSR…KILLER‰PAGEFREE�FAILED  *#*ˆRemove�this�segment�from�the�tst.* *#*ˆUnload�this�segment�from�the�MMU.* DESEG_09:*‰CLR.W…TSTCTL(A5,D5)‡INVALIDATE�MMU�ENTRY.-‰BSR‡UNLDMMU�UNLOAD�THE�SEGMENT�FROM�THE�MMU. )‰CLR.L…TSTANAME(A5,D5)…CLEAR�SEGMENT�NAME8‰CLR.L…TSTAATTR(A5,D5)…CLEAR�ATTRIBUTES,�TYPE�AND�COUNT. *‰CLR.L…TSTLB(A5,D5)ˆCLEAR�TSTLB�AND�TSTLE. ‰CLR.W…TSTPO(A5,D5)ˆCLEAR�TSTPO. 3‰SUB.B…#1,TSTCSEGS(A5)…DECREMENT�NUMBER�OF�SEGMENTS  *-*ˆGive�up�exclusive�access�to�tst�and�return.* ‰IFNE„MULTPROC‰TR0.VƒTCBTSTSM(A4)‰ENDC‰RTS‰END=/*=/*†M68XXX.SEGSHAR.AF=/*,=/* Chain file to assemble M68XXX.SEGSHAR.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.SEGSHAR.LS=/*=/IFC \1ƒ=ARG�M68XXX.SEGSHAR.LS=/ENDIF=/*3=ASM M68XXX.SEGSHAR.SA,M68XXX.SEGSHAR.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.SEG.EQ=/*ƒ9995.&.GST.EQ=/*}=/*=END8 éééééé‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*ˆINCLUDEƒ9995.&.GST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.SEG.EQ‰INCLUDEƒ9995.&.GST.EQ‰LIST‰PAGEFSEGSHAR‚IDNTƒ5,1ƒ68xxx�DIRECTIVES--SHARE�SEGMENT�AND�ATTACH�TO�SEGMENT*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*$*„SEGSHAR�--�REV�2.00ƒ4/20/79‚(HLD6)*š2/26/81‚(HLD6) *„ATTSEG‚-*Œ--�TRAP�1�ROUTINES*:*…PURPOSE:‚SEGSHAR�-‚GRANT�SHARED�ACCESS�TO�MEMORY�SEGMENT+*�ATTSEG‚-‚ATTACH�SHAREABLE�SEGMENT�TO�SELF*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS(*‘A4�HAS�SEGMENT�PARAMETER�BLOCK�ADDRESS* 0�-�TARGET�TASK�NAME* 4�-�SESSION�CODE*Ÿ10�-�SEGMENT�ATTRIBUTES*Ÿ12�-�SEGMENT�NAME*Ÿ16�-�LOGICAL�ADDRESS*ŠEXIT:ƒD0�HAS�RETURN�CODE*’D0�=�0‚GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST9*ŠRTCDTFUL�-�5ƒTARGET�TST�IS�FULL�-�NO�ROOM�FOR�NEW�ENTRY8*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�SEG�NAME�FOUND�IN�TST2*ŠRTCDNFND�-�7ƒENTRY�NOT�FOUND�IN�GLOBAL�SEG�TABLE6*ŠRTCDALOW�-�9ƒREQUESTER�CANNOT�SPECIFY�SELF�AS�TARGET'*ŠRTCDLGCF�-11ƒLOGICAL�ADDRESS�CONFLICT*‹SECTION�LEVEL03* ‰XDEF†ATTSEG ‰XDEF†SEGSHAR ‰XREF†KILLER ‰XREF†LOADMMU‰PAGE**ˆHere�for�ATTSEG. *ˆSet�target_tcb�<==�client_tcb.* ATTSEG:5‰MOVE.L„A6,A5�MOVE�CALLER'S�TCB�ADDR�TO�A5�FOR�ATTSEG9‰BSR.S…SEGSHR_SUBŠCall�the�common�subroutine,�SEGSHR_SUB. :‰MOVE.L„TCBTST(A6),A5‡Now,�set�A5�<==�TST�of�calling�task,4‰BSR‡LOADMMU�load�the�MMU�(to�describe�new�segment),%‰EXIT†SUB‘and�exit�(subroutine�exit).‰PAGE **ˆHere�for�SEGSHAR.)*ˆIf�target_tcb�=�client_tcb,�then�error.* SEGSHAR:+‰CMP.L…A6,A5�ARE�REQUESTOR�AND�TARGET�SAME?<‰EXIT.EQƒRTCDALOWŠERROR�-�REQUESTOR�AND�TARGET�ARE�SAME�TASK Si )9 9‰BSR.S…SEGSHR_SUBŠCall�the�common�subroutine,�SEGSHR_SUB,%‰EXIT†SUB‘and�exit�(subroutine�exit).‰PAGE**ˆGet�exclusive�access�to�gst.* SEGSHR_SUB:‰IFNE„MULTPROC ‰TR0.PƒSEMGST‰ENDC **ˆFind�entry�in�gst.* 2‰TR0.FNDGSG‚SGPBNAME(A4),SGPBATTR(A4),TCBSESSN(A5)‰BRA.SƒSEGSHR5�FOUND�ENTRY ‰EXIT„RTCDNFNDŽNO�ENTRY�IN�GST  **ˆError�returns.* SEGSHR7E:ŠEXIT„RTCDTFUL�NO�ROOM�IN�TST SEGSHR8E:ŠEXIT„RTCDLGCF�ADDRESS�CONFLICT SEGSHR9E: ŠEXIT„RTCDDPRQ�NAME�FOUND�IN�TST  *!*ˆLook�for�target�segment�in�tst.**�A3�=�GST�ENTRYƒA4�=�PARAM�BLK!*�A5�=�TARGET�TCB‚A2�=�TARGET�TST SEGSHR5:$‰MOVE.L‚A0,A3ŠSAVE�GST�ENTRY�ADDRESS ‰IFNE…MULTPROC‰TR0.P„TCBTSTSM(A5)‰ENDC 6‰MOVE.L‚TCBTST(A5),A2„A2,A3,A6�TARG�TST,GST,CALLER�TCB‰TR0.FNDSEG‚(A2),GSTNAME(A3)*‰BRA.SƒSEGSHR9E†FOUND�IT�--�INVALID�TARGET !‰TST.LƒD5ŒIS�THERE�AN�EMPTY�ENTRY‰BEQ…SEGSHR7E†BRANCH�IF�NO  **ˆCheck�for�address�conflict.* !‰CLR.L„D5ˆCLEAR�BEFORE�SHORT�MOVE,‰MOVE.W‚GSTNP(A3),D5ƒ#�PAGES,�LOG�ADDR�IN�D6$‰LSL.Lƒ#8,D5†SEGMENT�LENGTH�IN�BYTES9‰BTST„#SGPBOLNG,SGPBOPT(A4)‚IS�LENGTH�SUPPLIED�BY�CALLER?‰BEQ.SƒSEGSHR5BŽBRANCH�IF�NO #‰CMP.LƒSGPBSL(A4),D5‰IS�SIZE�VALID?‰BCC.SƒSEGSHR5AŽBRANCH�IF�YES %‰EXIT„RTCDPCNTŽERROR�-�BAD�SIZE�FIELD SEGSHR5A:/‰MOVE.L‚SGPBSL(A4),D5…GET�SIZE�FROM�PARAM�BLOCK‰ADD.Lƒ#$FF,D5‹*‰CLR.BƒD5�*�ROUND�TO�PAGES SEGSHR5B:!‰MOVE.L‚D5,D2ŒSAVE�LENGTH�(BYTES))‰MOVE.L‚SGPBLA(A4),D6„GET�LOGICAL�ADDRESS ‰CLR.BƒD68‰BTST„#SGPBOPAD,SGPBOPT(A4)‚SHOULD�EXEC�SUPPLY�LOG�ADDR?‰BEQ.SƒSEGSHR5CŽBRANCH�IF�NO -‰MOVE.L‚GSTPA(A3),D6ŠUSE�PHYS�ADDR�AS�LOGICAL SEGSHR5C:‰TR0.LOGPHY‚(A2)‰BRA.SƒSEGSHR8E$‰BRA.SƒSEGSHR8EŠLOG�ADDRESS�CONFLICT '‰TST.LƒD5ŠDID�LOGPHY�RETURN�MMU�OFFSET?‰BNE.SƒSEGSHR6…BRANCH�IF�YES $‰BSR…KILLER†SHOULD�NEVER�RETURN�ZERO SEGSHR6:-‰TST.BƒTSTCTL+1(A0,D5)ƒIS�ENTRY�REALLY�EMPTY?‰BNE.SƒSEGSHR8E  **ˆPut�new�entry�in�target�tst.* 0‰MOVE.L‚GSTNAME(A3),TSTANAME(A2,D5)�SEGMENT�NAME&‰CLR.BƒTSTAUCNT(A2,D5)�CLEAR�USE�COUNT'‰MOVE.L‚D6,D0‹LOGICAL�BEGINNING�ADDRESS!‰LSR.Lƒ#8,D6‹LOGICAL�BEGIN�(PAGE)‰MOVE.W‚D6,TSTLB(A2,D5)�SAVE�IT#‰LSR.Lƒ#8,D2‹CONVERT�BYTES�TO�PAGES‰ADD.WƒD2,D6‹PLUS�#�PAGES‰SUB.Wƒ#1,D6‹MINUS�1%‰MOVE.W‚D6,TSTLE(A2,D5)�=�LOGICAL�END'‰NEG.LƒD0ŽGET�NEGATIVE�OF�LOGICAL�BEGIN'‰ADD.LƒGSTPA(A3),D0„PHYS�ADDR�-�LOG�BEG#‰LSR.Lƒ#8,D0‹DIV�BY�8�=�PHYS�OFFSET,‰MOVE.W‚D0,TSTPO(A2,D5)�SAVE�PHYSICAL�OFFSET)‰MOVE.W‚#RAMCTL,TSTCTL(A2,D5)�SET�FOR�RAM%‰BTST„#SEGAROM,GSTATTR(A3)‚IS�IT�ROM?‰BEQ.S„SEGSHR7ŽNO )‰MOVE.W‚#ROMCTL,TSTCTL(A2,D5)ˆSET�FOR�ROM SEGSHR7:3‰MOVE.WƒGSTATTR(A3),TSTAATTR(A2,D5)‚MOVE�ATTRIBUTES+‰BSET…#SEGAUSED,TSTAATTR(A2,D5)„MARK�IN�USE(‰ADD.B„#1,TSTCSEGS(A2)‡COUNT�NEW�SEGMENT(‰ADD.W„#1,GSTCNT(A3)‰ADD�TO�COUNT�IN�GST6‰MOVE.LƒGSTPA(A3),TCBA0(A6)ƒRETURN�PHYS�ADDR�TO�CALLER  *-*ˆGive�up�exclusive�access�to�tst�and�return.* ‰IFNE„MULTPROC‰TR0.VƒTCBTSTSM(A5)‰ENDC ‰IFNEƒMULTPROC ‰TR0.V‚SEMGST‰ENDC !‰RTS›Return�to�calling�directive.‰ENDééé9 =/*=/*†M68XXX.SELFTEST.AF=/*-=/* Chain file to assemble M68XXX.SELFTEST.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.SELFTEST.LS=/*=/IFC \1ƒ=ARG�M68XXX.SELFTEST.LS=/ENDIF=/*5=ASM M68XXX.SELFTEST.SA,M68XXX.SELFTEST.RO,\1;MRZ=040=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*}=/*=ENDéééééé(‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰LIST‰PAGE9SELFTEST�IDNTƒ5,1ƒ68xxx�SYSTEM�SELFTEST�INTERRUPT�HANDLER*ˆ*********************ˆ*�SELFTEST�1.00„**ˆ*’**ˆ*�HLD6ƒ06/24/81‚**ˆ**********************…SELFTEST�INTERRUPT�ROUTINE*>*…THIS�ROUTINE�IS�USED�ONLY�TO�RESPOND�TO�A�SELFTEST�INTERRUPT-*…ON�A�VERSAMODULE�01�(AUTO�VECTOR�-�LEVEL�2)*%*…REGISTER�USAGE:�ALL�REGISTERS�SAVED*‰SECTION�LEVEL00*3CONTREG‚EQU„$F70030‡VERSAMODULE�01�CONTROL�REGISTER*‰XDEFƒSELFTEST‰XREF.S�SLFTSTA7*7SELFTEST�TST.L‚SLFTSTA7‡IS�THIS�FIRST�ENTRY�TO�ROUTINE?‰BNE.S‚SELFT4‰BRANCH�IF�NO!‰OR.Wƒ#$700,SR‡INHIBIT�INTERRUPTS-‰MOVEM.L�D0-D7/A0-A6,-(A7)‚SAVE�ALL�REGISTERS&‰MOVE.L‚A7,SLFTSTA7ƒSAVE�STACK�POINTER)‰MOVE.W‚60(A7),SR…RESTORE�INTERRUPT�LEVELBSELFT4ƒMOVE.L‚SLFTSTA7,A7ƒRESTORE�A7�IN�CASE�THIS�IS�NOT�1ST�ENTRY*6*„CODE�TO�CALL�A�SELF�TEST�ROUTINE�CAN�BE�ENTERED�HERE*!‰OR.W„#$700,SR†INHIBIT�INTERRUPTS'‰MOVE.B‚CONTREG,D0„GET�CONTROL�REGISTER%‰OR.B„#$20,D0‡SET�BIT�TO�TURN�OFF�LED/‰MOVE.B‚D0,CONTREG„PUT�IT�INTO�CONTROL�REGISTER4‰MOVE.L‚SLFTSTA7,A7ƒRELOAD�A7�(MAYBE�IT�WAS�CHANGED)0‰MOVEM.L�(A7)+,D0-D7/A0-A7ƒRESTORE�ALL�REGISTERS%‰CLR.LƒSLFTSTA7†CLEAR�ENTRY�FLAG�WORD ‰RTE“GO�BACK‰ENDé: é12=/*=/*†M68XXX.SERVE.AF=/**=/* Chain file to assemble M68XXX.SERVE.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.SERVE.LS=/*=/IFC \1ƒ=ARG�M68XXX.SERVE.LS=/ENDIF=/*/=ASM M68XXX.SERVE.SA,M68XXX.SERVE.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TIOT.EQ=/*}=/*=ENDéééééé:‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TIOT.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TIOT.EQ‰LIST‰PAGE4SERVE„IDNTƒ5,1‡68xxx�DIRECTIVE--BECOME�A�SERVER�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*„SERVER‚--�REV�2.00ƒ6/25/79‚(HLD6)*š2/20/81‚(HLD6)*Œ--�TRAP�1�ROUTINE*0*…PURPOSE:‚REQUESTOR�WISHES�TO�CLAIM�A�USER�TRAP/*�WILL�BECOME�SERVER�FOR�OTHER�TASKS�USING�TRAP*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS'*‘A4�HAS�SERVER�PARAMETER�BLOCK�ADDRESS* 0�-�INTERRUPT�ADDRESS* 4�-�TRAP�IDENTIFIER* 5�-�1�BYTE�RESERVED**ŠEXIT:ƒD0�HAS�RETURN�CODE*’D0�=�0‚GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE**ŠRTCDNTBL�-�4ƒCALLER'S�ASQ�DOES�NOT�EXIST=*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�THIS�TRAP�ALREADY�ASSIGNED-*ŠRTCDALOW�-�9ƒONLY�SYSTEM�TASK�CAN�BE�SERVER8*ŠRTCDADR1�-12ƒINTERRUPT�ADDR�NOT�IN�CALLER'S�ADDR�SPACE*‰SECTION�LEVEL04* ‰XDEF‚SERVER‰XREF.SƒSEMTIOT ‰XREF.SƒTIAT ‰XREF.SƒTIOT‰PAGESERVER:)‰MOVE.W‚4(A4),D7ŽSAVE�OPTIONS�AND�PB�SIZE4‰BTST„#TSKASYST,TC: BATTR(A6)�IS�CALLER�A�SYSTEM�TASK?‰BNE.SƒSERV1‘BRANCH�IF�YES 2‰BCLR„#14,D7�DO�NOT�ALLOW�USER�TO�SET�TERM�MSG�BIT  **‡CHECK�INTERRUPT�ADDRESS* SERV1:"‰TST.Lƒ(A4)’WAS�INT�ADDR�SUPPLIED?+‰BEQ.SƒSERV2‘NO�INTERRUPT�ADDRESS�-�USE�ASR "‰TR0.LOGPHY‚,(A4),#4#‰BRA.SƒSERV2‘BRANCH�IF�GOOD�ADDRESS ‰NOP(‰EXIT„RTCDADR1ŽILLEGAL�INTERRUPT�ADDRESS  **‡CHECK�REQUESTOR'S�ASQ* SERV2:!‰TST.LƒTCBASQ(A6)ŒDOES�ASQ�EXIST?.‰EXIT.EQ�RTCDNTBLŽERROR�-�REQUESTOR�HAS�NO�ASQ  **…GET�EXCLUSIVE�ACCESS�TO�TIOT* ˆIFNE…MULTPROCˆTR0.P„SEMTIOTˆENDC  *"*…CHECK�CURRENT�ASSIGNMENT�IN�TIAT* ‰MOVE.B‚4(A4),D2„TRAP�IDENTIFIER$‰AND.Lƒ#$0F,D2…MUST�BE�IN�RANGE�0-15CbL"‰LEA…TIAT,A2…ADDRESS�OF�TIAT!‰TST.Bƒ0(A2,D2)„IS�TRAP�ASSIGNED?,‰EXIT.NE�RTCDDPRQ„YES�-ERROR-�CAN'T�CLAIM�IT  **†BUILD�TIOT�ENTRY*  7‰MOVE.B‚#TIATUSER,0(A2,D2)„SET�ASSIGNMENT�VALUE�IN�TIAT‰LEA…TIOT,A2�ADDRESS�OF�TIOT$‰MULU„#TIOTEL,D2ŒGET�OFFSET�TO�ENTRY9‰MOVE.L‚A6,TIOTTCB(A2,D2)…SAVE�TASK�CONTROL�BLOCK�ADDRESS,‰MOVE.L‚TCBSESSN(A6),TIOTSESS(A2,D2)�SESSION.‰MOVE.W‚#1,TIOTSEM(A2,D2)…INITIALIZE�SEMAPHORE)‰CLR.LƒTIOTSEM+2(A2,D2)†CLEAR�SEM�POINTER.‰MOVE.L‚(A4),TIOTADDR(A2,D2)‚INTERRUPT�ADDRESS*‰CLR.WƒTIOTMCNT(A2,D2)‡CLEAR�MESSAGE�COUNT2‰MOVE.W‚D7,TIOTSTAT(A2,D2)„SAVE�STATUS�AND�PB�SIZE1‰AND.Bƒ#$60,TIOTSTAT(A2,D2)‚SAVE�ONLY�STATUS�BITS1‰BSET„#TIOTSON,TIOTSTAT(A2,D2)�SET�ENABLE�FLAG�ON  *"*„GIVE�UP�EXCLUSIVE�ACCESS�TO�TIOT* SERVX1ƒEQU…*‰IFNE„MULTPROC‰TR0.VƒSEMTIOT‰ENDC ‰EXIT„SUB‰ENDéééé=/*=/*†M68XXX.SETPRI.AF=/*+=/* Chain file to assemble M68XXX.SETPRI.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.SETPRI.LS=/*=/IFC \1ƒ=ARG�M68XXX.SETPRI.LS=/ENDIF=/*1=ASM M68XXX.SETPRI.SA,M68XXX.SETPRI.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéé; ééééT‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE7SETPRI‚IDNT‚5,1…68xxx�DIRECTIVE--CHANGE�TASK'S�PRIORITY*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡********************‡*‚S�E�T�P�R�I„*ƒSET�PRIORITY*‡*‚REV�1.00ƒHLD6**‡*‚08/29/79‡**‡********************>*†THIS�ROUTINE�SETS�A�NEW�CURRENT�PRIORITY�FOR�THE�TARGET�TASK***‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A4�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�TASK�NAME*—4�-�SESSION�CODE*—8�-�PRIORITY�(1�BYTE)*’A5�HAS�TARGET�TCB�ADDRESS**‹EXIT�:�D0�HAS�RETURN�CODE&*’D0�=�0„GOOD�RETURN,�ATTRIBUTES�IN�A0*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST.*ŠRTCDALOW�-�9ƒUSER�CANNOT�SET�SYSTEM�PRIORITY**ŠRTCDSTAT�-10ƒPRIORITY�SPECIFIED�IS�>�MAX***‰SECTION�LEVEL04* ‰XDEF„SETPRI‰PAGE*$*ˆIs�caller�allowed�to�set�priority?* SETPRI:4‰BTST„#TSKASYST,TCBATTR(A6)†IS�CALLER�A�SYSTEM�TASK?‰BNE.SƒSETPRI3”BRANCH�IF�YES 4‰BTST„#TSKASYST,TCBATTR(A5)†IS�TARGET�A�SYSTEM�TASK? $‰EXIT.NE�RTCDALOW“IF�YES�THEN�ERROR.*«USER�TASK�CANNOT�SET�PRIORITY*«FOR�SYSTEM�TASK. **ˆSet�priority.* SETPRI3:2‰MOVE.Bƒ8(A4),D0’GET�NEW�PRIORITY�FROM�PARAM�BLOCK,‰CMP.B„TCBLPRI(A5),D0ŒIS�NEW�PRIORITY�>�MAX?‰BLS.S„SETPRI4“BRANCH�IF�NO ‰CLR.L„TCBA0(A6)‘CLEAR�A0:‰MOVE.BƒTCBLPRI(A5),TCBA0+3(A6)ƒRETURN�MAX�PRIOR�TO�CALLER (‰EXIT…RTCDSTAT’ERROR�-�PRIORITY�TOO�HIGH SETPRI4:/‰MOVE.BƒD0,TCBCPRI(A5)ŒSET�NEW�CURRENT�PRIORITY-‰MOVE.BƒD0,TCBRPRI(A5)ŒSET�NEW�READY�PRIORITY!‰EXIT…SUB—exit�(subroutine�exit);‰END]S=/*=/*†M68XXX.SGSEM.AF=/**=/* Chain file to assemble M68XXX.SGSEM.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to M68XXX.SGSEM.LS=/*=/IFC \1ƒ=ARG�M68XXX.SGSEM.LS=/ENDIF=/*/=ASM M68XXX.SGSEM.SA,M68XXX.SGSEM.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.UST.EQ=/*}=/*=END; ééééééf‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.UST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.UST.EQ‰LIST‰PAGE:SGSEM„IDNTƒ5,1„68xxx�DIRECTIVES--SIGNAL�AND�WAIT�SEMAPHORE*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*"*„WTSEMƒ--�REV�2.00ƒ5/26/81ƒ(HLD6)*…SGSEM‚--�TRAP�1�ROUTINES*8*‡PURPOSE:ƒREQUEST�TO�SIGNAL�OR�WAIT�ON�A�USER�SEMAPHORE*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS *‘A4�HAS�PARAMETER�BLOCK�ADDRESS* 0�-�SEMAPHORE�NAME* 4�-�SEMAPHORE�KEY* 9�-�SEMAPHORE�TYPE�(1�BYTE)**ŠEXIT:ƒD0�HAS�RETURN�CODE)*’D0�=�0‚GOOD�RETURN,�SEGMENT�DEALLOCATED*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE0*ŠRTCDNFND�-�7ƒENTRY�NOT�FOUND�IN�USER�SEM�TABLE4*ŠRTCDALOW�-�9ƒTYPE�1�WAIT�OR�SIGNAL�OUT�OF�SEQUENCE*‰SECTION�LEVEL04* ‰XDEF‚SGSEM ‰XDEF‚WTSEM‰XREF.S�USTBEG‰PAGESGSEM:'‰CLR.WƒD7‡FLAG�--�ENTRY�POINT�IS�SIGNAL ‰BRA.SƒWTSEM1  WTSEM:)‰MOVE.W‚#1,D7„FLAG�--�ENTRY�POINT�IS�WAIT  **ˆDECODE�SEMAPHORE�KEY* WTSEM1:‰MOVE.Lƒ4(A4),D3‰SEMAPHORE�KEY  **†CHECK�ENTRY�FOUND*'*‰A1�=�ADDRESS�OF�UST„D3�=�ENTRY�OFFSET* (‰MOVE.L‚USTBEG,A1‡ADDR�OF�USER�SEM�TABLE‰MOVE.W‚D3,D0‹ENTRY�OFFSET‰LSR.Wƒ#8,D0‹PAGE�#�OF�OFFSET/‰CMP.WƒUSTNPAGE(A1),D0‚CHECK�FOR�OFFSET�TOO�BIG&‰BGE.SƒWTSEME2‰ERROR�IF�OFFSET�TOO�BIG *‰MOVE.L‚(A4),D4‰GET�SEMAPHORE�NAME�FROM�PB0‰CMP.LƒUSTSNAME(A1,D3),D4ƒCOMPARE�SEMAPHORE�NAME#‰BNE.SƒWTSEME2‹NO�COMPARE�-�BAD�KEY *‰TST.WƒUSTUCNT(A1,D3)„IS�SEMAPHORE�IN�USE?‰BEQ.SƒWTSEME2ŒCAN�NOT�BE�0 (‰CMP.Bƒ#1,USTTYPE(A1,D3)ƒIS�THIS�TYPE�1?‰BNE.SƒWTSEM4ŽNO +‰CMP.BƒUSTXCNT(A1,D3),D7„COMPARE�SG-WT�FLAG(‰BEQ.SƒWTSEME3ŽBRANCH�IF�OUT�OF�SEQUENCE *‰MOVE.B‚D7,USTXCNT(A1,D3)„RESET�SG-WT�FLAG WTSEM4:-‰TST.WƒUSTUCNT(A1,D3)‡IS�THIS�SEM�OR�POINTER? ‰BPL.SƒWTSEM5 o^x< ‰MOVE.L‚USTSPTR(A1,D3),D3  *$*†FOUND�GOOD�ENTRY�-�DO�PSEM�OR�VSEM* WTSEM5‚TST.W„D7ŠWHICH�ENTRY?ˆBEQ.S„SGSEM5†IT�WAS�SGSEM ˆTR0.P„ ˆEXIT…SUB SGSEM5:ˆTR0.V„ ˆEXIT…SUB  **†ERROR�RETURNS* WTSEME2‚EXIT„RTCDNFND WTSEME3‚EXIT„RTCDALOW‰ENDéééééé‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.IOV.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.IOV.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE‰IFEQ…CHIPTYPE-680008SINT…IDNT…5,1ƒ68000�DIRECTIVE--SIMULATE�INTERRUPT�TO�ISR‰ENDC‰IFEQ…CHIPTYPE-680108SINT…IDNT…5,1ƒ68010�DIRECTIVE--SIMULATE�INTERRUPT�TO�ISR‰ENDC*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*******************'*‡*‚S�I�N�Tˆ*ƒSIMULATE�INTERRUPT�TO�ISR*‡*‘**‡*‚2.00…HLD6‚**‡*…10/14/80„**‡*…03/30/81„**‡*********************,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‚ChangesG*…--------‚------‚-----------------------------------------------------D*†1/24/84ƒMSL„Pushed�a�VOR�on�stack�(i�f�M68010)�before�SINTRTN,�and4*—an�SR�after,�so�that�the�RTE�in�COMINTZ�will�work.***†ENTRY:‚A6‚REQUESTOR'S�TCB*ŽA4‚PARAMETER�TABLE�POINTER*�(A4)�N/A‚OPTIONS*Œ2(A4)�INTERRUPT�PRIORITY*Œ3(A4)�VECTOR�NUMBER**„EXIT‚D0�=�0‚SUCCESS*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE *ŠRTCDALOW�-�9ƒLEVEL�#�NOT�VALID**ŠRTCDENAB�-14ƒVECTOR�HAS�NOT�BEEN�CLAIMED*‰SECTION�LEVEL03* ‰XDEF„SINT ‰XREF.S‚TRACER‰XREF.S‚TRACFLAG‰XREF.S‚VCTUBGN‰PAGESINT: ‰CLR.LƒD2‰MOVE.B‚3(A4),D2†VECTOR�NUMBER#‰MOVE.L‚VCTUBGN,A1„VECTOR�USE�TABLE(‰TST.Bƒ0(A1,D2)†HAS�VECTOR�BEEN�CLAIMED?,‰EXIT.LE�RTCDENAB†ERROR�-�VECTOR�NOT�CLAIMED ‰CLR.LƒD32‰MOVE.B‚2(A4),D3‡LEVEL�NUMBER�(INTERRUPT�PRIORITY)‰BEQ.SƒSINT04‰ZERO�IS�NOT�VALID ‰CMP.Wƒ#6,D3ŠMUST�BE�1�TO�6‰BLE.SƒSINT06‰BRANCH�IF�OK SINT04:'‰EXIT„RTCDALOW‡ERROR�-�BAD�LEVEL�NUMBER  SINT06:‰LSL.L„#8,D3ŠMOVE�LEVEL�#$‰BSET…#SRMODE,D3…SET�SUPERVISOR�MODE  *.*ˆTEMPORARY�--�FOR�TIMING�--�RETURN�TO�SINTRTN* ‰IFEQ…CHIPTYPE-680101‰MOVE.Wƒ#$0084,-(A7)ƒIF�68010,�PUSH�VOR�ON�STACK.‰ENDC < €^‰#‰PEA†SINTRTN(PC)„RETURN�ADDRESS*‰MOVE.WƒSR,-(A7)‡SR�(FOR�RTE�INSTRUCTION). ‰IFEQ…CHIPTYPE-680101‰MOVE.Wƒ#$0084,-(A7)„IF�68010,�PUSH�VOR�ON�STACK.‰ENDC (‰LSL.L„#2,D2‹CONVERT�VECTOR�#�TO�ADDRESS)‰MOVE.LƒD2,A0‹PUT�VECTOR�ADDRESS�IN�A�REG2‰MOVE.Lƒ(A0),-(A7)†PUT�CONTENTS�OF�VECTOR�ON�STACK/‰MOVE.WƒD3,-(A7)ˆPUT�SR�WITH�LEVEL�SET�ON�STACK.‰BTST…#TRCFSINT,TRACFLAG+1‚TRACE�ENTRY�WANTED?‰BEQ.S„SINT10ŠBRANCH�IF�NO ‰BSR†TRACERŠGO�BUILD�TRACE�ENTRY‰DC.W…$EE07‹TRACE�CODE SINT10:‰RTE–PHONEY�INTERRUPT  **„RETURN�TO�DO�TRACE* SINTRTN:.‰BTST„#TRCFSINT,TRACFLAG+1‚TRACE�ENTRY�WANTED? ‰BEQ.SƒSINT99 ‰BSR…TRACER‹BUILD�TRACE�ENTRY‰DC.W„$DD07ŒTRACE�CODE SINT99:!‰EXIT„SUBŽexit�(subroutine�exit);‰ENDééééé=/*=/*†M68XXX.SNAPTRAC.AF=/*-=/* Chain file to assemble M68XXX.SNAPTRAC.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.SNAPTRAC.LS=/*=/IFC \1ƒ=ARG�M68XXX.SNAPTRAC.LS=/ENDIF=/*5=ASM M68XXX.SNAPTRAC.SA,M68XXX.SNAPTRAC.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TRACE.EQ=/*}=/*=ENDééééé= 鑉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TRACE.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TRACE.EQ‰LISTˆPAGE=SNAPTRAC‚IDNTƒ5,1„68xxx�DIRECTIVE--GIVE�TRACE�TABLE�TO�CALLER*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡***************************‡*‚SNAPTRACŽ**‡*˜**‡*ƒ1.00ƒC313‚7-30-79�**‡**************************#*ˆMOVE�TRACE�TABLE�TO�USER'S�BUFFER"*ˆAND�CHANGE�POINTER�AND�END�TO�BE*ˆCORRECT�ADDRESSES**ˆENTRY:‚A6ƒREQUESTOR'S�TCB*�A0ƒADDRESS�OF�USER'S�BUFFER**ˆEXIT:ƒD0=�0‚SUCCESS*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*3*ŠRTCDADR1�-12ƒBUFFER�ADDR�NOT�IN�USER'S�ADDR�SPACE* *�01234567*‡USESƒDR�**�** *ŽA*********„CHECK�BUFFER�IN�USER'S�SPACE*‹SECTION�LEVEL04*‹XDEFƒSNAPTRAC‹XREF.S�TRACEBEG‰PAGE SNAPTRAC:‰MOVE.L„A0,D6�LOGICAL�START!‰MOVE.L„A0,A5�SAVE�BUFFER�ADDRESS*‰MOVE.L„TRACEBEG,A1‰ADDRESS�OF�TRACE�TABLE ‰MOVE.L„A1,D0‰BEQ.S…SNPTRCER *‰MOVE.L„TRCLNG(A1),A0‡END�ADDRESS�OF�TABLE‰SUB.L…A1,A0�LENGTH�OF�TABLE‰MOVE.L„A0,D5�LENGTH‰MOVE.L„A0,D2�SAVE�LENGTH"‰MOVE.L„TCBTST(A6),A0‡WHERE�TST�IN ‰TR0.LOGPHY‰BRA.S…SNAPTRC1ŒGOOD�RETURN ‰NOP SNPTRCER:!‰EXIT†RTCDADR1ŒBAD�BUFFER�ADDRESS  *#*ƒMOVE�TRACE�TABLE�TO�USER'S�BUFFER*ƒA1�CONTAINS�'FROM'�ADDRESS* SNAPTRC1:‰MOVE.L„D6,A2�'TO'�ADDRESS‰MOVE.L„D2,D3�SAVE�LENGTH‰LSR.L…#2,D2�DIVIDE�LENGTH�BY�42‰SUB.L…#1,D2�ADJUST�FOR�DECREMENT�AND�BRANCH�INST. SNAPTRC2:#‰MOVE.L„(A1)+,(A2)+‰MOVE�LONG�WORDS!‰DBRA†D2,SNAPTRC2‰DECREMENT�COUNT  *2*ƒUPDATE�TRCPTR�AND�TRCLNG�TO�USER'S�ADDRESS�SPACE* ‰MOVE.L„D6,A2�'TO'�ADDRESS‰MOVE.L„A5,A4�BUFFER�ADDRESS*‰MOVE.L„TRACEBEG,A1‰ADDRESS�OF�TRACE�TABLE#‰MOVE.L„TRCPTR(A1),A3‡TRACE�POINTER.‰SUB.L…A1,A3�TRACE�POINTER�STRIPPED�OF�ADDRESS+‰ADD.L…A3,A4�UPDATED�TRACE�POINTER�FOR�USERš_£0‰MOVE.L„A4,(A2)+ŒUPDATED�POINTER�TO�USER'S�TABLE'‰ADD.L…D3,A5�LENGTH�PLUS�BUFFER�ADDRESS/‰MOVE.L„A5,(A2)+ŒUPDATED�LENGTH�TO�USER'S�TABLE!‰EXIT†SUB‘exit�(subroutine�exit);‰ENDéééé= ééé=/*=/*†M68XXX.SPURINT.AF=/*,=/* Chain file to assemble M68XXX.SPURINT.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.SPURINT.LS=/*=/IFC \1ƒ=ARG�M68XXX.SPURINT.LS=/ENDIF=/*3=ASM M68XXX.SPURINT.SA,M68XXX.SPURINT.RO,\1;MRZ=040=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.PANEL.EQ=/*}=/*=ENDéééééé« \'M68XXX SPURINT SAÀÀ6qqSTDTIM AFÉÉqqSTDTIM SAÒÒ”qqSUPER SAãã uqqSUSPEND AFôôqqSUSPEND SAýýqqTERM AFqqTERM SA2 qqTFRSEG AFPPqqTFRSEG SAYYqqTIMEINT AIzz WqqTRACER AF‹‹qqTRACER SA””UqqTRAP0 SA¥¥+nqqTRAP1 SAÖÖ<mqqTSKATTR AF  qqTSKATTR SA CqqTSKBORN AF ) )qqTSKBORN SA 2 2 qqTSKINFO AF [ [qq> ŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.PANEL.EQ*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.PANEL.EQŠLISTŠPAGE1SPURINTƒIDNTƒ5,1�68xxx�SPURIOUS�INTERRUPT�HANDLER*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�SPURINT‚1.00„**ˆ*’**ˆ*�HLD6ƒ09/30/80‚**ˆ**********************…SPURIOUS�INTERRUPT�ROUTINE*.*…REGISTER�USAGE:�D0�AND�A1�SAVED�AND�RESTORED*ŠSECTION�LEVEL00* ŠXDEFƒSPURINT ŠXREF.S�PANELŠXREF.S�SPURCNT‰PAGESPURINT:!ŠADD.W‚#1,SPURCNT‰INCREMENT�COUNT*ŠCMP.W‚#100,SPURCNT‡HAVE�100�OCCURRED�YET?ŠBMI.S‚SPURINT8‹BRANCH�IF�NO  **ˆToo�many�interrupts.,*ˆLet�user�know,�by�putting�A1�into�display.* ŠMOVE.L�A1,-(A7)‹SAVE�A1ŠMOVE.L�PANEL,A1‹PANEL�ADDRESS)ŠMOVE.W�#$15,FPLEDST(A1)ƒPUT�AX�IN�LIGHTS!ŠMOVE.W�#$35,FPLEDST(A1)ƒLATCH�IT)ŠMOVE.W�#$2E,FPLEDST(A1)ƒPUT�X1�IN�LIGHTS!ŠMOVE.W�#$3E,FPLEDST(A1)ƒLATCH�ITŠMOVE.L�(A7)+,A1‹RESTORE�A1ŠCLR.W‚SPURCNTŒRESET�COUNT  SPURINT8:ŠRTEŠENDééé¸7=/*=/*†M68XXX.STDTIM.AF=/*+=/* Chain file to assemble M68XXX.STDTIM.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.STDTIM.LS=/*=/IFC \1ƒ=ARG�M68XXX.STDTIM.LS=/ENDIF=/*0=ASM M68XXX.STDTIM.SA,M68XXX.STDTIM.RO,\1;RZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDééééé> éÁŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGE2STDTIM„IDNTƒ5,1�68xxx�DIRECTIVE--SET�DATE�AND�TIME*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡****************************#*‡*‚S�T�D�T�I�M�*ƒSET�DATE�AND�TIME*‡*‚REV�1.00‚HLD6�11/12/79�**‡*‚REV�3.00‚HLD6�11/06/81�**‡*****************************;*†THIS�ROUTINE�SETS�DATE�AND�TIME�TO�VALUES�GIVEN�BY�CALLER***‹ENTRY:�A6�HAS�ADDR�OF�TCB *’A4�HAS�PARAMETER�BLOCK�ADDRESS *”0(A4)�-�ORDINAL�DATE�(4�BYTES)*”4(A4)�-�TIME�(MILLISECONDS)**‹EXIT�:�D0�HAS�RETURN�CODE*’D0=�0…GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE1*ŠRTCDALOW�-�9ƒUSER�TASK�CANNOT�SET�DATE�AND�TIME**ŠSECTION�LEVEL04* ŠXDEFƒSTDTIM0ŠXDEFƒSCHED_DATEUP‡Referenced�from�M68XXX.RMS.SA ŠXREF.S�DATEŠXREF.S�MIDNIGHT ŠXREF.S�NSEŠXREF.S�TIME_LEFT ŠXREFƒKILLER ŠXREFƒSBRQPA‰PAGE:STDTIM„BTSTƒ#TSKASYST,TCBATTR(A6)�Is�caller�a�system�task?ŠIF��THEN.S,�EXITƒRTCDALOW‹Error�-�caller�not�a�sys�taskŠENDI 4ŠMOVE.W�SR,-(A7)‹Save�for�unmasking�interrupts�later  *.* Cancel the DATE periodic activation routine.* !ŠMOVE.W�#1<<15,D1ŠIndicate�cancel1ŠMOVE.L�#PATDATEID,D2†ID�of�node�I�wish�to�cancelŠBSR„SBRQPA�Cancel�itŠNOP—Provide�for�PC+2�return =ŠMOVEM.L�(A4)+,D3-D4‡D3�=�ordinal�date,�D4�=�ms�past�midnight8ŠMOVE.L�#24*60*60*1000,D7‚24�hours�worth�of�milliseconds $ŠWHILE.L�D4��D7�DO.Sƒ�=�0�SUB.L‚D7,D4‹Bias�so�ms�past�midnight�<�24�hours$�ADD.L‚#1,D3‹Bump�date�for�each�biasŠENDW  * * Formulas:!*ƒABSOLUTE_TIME�=�NSE�-�TIME_LEFTÊYÓ<(*ƒTIME_OF_DAYƒ=�ABSOLUTE_TIME�-�MIDNIGHTE*ƒMidnight�correction�(DELTA)�=�CURRENT_TIME_OF_DAY�-�NEW_TIME_OF_DAYC*…adding�DELTA�to�MIDNIGHT�will�make�our�NEW_ABSOLUTE_TIME�correct. 7* Compute DELTA = CURRENT_TIME_OF_DAY - NEW_TIME_OF_DAY* ŠDISABLE_INTERRUPTSˆMaskŠMOVE.L�D3,DATEŒUpdate�DATEŠMOVE.L�NSE,D3.ŠSUB.L‚TIME_LEFT,D3‡D3�=�current�absolute�time>ŠSUB.L‚MIDNIGHT,D3ˆD3�=�current�time�of�day�(ms�past�midnight) 4ŠSUB.L‚D4,D3ŽSubtract�desired�new�time�of�day�to�...*£...�give�us�DELTA9ŠADD.L‚D3,MIDNIGHTˆAdjust�MIDNIGHT�so�abs�time�is�correct)ŠBCLRƒ#31,MIDNIGHT‡Insure�positive�number 7ŠBSR.S‚SCHED_DATEUP‡Now�go�schedule�date�bumper�routine .ŠMOVE.W�(A7)+,SR‹Unmask�and�lose�SR�from�stack!ŠEXITƒSUB�exit�(subroutine�exit);  *<* Now reschedule the date update routine to fire at midnight%*ƒDelay�time�from�now�to�midnight�is:**‰(MIDNIGHT�+�24hrs�of�ms)�-�ABSOLUTE_TIME* SCHED_DATEUP:ŠMOVE.L�MIDNIGHT,D1 ŠSUB.L‚NSE,D12ŠADD.L‚TIME_LEFT,D1‡Time�delay�for�next�activation;ŠADD.L‚#24*60*60*1000,D1‚Add�24�hours�worth�of�milliseconds#ŠBCLRƒ#31,D1�Insure�positive�number ŠMOVE.L�D1,A1.ŠCLR.LƒD1�Options�=�new,�one-shot,�int�level�0ŠMOVE.L�#PATDATEID,D2†ID%ŠLEA„DATEUP(PC),A0†Address�of�routine ŠBSR? „SBRQPA ŠBRA.S‚*+61ŠBSR„KILLER�Crash�on�illegal�instruction�if�errorŠRTS  J*�This�is�the�routine�that�gets�scheduled�to�update�the�date.‚It�runs�from2*ƒexec�request�periodic�activation�every�24�hours.*DATEUP: 0ŠMOVE.W�SR,-(A7)‹Save�to�unmask�interrupts�later#ŠDISABLE_INTERRUPTSˆMask�interrupts'ŠADD.L‚#1,DATEŒUpdate�DATE�and�MIDNIGHTŠADD.L‚#24*60*60*1000,MIDNIGHTŠBSR„SCHED_DATEUP.ŠMOVE.W�(A7)+,SR‹Unmask�and�lose�SR�from�stack*ŠRTE—Return�to�background�routine�that�...*£...�scheduled�me�(TIMEINT)ŠEND‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.ENV.EQ*ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.PANEL.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.ENV.EQ‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.PANEL.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE‰IFEQ…CHIPTYPE-68000:SUPER„IDNT…5,1‚M68000�DIRECTIVE--SWITCH�TO�SUPERVISOR�MODE‰ENDC‰IFEQ…CHIPTYPE-68010:SUPER„IDNT…5,0‚M68010�DIRECTIVE--SWITCH�TO�SUPERVISOR�MODE‰ENDC*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ******************** *ˆ*�SUPERŒ**ˆ*’**ˆ*�7616„01/10/80�*)*ˆ*�7616„12/06/80�*�ADD�PRIVILEDGE�CHECKS*ˆ**********************ˆGIVE�SUPERVISOR�MODE�TO�TASK* ‰SECTION�LEVEL04* ‰XDEF„SUPER *‰XREF.S‚EXCSTACK†GET�USER'S�RETURN�ADDRESS%‰XREF.S‚PANEL‰CHECK�FOR�ENABLED�PANEL2‰XREF.S‚RUNNERˆRESTORE�A6�UPON�RETURN�TO�USER�MODE ‰XREF†LOADMMU‰PAGE**ˆVERIFY�SUPER�PASSWORD* SUPER:!‰MOVE.L„TCBA0(A6),D0ˆGET�PASSWORD‰CMP.L…#1269464059,D0†CHECK�IT1‰EXIT.NEƒRTCDDIRNŒif�bad,�then�return�(error_01);  **ˆOK�IF�USER�0* "‰TST.W…TCBUSER(A6)‰IS�THIS�USER�0?‰BEQ.S…SUPER_01ŒPROCEED�IF�YES  *+*ˆIF�NOT�USER�0,�THEN�PANEL�MUST�BE�ENABLED* )‰MOVE.L„PANEL,A0ŒGET�FRONT�PANEL�ADDRESS.&‰BTST†#1,FPDMPTST+1(A0)ƒSEE�IF�ENABLED$‰EXIT.NEƒRTCDDIRNŒreturn�(error_01);  *#*ˆCHECK�TO�SEE�IF�DIRECTIVE�ADDRESS*ˆWITHIN�USER'S�ADDRESS�SPACE.* SUPER_01:&‰MOVE.L„EXCSTACK,A0‰TOP�OF�SUPER�STACK *6*ˆNote:‚Under�4.4�we�have�a�"pseudo-vor"�on�the�bottom*�of�the�stack�for�a�68000.* $*ˆSUB.L…#VORLNGTH,A0ˆCORRECT�FOR�VOR-‰SUB.L…#2,A0�CORRECT�FOR�VOR�(OR�PSEUDO-VOR). '‰MOVE.L„-(A0),D6ŒLOGICAL�RETURN�ADDRESS$‰MOVE.L„#6,D5�2�BYTES�PLUS�PRE-FETCH6‰TR0.LOGPHY�…GET�PHYSICAL�RETURN�ADDRESS‰BRA.S…SUPER_02ŒGOOD‰NOP›BAD!‰EXIT†RTCDDIRNŒreturn�(error_01);  **ˆGRANT�SUPER�ACCESS.* SUPER_02:$‰MOVE.L„D6,A5�PHYSICAL�ADDRESS�IN�A5Ûhä5‰MOVEM.LƒTCBD0(A6),D0-D7/A0-A4�RESTORE�MOST�REGISTERS ‰JSR�(A5)  **ˆRETURN�FROM�SUPER�MODE* ‰MOVE.L„RUNNER,A6‹Restore�A6.8‰MOVE.L„TCBTST(A6),A5‡Get�TST�address,�and�load�the�MMU.+‰BSR‡LOADMMU�(in�case�he�changed�anything).‰EXIT†SUB‘exit�(subroutine); ‰ENDéé? éééé=/*=/*†M68XXX.SUSPEND.AF=/*,=/* Chain file to assemble M68XXX.SUSPEND.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.SUSPEND.LS=/*=/IFC \1ƒ=ARG�M68XXX.SUSPEND.LS=/ENDIF=/*3=ASM M68XXX.SUSPEND.SA,M68XXX.SUSPEND.RO,\1;MRZ=050=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*}=/*=ENDééééééì‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰LIST‰PAGE)SUSPEND‚IDNTƒ5,1…68xxx�DIRECTIVE--SUSPEND*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*,*ˆTASK�IS�SUSPENDED�UNTIL�RESUMED�BY�ANOTHER$*�ENTRY:‚A6�HAS�ADDRESS�OF�SUSPENDEE*‰SECTION�LEVEL04* ‰XDEF†SUSPEND*SUSPEND:1‰BSET†#TSKSSUSP,TCBSTATE(A6)ˆSet�suspended�state;&‰EXIT†POSTEMPT–Exit�(postempt�client);‰END@ éééééõ=/*=/*†M68XXX.TERM.AF=/*)=/* Chain file to assemble M68XXX.TERM.SA=/*:=/* If no output argument is specified for the listing the-=/* chain file will default to M68XXX.TERM.LS=/*=/IFC \1ƒ=ARG�M68XXX.TERM.LS=/ENDIF=/*-=ASM M68XXX.TERM.SA,M68XXX.TERM.RO,\1;MRZ=065=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.TIOT.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.PAT.EQ=/*ƒ9995.&.INTERRUP.MC=/*}=/*=ENDééééééþŠPAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.TIOT.EQ*ˆINCLUDEƒ9995.&.BAB.EQ*ˆINCLUDEƒ9995.&.PAT.EQ*ˆINCLUDEƒ9995.&.INTERRUP.MC*@ ŠNOLISTŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.TST.EQŠINCLUDE�9995.&.TIOT.EQŠINCLUDE�9995.&.BAB.EQŠINCLUDE�9995.&.PAT.EQŠINCLUDE�9995.&.INTERRUP.MCŠLISTŠPAGEETERM†IDNTƒ5,1„68xxx�DIRECTIVES--TERMINATE�SELF,�TERMINATE�TASK,�ABORT*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*…TERMT�--‚REV�3.00ƒ11/06/81„(HLD6)*�REV�2.00„2/08/81„(HLD6)*�REV�1.01„9/10/79„(HLD6)*‹--‚TRAP�1�ROUTINE**5*…PURPOSE:‚TERMT�-�TERMINATION�OF�ONE�TASK�BY�ANOTHER**…ENTRY:‚A6�HAS�REQUESTOR'S�TCB*�A4�HAS�TERMT�PARAMETER�BLOCK*“0(A4)�-�TASK�NAME*“4(A4)�-�SESSION*“8(A4)�-�ABORT�CODE�(2�BYTES)**…EXIT�:‚D0�HAS�RETURN�CODE*�D0�=�0�GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST2*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�TERM�IN�PROCESS(*ŠRTCDALOW�-�9ƒUSER�CANNOT�TERM�SYS�TASK*ŠSECTION�LEVEL04* ŠXDEFƒTERMT*‰PAGE%TERMT…TST.L‚(A4)�IS�TASK�NAME�=�ZERO?ŠBNE.S‚TERMT4�BRANCH�IF�NO  **ŠSELECT�A�TASK�TO�TERMINATE* -ŠMOVE.L�4(A4),D1‹CHECK�SESSION�IN�PARAM�BLOCKŠBEQ.S‚TERMT1AŒBRANCH�IF�ZERO 4ŠBTSTƒ#TSKASYST,TCBATTR(A6)�IS�CALLER�A�SYSTEM�TASK?ŠBNE.S‚TERMT1BŒBRANCH�IF�NO ( 0X8g@1ŠBSETƒ#TSK2TRMP,TCBSTAT2(A5)�IS�TASK�TERMINATING?.ŠBEQ.S‚TERMT9�BRANCH�IF�NO�-�FOUND�ONE�TO�TERM 0TERMT3„MOVE.L�TCBALL(A5),A5†GET�ADDR�OF�NEXT�TCB%ŠBRA.S‚TERMT2�BRANCH�BACK�TO�CHECK�IT  *(*‡LOOK�FOR�TASK�NAMED�IN�PARAMETER�BLOCK* #TERMT4„TR0.GETTCB�(A4)‹LOOK�FOR�TCBŠBRA.S‚TERMT6�BRANCH�IF�FOUND  **…NO�TASK�FOUND�-�RETURN�ERROR* ,TERMT5„CLR.L‚TCBA0(A6)ŠNO�TASK�NAME�RETURNEDŠEXITƒRTCDTASK‹ERROR�-�NO�TASK  **‡CHECK�FOR�LEGAL�REQUEST* 5TERMT6„MOVE.L�A0,A5ŽTCB�ADDRESS�OF�TASK�TO�BE�STOPPEDŠCMP.L‚A5,A6ŽIS�TASK�=�CALLER?$ŠBEQ.S‚TERMT7�BRANCH�IF�YES�-�ERROR. 4ŠBTSTƒ#TSKASYST,TCBATTR(A5)�IS�TARGET�A�SYSTEM�TASK?ŠBEQ.S‚TERMT8�BRANCH�IF�NO 4ŠBTSTƒ#TSKASYST,TCBATTR(A6)�IS�CALLER�A�SYSTEM�TASK?ŠBNE.S‚TERMT8�BRANCH�IF�YES. %TERMT7„EXITƒRTCDALOW‹EXIT�(ERROR_09); ?TERMT8„BSETƒ#TSK2TRMP,TCBSTAT2(A5)�IS�TASK�ALREADY�TERMINATING?)ŠEXIT.NE�RTCDDPRQŠEXIT�IF�YES�(ERROR_06);  *2*†SAVE�ABORT�CODE,�STATE�WORD�AND�RETURN�TASK�NAME* %TERMT9„MOVE.W�8(A4),D0‹GET�ABORT�CODE(ŠBEQ.S‚TERMT9AŒDO�NOT�SET�HI�BIT�ON�ZERO ŠBSETƒ#HIBIT,D0ŠSET�BIT�155TERMT9AƒBSETƒ#TSKIABRT,TCBATTI(A5)�SET�TASK�ABORT�BIT*ŠMOVE.W�D0,TCBABORT(A5)„SAVE�IN�TARGET�TCB<ŠMOVE.W�TCBSTATE(A5),TCBSTATE+2(A5)�SAVE�STATE�WORD�FOR�DUMP8ŠMOVE.L�TCBNAME(A5),TCBA0(A6)�RETURN�TASK�NAME�TO�CALLER>ŠMOVE.L�TCBNAME(A6),TCBATSK(A5)�GIVE�CALLER'S�TASK�NAME�TO�TGT2ŠMOVE.L�TCBSESSN(A6),TCBASES(A5)�GIVE�SESSION�ALSO  **„CLEAR�WAIT�FOR�EXMON5*„IF�TASK�WAITING�ON�SEMAPHORE‚--‚REMOVE�IT�FROM�LIST* 1ŠBCLRƒ#TSKSWTEM,TCBSTATE(A5)�CLEAR�EXMON�WAIT�BIT0ŠBCLRƒ#TSK2RTEX,TCBSTAT2(A5)�RTN�TO�EXEC�CLEARED?TERMTT0ƒBCLRƒ#TSKSSMWT,TCBSTATE(A5)�CLEAR�AND�TEST�SEM-WAIT�BIT$ŠBEQ.S‚TERMTT5ŒBRANCH�IF�NOT�WAITING *ŠMOVE.L�TCBXA0(A5),A0†POINTER�TO�SEMAPHORE-ŠMOVE.W�SR,-(A7)‹Save�current�interrupt�level&ŠDISABLE_INTERRUPTSˆINHIBIT�INTERRUPTS1TERMTT1ƒTAS„(A0)�TEST�AND�SET�MULTIPROCESSOR�FLAG"ŠBMI.S‚TERMTT1ŒLOOP�IF�ALREADY�SET A "ŠLEA„2-TCBSEM(A0),A1„FIRST�POINTER*TERMTT2ƒTST.L‚TCBSEM(A1)‰DOES�ENTRY�EXIST?#ŠBEQ.S‚TERMTT4ŒNO�-�SEARCH�FINISHED +ŠCMP.L‚TCBSEM(A1),A5†HAVE�WE�FOUND�A�MATCH?ŠBEQ.S‚TERMTT3ŒBRANCH�IF�YES ŠMOVE.L�TCBSEM(A1),A1†NEXT�ENTRY+ŠBRA.S‚TERMTT2ŒLOOP�BACK�TO�CONTINUE�SEARCH 6TERMTT3ƒMOVE.L�TCBSEM(A5),TCBSEM(A1)�UNLINK�FROM�CHAIN(ŠADD.W‚#1,(A0)ŒINCREMENT�SEMAPHORE�COUNT2TERMTT4ƒBCLRƒ#HIBIT,(A0)ˆCLEAR�MULTIPROCESSOR�FLAG(ŠMOVE.W�(A7)+,SR‹RESTORE�STATUS�REGISTER  *1*ˆCLEAR�WAIT�STATES�(EXCEPT�WAIT�FOR�ACKNOWLEDGE)* @CLRMSK„EQU„$FFFF-1<�to�periodic�activation�table�header*ŠLEA„PATHDR(A1),A2†A2�-->�head�of�PAT�list ŠMOVE.L�A2,A3;ŠMOVE.W�SR,-(A7)‹Save�old�status�for�unmask�operation�later#ŠDISABLE_INTERRUPTSˆMask�interrupts5ŠMOVE.L�PATNEXT(A3),D0…D0�-->�first�PAT�entry�on�list  I* Walk thru PAT list keeping A2 pointing to entry under consideration andJ*ƒA3�pointing�to�previous�entry.‚Remove�any�entries�from�the�PAT�list�that(*ƒbelong�to�the�task�we�are�terminating. ŠWHILE��DO.S'�MOVE.L�D0,A2ŽA2�-->�next�entry�on�list�IF.L�PATTCB(A2)��A4�THEN.S(�BSR„PAT_DEL_NODE‚Go�delete�the�PAT�node�ELSE.S �MOVE.L�A2,A3�ENDI7�MOVE.L�PATNEXT(A3),D0‚Advance�to�next�node�on�the�listŠENDWA -ŠCLR.L‚TCBDLAY(A4)ˆClear�delay�pointer�in�TCB #ŠMOVE.W�(A7)+,SRŒUnmask�interrupts.  **&*†CLEAR�USER�INTERRUPTS�IF�ANY�CLAIMED* ééééééé/ŠBTSTƒ#TSKIUVCT,TCBATTI(A4)�DOES�TASK�HAVE�ISR?ŠBEQ.S‚TERMNWDŒBRANCH�IF�NO ŠTR0.DIOVX  *?*ˆIf�this�task�Network�Services�attachment,�put�in�disconnect�Q* NATNXDCƒEQU„4’Disconnect�Q�linkNATTCB„EQU„8’TCB�Address @TERMNWDƒMOVE.L�TCBNAU(A4),D0†Is�task�a�Network�Addressable�Unit?ŠBEQ.S‚TERMC0�Branch�if�NO )ŠMOVE.L�D0,A0ŽNetwork�Address�Table�Entry#ŠCLR.L‚NATTCB(A0)‰Clear�TCB�address1ŠMOVE.L�NWDQHD,NATNXDC(A0)�Link�into�disconnect�QŠMOVE.L�A0,NWDQHDŠUpdate�Q�head  **…IS�THIS�LAST�TASK�IN�SESSION?0*…IF�THIS�TASK�IS�EXMON�-�LOOK�FOR�WAITING�TASKS* 7TERMC0„MOVE.L�TCBNAME(A4),D3…SAVE�TASK�NAME�FOR�COMPARE0ŠMOVE.L�TCBSESSN(A4),D4„SAVE�SESSION�FOR�COMPARE5ŠBSETƒ#TSKILAST,TCBATTI(A4)�SET�'LAST�IN�SESSION'�BITŠIFNEƒMULTPROC �TR0.P‚SEMTCBŠENDC!ŠMOVE.L�TCBHD,A1‹1ST�TCB�IN�CHAIN7TERMC1„BTSTƒ#TSK2TRMP,TCBSTAT2(A1)�IS�TASK�TERMINATING?*ŠBNE.S‚TERMC4�BRANCH�IF�YES�-�DO�NOT�COUNT 'ŠCMP.L‚TCBSESSN(A1),D4„COMPARE�SESSIONSŠBNE.S‚TERMC2�NOT�SAME�SESSION 7ŠBCLRƒ#TSKILAST,TCBATTI(A4)�CLEAR�'LAST�IN�SESSION'�BIT?TERMC2„BTSTƒ#TSKIEXMT,TCBATTI(A4)�IS�TERMINATING�TASK�AN�EXMON?ŠBEQ.S‚TERMC4�BRANCH�IF�NO ;ŠBTSTƒ#TSKSWTEM,TCBSTATE(A1)�IS�THIS�TASK�WAITING�FOR�EXMONŠBEQ.S‚TERMC4�BRANCH�IF�NO /ŠCMP.L‚TCBEXM(A1),D3†EXMON�WITH�THIS�TASK�NAME?ŠBNE.S‚TERMC4�BRANCH�IF�NO 0ŠCMP.L‚TCBEXMS(A1),D4…IS�EXMON�SESSION�THE�SAME?ŠBNE.S‚TERMC4�BRANCH�IF�NO /ŠMOVE.W�#T1EXMON,D7ˆUSE�DIRECTIVE�AS�ABORT�CODEŠTR0.EXABRT�(A1)‹ABORT�TASK  -TERMC4„MOVE.L�TCBALL(A1),A1†NEXT�TCB�IN�CHAIN ŠMOVE.L�A1,D0 ŠBNE„TERMC1 ŠIFNEƒMULTPROC �TR0.V‚SEMTCBŠENDC  *"*„DETACH�FROM�EXMON�--�IF�ATTACHED* 5ŠBTSTƒ#TSKIEXM,TCBATTI(A4)�IS�TASK�ATTACHED�TO�EXMON?ŠBEQ.S‚TERMA8�BRANCH�IF�NO $ŠTR0.DMONX�.�DETACH�AND�SEND�MESSAGEŠNOP—.ŠIGNORE�ERROR�RETURN  *)*…IF�SERVER�--�DEALLOCATE�SERVER�FUNCTION* TERMA8„EQU„* ŠTR0.DSRVX * *†DEALLOCATE�ALL�USER�SEMAPHORES* B 5ŠBTSTƒ#TSKIUSEM,TCBATTI(A4)�ARE�THERE�ANY�SEMAPHORES?ŠBEQ.S‚TERMS1�NO ŠTR0.DSEMXŠPAGE**…SEND�MESSAGE�TO�TRAP�SERVERS* TERMS1„MOVE.L�#1,D7+TERMS3„LEA„TIAT,A1ŒADDR�OF�ASSIGNMENT�TABLE ŠLEA„TIOT,A2ŒADDR�OF�OWNER�TABLEŠMOVE.L�D7,D1ŽTRAP�NUMBERŠMULUƒ#TIOTEL,D1‰OFFSET�TO�TIOT"ŠCMP.B‚#2,0(A1,D7)ˆIS�IT�ASSIGNED?ŠBNE.S‚TERMS8�NO 9ŠBTSTƒ#TIOTSTRM,TIOTSTAT(A2,D1)�DOES�SERVER�WANT�MESSAGE?ŠBEQ.S‚TERMS8�BRANCH�IF�NO ŠMOVE.L�D7,-(A7)#ŠTR0.EXEQDQ�.ŽGO�TO�MESSAGE�ROUTINEŠMOVE.L�(A7)+,D7ŠBTSTƒ#TSKSAKWT,TCBSTATE(A4) ŠBEQ.S‚TERMS8 ŠTR0.PAUSE TERMS8„ADD.L‚#1,D7 ŠCMP.L‚#15,D7*ŠBLE„TERMS3�BRANCH�BACK�TO�CKECK�NEXT�TRAP  **‡DEALLOCATE�ASQ* ŠTR0.DASQX  * *ƒDEALLOCATE�ALL�MEMORY�SEGMENTS* ŠTR0.DSEGX  **…SEND�MESSAGE�TO�MONITOR*  ŠTST.L‚TCBMON(A4)ŠBEQ.S‚TERME1�NO�MONITOR &ŠMOVE.W�#$1805,D2ŠMESG�LENGTH�AND�TYPEŠSWAPƒD2)ŠMOVE.W�TCBNAME(A4),D2…TASK�NAME�1ST�HALF;ŠMOVE.L�TCBNAME+2(A4),D3ƒTASK�NAME�2ND�HALF,�SESSN�1ST�HALF*ŠMOVE.W�TCBSESSN+2(A4),D4‚SESSION�2ND�HALFŠSWAPƒD4,ŠMOVE.W�TCBATSK(A4),D4…TASK�ATSK�-�REQUESTOR8ŠMOVE.L�TCBATSK+2(A4),D5ƒATSK�2ND�HALF,�SESSION�1ST�HALF)ŠMOVE.W�TCBASES+2(A4),D6ƒSESSION�2ND�HALFŠSWAPƒD6%ŠMOVE.W�#$0100,D6ŠEVENT�TYPE�-�1=TERM"ŠMOVE.L�TCBABORT(A4),D7„ABORT�CODE$ŠMOVE.W�TCBD0(A4),D7‡UPPER�1/2�OF�D0 -ŠBTSTƒ#TSKIABRT,TCBATTI(A4)�WAS�TASK�ABORTED?ŠBEQ.S‚TERMD2�BRANCH�IF�NO &ŠMOVE.W�#$0200,D6ŠEVENT�TYPE�-�2=ABORT'TERMD2„MOVE.L�A4,A2ŽSAVE�ADDRESS�OF�TCB.ŠTR0.QEVNTN�TCBMON(A4)…SEND�MESSAGE�TO�MONITORŠNOP—DON'T�CARE�IF�IT�FAILED$ŠMOVE.L�A2,A4ŽRESTORE�ADDRESS�OF�TCB  **†REMOVE�FROM�TCB�ALL�LIST* TERME1„EQU„*ŠIFNEƒMULTPROC1�TR0.P‚SEMTCB�GET�EXCLUSIVE�ACCESS�TO�TCBALL�LISTŠENDCŠLEA„TCBHD-TCBALL,A1 TERME2„MOVE.L�TCBALL(A1),D0 ŠBEQ.S‚TERME4 ŠCMP.L‚D0,A4ŽDO�WE�HAVE�A�MATCHŠBEQ.S‚TERME3�YES ŠMOVE.L�D0,A1 ŠBRA.S‚TERME2  5TERME3„MOVE.L�TCBALL(A4),TCBALL(A1)�REMOVE�FROM�CHAIN TERME4„EQU„*  *)*‰Delete�this�task's�Address�Space�Number* ŠBSR„DEASNŽDelete�ASNŠIFNEƒMULTPROC(�TR0.V‚SEMTCB�GIVE�UP�EXCL�ACCESS�TO�TCBŠENDC/ŠCLR.L‚RUNNER�CLEAR�RUNNER�-�TCB�WILL�DISAPPEAR  **…DEALLOCATE�TCB�AND�RETURN* TERMP1:ŠTR0.PGFR�(A4),#2ŠBRA.S‚TERMP2�GOOD�RETURN. .ŠSAVE_STATE‚L1_FULLŠPERFORM�A�FULL�STATE�SAVE.%ŠBSR„KILLER�BAD�RETURN�-�CALL�KILLER. TERMP2:#ŠEXITƒTERM’EXIT�-�TERMINATE�CALLER.ŠENDééééééB =/*=/*†M68XXX.TFRSEG.AF=/*+=/* Chain file to assemble M68XXX.TFRSEG.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.TFRSEG.LS=/*=/IFC \1ƒ=ARG�M68XXX.TFRSEG.LS=/ENDIF=/*1=ASM M68XXX.TFRSEG.SA,M68XXX.TFRSEG.RO,\1;MRZ=070=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.&.SEG.EQ=/*ƒ9995.&.GST.EQ=/*}=/*=ENDééééééH‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*ˆINCLUDEƒ9995.&.SEG.EQ*ˆINCLUDEƒ9995.&.GST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰INCLUDEƒ9995.&.SEG.EQ‰INCLUDEƒ9995.&.GST.EQ‰LIST‰PAGEATFRSEGƒIDNT„5,1‚68xxx�DIRECTIVE--TRANSFER�SEGMENT�TO�ANOTHER�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.*#*„TFRSEG‚--�REV�2.00ƒ4/24/79‚(HLD6)*š2/26/81‚(HLD6)*Œ--�TRAP�1�ROUTINE*1*…PURPOSE:‚TRANSFER�SEGMENT�FROM�CALLER�TO�TARGET*'*‰ENTRY:‚A6�HAS�REQUESTOR'S�TCB�ADDRESS(*‘A4�HAS�SEGMENT�PARAMETER�BLOCK�ADDRESS*•0�-�TARGET�TASK�NAME*•4�-�SESSION�CODE *•8�-�OPTIONS)*™BIT�15,�ATTRIBUTES�GIVEN�IN�PARAM�BLOCK+*™BIT�14,�LOGICAL�ADDR�GIVEN�IN�PARAM�BLOCK0*™BIT�13,�EXEC�SUPPLIES�LOGICAL�ADDR�(=PHYSICAL)*”10�-�SEGMENT�ATTRIBUTES*”12�-�SEGMENT�NAME*”16�-�LOGICAL�ADDRESS**ŠEXIT:ƒD0�HAS�RETURN�CODE*’D0�=�0‚GOOD�RETURN*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST9*ŠRTCDTFUL�-�5ƒTARGET�TST�IS�FULL�-�NO�ROOM�FOR�NEW�ENTRY5*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�TARGET�HAS�SEGMENT0*ŠRTCDNFND�-�7ƒSEGMENT�NOT�FOUND�IN�CALLER'S�TST=*ŠRTCDALOW�-�9ƒCALLER�CANNOT�GIVE�UP�SEG�-�A7�POINTS�INTO�SEG'*ŠRTCDLGCF�-11ƒLOGICAL�SEGMENT�CONFLICT*‹SECTION�LEVEL03* ‹XDEFƒTFRSEG ‹XREF.S�KILLER‹XREF.S�UNLDMMU‰PAGETFRSEG:*ŠMOVE.L�A5,A3†SAVE�TARGET�TASK�TCB�ADDRESS  *'*ˆGet�exclusive�access�to�caller's�tst.* ‰IFNEƒMULTPROC‰TR0.P‚TCBTSTSM(A6)‰ENDC '‰MOVE.L‚TCBTST(A6),A5ˆA5�=�CALLER'S�TST  **ˆFindC �segment�in�caller's�tst.* ‰TR0.FNDSEG‚(A5),SGPBNAME(A4)‰BRA.S‚TFRSEG3ƒFOUND�IT�--�GOOD TFRSEG4E:(‰EXITƒRTCDNFND�SEG�NAME�NOT�FOUND�IN�TST  *'*ˆCan�caller�have�segment�de-allocated?* TFRSEG3:Q]ZabGj'‰TST.LƒTCBASQ(A6)†DOES�CALLER�HAVE�ASQ?‰BEQ.SƒTFRSEG4‰BRANCH�IF�NO %‰MOVE.L„USP,A0‰GET�CALLER'S�A7�(USP). ‰MOVE.L„A0,D0‰LSR.Lƒ#8,D0ŒGET�PAGE�NUMBER&‰CMP.WƒTSTLB(A5,D5),D0‚IS�USP�<�BEGIN?‰BCS.SƒTFRSEG4ŠBRANCH�IF�YES %‰CMP.WƒTSTLE(A5,D5),D0ƒIS�USP�>�END�?,‰EXIT.LS�RTCDALOW‰ERROR�-�USP�WITHIN�SEGMENT  **ˆFind�target�task's�tcb.* TFRSEG4:+‰CMP.LƒA6,A3ˆARE�REQUESTOR�AND�TARGET�SAME?,‰EXIT.EQ�RTCDTASK‰BAD�TARGET�NAME--NOT�FOUND *%*ˆGet�exclusive�access�to�target�tst.* ‰IFNEƒMULTPROC‰TR0.P‚TCBTSTSM(A3)‰ENDC "‰MOVE.L‚D5,A1ˆCALLER'S�MMU�POINTER%‰MOVE.L‚A4,A2ˆPARAMETER�BLOCK�POINTER *!*ˆLook�for�target�segment�in�tst.* '‰TR0.FNDSEG�,SGPBNAME(A2)*‰BRA.SƒTFRSEG6E†FOUND�IT�--�INVALID�TARGET ‰TST.LƒD5”IS�THERE�ROOM�IN�TST?‰BNE.SƒTFRSEG6�BRANCH�IF�YES "‰EXIT„RTCDTFULŽERROR�-�TST�IS�FULL TFRSEG6E:+‰EXITƒRTCDDPRQ�ERROR�-�TARGET�HAS�SEG�NAMED  **ˆChekc�logical�address.* TFRSEG6:)‰MOVE.L‚A1,D5‘RESTORE�CALLER'S�MMU�OFFSET.‰MOVE.L‚SGPBLA(A2),D6‰LOG�ADDR�IN�PARAM�BLOCK?:‰BTST„#SGPBOLAD,SGPBOPT(A2)�IS�LOGICAL�ADDRESS�OPTION�SET?‰BNE.SƒTFRSEG7�YES�--�USE�IT ‰CLR.LƒD6-‰MOVE.W‚TSTLB(A5,D5),D6‡LOG�BEGIN�FROM�CALLER1‰BTST„#SGPBOPAD,SGPBOPT(A2)�IS�PHYS�ADDR�OPT�SET?‰BEQ.SƒTFRSEG6AŽBRANCH�IF�NO &‰ADD.WƒTSTPO(A5,D5),D6‡ADD�PHYS�OFFSET TFRSEG6A:!‰LSL.Lƒ#8,D6‘HAVE�LOGICAL�ADDRESS TFRSEG7: ‰CLR.LƒD0#‰MOVE.W‚TSTLE(A5,D5),D0‡LOGICAL�END*‰SUB.WƒTSTLB(A5,D5),D0‡MINUS�LOGICAL�BEGIN#‰MOVE.L‚D0,D2‘SAVE�DIFF�FOR�NEW�MMU‰ADD.Wƒ#1,D0‘+1�=�#PAGES ‰MOVE.L‚D0,D5‘MOVE�#�PAGES�TO�D5‰LSL.Lƒ#8,D5‘#BYTES ‰TR0.LOGPHY ‰BRA.SƒTFRSEG8EŽADDRESS�CONFLICT‰BRA.SƒTFRSEG8E #‰TST.LƒD5ˆWAS�AN�EMPTY�ENTRY�FOUND?‰BNE.SƒTFRSEG8ƒBRANCH�IF�YES ,‰BSR…KILLER„KILL�SYSTEM�IF�NO�-�CAN'T�HAPPEN TFRSEG8E:‰EXIT„RTCDLGCF TFRSEG8:0‰TST.BƒTSTCTL+1(A0,D5)„IS�THERE�A�MMIO�SEG�HERE?‰BNE„TFRSEG8E…BRANCH�IF�YES  **ˆAll�ok�-�transfer�segment.* ‰MOVE.L‚D6,D1�LOGICAL�ADDRESS‰MOVE.L‚A1,D4�CALLER'S�TST�MMU‰LSR.Lƒ#8,D1�NEW�LOGICAL�BEGIN‰ADD.WƒD1,D2�NEW�LOGICAL�END*‰MOVE.W‚D1,TSTLB(A0,D5)ƒSAVE�LOGICAL�BEGIN(‰MOVE.W‚D2,TSTLE(A0,D5)ƒSAVE�LOGICAL�END4‰SUB.WƒTSTLB(A5,D4),D1ƒOLD�LOG�BEGIN�-�NEW�LOG�BEGIN ‰NEG.WƒD1'‰ADD.WƒTSTPO(A5,D4),D1ƒ+OLD�PHYS�OFFSET)‰MOVE.W‚D1,TSTPO(A0,D5)ƒ=�NEW�PHYS�OFFSET1‰MOVE.L‚TSTANAME(A5,D4),TSTANAME(A0,D5)�MOVE�NAME6‰MOVE.W‚TSTAR1(A5,D4),TSTAR1(A0,D5)…MOVE�R1�AND�USECNT)‰MOVE.W‚TSTAATTR(A5,D4),D3„OLD�ATTRIBUTES/‰BTST„#SGPBOATR,SGPBOPT(A2)�IS�ATTR�OPTION�SET?+‰BEQ.SƒTFRSEG9�BRANCH�IF�NO�--�USE�OLD�ATTR %‰BCLR„#SEGAROM,D3‹CLEAR�READ�ONLY�BIT>‰BTST„#SEGAROM,SGPBATTR(A2)�IS�READ�ONLY�SET�IN�PB�ATTRIBUTES?‰BEQ.SƒTFRSEG9�BRANCH�IF�NO 3‰BSET„#SEGAROM,D3‹IF�YES�-�SET�IT�FOR�NEW�TST�ENTRY TFRSEG9:‰BSET„#SEGAUSED,D3ŠSET�USED�BIT*‰MOVE.W‚D3,TSTAATTR(A0,D5)„SAVE�ATTRIBUTES0‰MOVE.W‚#RAMCTL,TSTCTL(A0,D5)�SET�CONTROL�TO�RAM#‰BTST„#SEGAROM,D3‹SHOULD�IT�BE�ROM?‰BEQ.SƒTFRSEG9AŽBRANCH�IF�NO 0‰MOVE.W‚#ROMCTL,TSTCTL(A0,D5)�SET�CONTROL�TO�ROM **ˆRemove�segment�from�MMU.* TFRSEG9A:(‰CLR.WƒTSTCTL(A5,D4)‰INVALIDATE�SEGMENT. *‰EXG…D4,D5‘PUT�CALLER'S�SEG�OFFSET�INTO�D5$‰BSR…UNLDMMU�REMOVE�CALLER'S�SEGMENT‰EXG…D5,D4‘RESTORE�REGISTERS ‰CLR.LƒTSTANAME(A5,D4)‡*(‰CLR.LƒTSTAATTR(A5,D4)‡*�CLEAR�OLD�ENTRY ‰CLR.LƒTSTLB(A5,D4)Š*‰CLR.WƒTSTPO(A5,D4)Š* .‰SUB.Bƒ#1,TSTCSEGS(A5)†DECR�COUNT�IN�'OLD'�TST.‰ADD.Bƒ#1,TSTCSEGS(A0)†INCR�COUNT�IN�'NEW'�TST %‰MOVE.W‚TSTLB(A0,D5)C ,D1†LOGICAL�BEGIN&‰ADD.WƒTSTPO(A0,D5),D1†ADD�PHYS�OFFSET‰LSL.Lƒ#8,D1‘=�PHYSICAL�ADDRESS-‰MOVE.L‚D1,TCBA0(A6)‰GIVE�PHYS�ADDR�TO�CALLER  */*ˆLook�for�locally�shared�segment�-�change�gst.* ,ŠBTSTƒ#SEGASHR,D3…IS�SEGMENT�LOCALLY�SHARED?ŠBEQ.S‚TFRSEGX1ˆBRANCH�IF�NO ,ŠMOVE.L�TCBSESSN(A6),D2‚GET�CALLER'S�SESSION.ŠCMP.L‚TCBSESSN(A3),D2‚SAME�AS�TARGET�SESSION?ŠBEQ.S‚TFRSEGX1ˆBRANCH�IF�YES 'ŠMOVE.L�TSTANAME(A0,D5),A0‚SEGMENT�NAMEŠMOVE.L�D3,D1‹ATTRIBUTESŠMOVE.L�A3,A4‹SAVE�A3 ŠTR0.FNDGSGŠBRA.S‚TFRSEG12ˆBRANCH�IF�FOUND ŠBSR„KILLERŠNOT�FOUND�--�CRASH  TFRSEG12:ŠMOVE.L�A4,A3ŒRESTORE�A3&ŠMOVE.L�TCBSESSN(A3),D2‚TARGET�SESSION#ŠMOVE.L�D2,GSTSESSN(A0)‚SAVE�IN�GST  *7*ˆGive�up�exclusive�access�to�both�tst's�-�then�return.* TFRSEGX1:‰IFNE„MULTPROC‰TR0.VƒTCBTSTSM(A3)‰ENDC ‰IFNE„MULTPROC‰TR0.VƒTCBTSTSM(A6)‰ENDC!‰EXIT†SUB‘exit�(subroutine�exit);‰ENDéééééé‰PAGE********************** M68XXX.TIMEINT.SA **********************E* This file is appended to the device dependent source for all of theA*ƒTIMEINT�modules�during�the�assembly�process.‚It�contains�common4*ƒcode�for�timer�interrupt�functions�on�all�systems.*B*ƒThis�code�will�schedule�a�background�routine�to�fire�off�any�PAT*…nodes�whose�time�has�come. ŠIF��THEN.S3�MOVE.L�PATBEG,A1‡A1�contains�address�of�PAT�header:�LEA„PATBABT(A1),A0‚Address�of�background�activation�block�LEA„PATFIRE(PC),A13�MOVE.L�A1,BABPTR(A0)ƒAddress�of�background�routine�BSR„BKG_SCHEDULE„Schedule�itŠENDI ***†RESTORE�REGISTERS�AND�TRACE�IF�REQUESTED* ,ŠMOVEM.L�(A7)+,D0-D1/A0-A1�RESTORE�REGISTERS&ŠBTSTƒ#TRCFTIMR,TRACFLAG�TRACE�WANTED?ŠIF…�THEN.Sˆ�BSR„TRACER�CALL�TRACE�ROUTINE �DC.Wƒ$FF13ŠENDI  *G*‚Check�to�see�whether�this�tic�represents�the�end�of�the�timeslice�for*‚the�running�task,�and�exit.* 7ŠTST„TIMESLIC‹If�we're�supposed�to�be�doing�timeslicing9ŠIF…�THEN.SŠ(i.e.,�if�tics/timeslice�parameter�<>�0), .�SUB„#1,TIMEOUT‰decrement�the�timeout�counter.'�IF…�THEN.S�If�it�is�0�or�negative,9�ST…PREEMPT_FLAG„set�the�flag�that�will�cause�a�dispatch.�ENDIƒ* ŠENDIƒ* 3ŠEXITƒINTERRUPTŠEither�way,�exit�through�the�common*§interrupt�handler.‰PAGE*I* This is a background routine (scheduled when TIME_LEFT <= 0) that fires *ƒall�PAT�nodes�elibible�to�run.* PATFIRE:$ŠMOVE.L�PATBEG,A1ŠPAT�header�address*SRSTACKƒD SET„0’Offset�to�SR�before�on�stack#ŠDISABLE_INTERRUPTSˆMask�interruptsŠMOVE.L�TIME_LEFT,D2ŠWHILE��DO.S,�MOVE.L�PATHDR(A1),A2ƒPoint�A2�to�first�node*�BSRƒPAT_RM_1ST_NODE‚Remove�the�first�node%�ENABLE_INTERRUPTS†Unmask�interrupts..�TST.L‚PATTCB(A2)ƒIs�it�Exec�node?�0�means�yes �IF��THEN.S�MOVE.W�SR,D0ˆSR�before�masking�IFEQƒCHIPTYPE-68010%“MOVE.W�#$0084,-(A7)…Push�TRAP�#1�VOR�ENDCrF{�IFEQƒCHIPTYPE-68020%“MOVE.W�#$0084,-(A7)…Push�TRAP�#1�VOR�ENDC�BSR„CKEXPAŽGo�fire�exec�node �ELSE.S�BSR„CKDELAY�Go�fire�task�node�ENDI �ENABLE_INTERRUPTS$�MOVE.L„PATBEG,A1‹PAT�header�address�DISABLE_INTERRUPTS*�MOVE.L„PATHDR(A1),A2‡Look�at�new�1st�node�MOVE.L„TIME_LEFT,D2ŠENDW ŠENABLE_INTERRUPTS‰UnmaskŠRTS—Back�to�the�EXECéééééé=/*=/*†M68XXX.TRACER.AF=/*+=/* Chain file to assemble M68XXX.TRACER.SA=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to M68XXX.TRACER.LS=/*=/IFC \1ƒ=ARG�M68XXX.TRACER.LS=/ENDIF=/*0=ASM M68XXX.TRACER.SA,M68XXX.TRACER.RO,\1;MRZ=46=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TRACE.EQ=/*}=/*=ENDéééD éé郉PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TRACE.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TRACE.EQ‰LISTŠPAGE#TRACER„IDNT�1,0‚TRACE�EXEC�ACTIVITY*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆTRACERƒREV�1.0ƒ7-19-79„(C313)+*ˆSAVES�TRACE�CODE�-�SR�-�PC�-�A0�-�A6�-�D0$*ˆALL�REGISTERS�ARE�RESTORED�ON�EXIT*ˆCALL:‚JSR‚TRACER*�DC.W�X*ˆX�IS�TRACE�CODE�OF�CALLER*‹SECTION�LEVEL01*'‹XDEF‚TRACER„ENTRY--TRACE�EXEC�ACTIVITY‹XREF.S‚TRACEBEG‰PAGE0TRACERSPƒEQU‚20‡OFFSET�TO�ORIGINAL�STACK�POINTER /TRACER…MOVEM.L�D0-D1/A3-A5,-(A7)ƒSAVE�REGISTERS%‹MOVE.W‚SR,-(A7)†SAVE�STATUS�REGISTER*‹MOVE.L‚TRACEBEG,A3ƒADDRESS�OF�TRACE�TABLE"‹ORI.Wƒ#$700,SR‡INHIBIT�INTERRUPTS5‹MOVE.L‚TRCPTR(A3),A5ˆGET�CURRENT�TABLE�ENTRY�POINTER(‹CMP.LƒTRCLNG(A3),A5ƒSEE�IF�BEYOND�TABLE.‹BNE.S„TRACER1‡TABLE�FILLED-START�AT�TOP�AGAIN +‹LEA†TRCENTRS(A3),A5„ADDRESS�OF�FIRST�ENTRY .TRACER1„LEA†TRCENTSZ(A5),A4‡NEXT�ENTRY�POINTER‹MOVE.LƒA4,TRCPTR(A3)†SAVE�IT(‹MOVE.Wƒ(A7)+,SRŒRESTORE�INTERRUPT�LEVEL  **‰FILL�IN�ONE�ENTRY* &‹MOVE.L‚D0,TRCD0(A5)„USERS�D0�TO�TABLE&‹MOVE.L‚A0,TRCA0(A5)„USERS�A0�TO�TABLE ‹MOVE.L‚A6,TRCA6(A5)„A6�TO�TABLE9‹MOVE.L‚TRACERSP(A7),A4ƒGET�RETURN�ADDRESS-HAS�TRACE�CODE,‹MOVE.W‚(A4),TRCCODE(A5)‚TRACE�CODE�TO�TABLE,‹ADD.Lƒ#2,TRACERSP(A7)ƒUPDATE�RETURN�ADDRESS,‹MOVE.W‚TRACERSP+4(A7),TRCSR(A5)…SR�TO�TABLE,ˆMOVE.L‚TRACERSP+6(A7),TRCPC(A5)ƒPC�TO�TABLE3ˆCMP.W‚#$EFFF,TRCCODE(A5)ƒIS�THIS�AN�I/O�INT�ENTRY?ˆBHI.S‚TRACER4ŽBRANCH�IF�NO 8ˆMOVE.L�TRACERSP+12(A7),TRCA0(A5)ƒREPLACE�A0�WITH�2ND�PC  * *‡SAVE�TIME* TRACER4 TR0.RDTIM'ˆMOVE.L‚D1,TRCTIME(A5)‡SAVE�TIME�OF�DAY'ˆMOVE.W‚#249,D1ŒMAX�COUNT�FOR�LSB�TIMERˆSUB.BƒD0,D1ŽGET�ACTUAL�COUNTˆLSR.Wƒ#8,D0ŽMSB�OF�TIMERˆNOT.WƒD0‘COMPLEMENT�ITˆAND.Wƒ#3,D0ŽWANT�2�BITS ˆMULU„#250,D0ˆADD.WƒD0,D1ŽADD�MICROSECS*ˆMOVE.W‚D1,TRCTIM2(A5)…SAVE�IN�TRACE�ENTRY  **‡RETURN* ,ˆMOVEM.L‚(A7)+,D0-D1/A3-A5…RESTORE�REGISTERS ˆRTSœRETURNŒU•ˆENDééE ééééé‰IFEQ„CHIPTYPE-68000/TRAP0…IDNTƒ5,1‡68000�TRAP�#0�handler�and�table.‰ENDC‰IFEQ„CHIPTYPE-68010/TRAP0…IDNTƒ5,1‡68010�TRAP�#0�handler�and�table.‰ENDCO*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***H***…FILE:‚TRAP0�--�ALL�THE�STUFF�DEALING�WITH�THE�TRAP�#0�MECHANISM.ƒ******É***J***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000�family.***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***I***…FUNCTION:‚In�this�file�are�(1)�the�TRAP�#0�handler,�(2)�the�table‚***E***‡containing�offsets�to�the�TRAP�#0�routines,�and�(3)�a�TRAP�#0…***I***‡routine�which�returns�the�entry�point�address�for�a�given�TRAP�#0�******‡directive.¸******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------2*…09/10/84‚MSLŒRemoved�entries�for�subroutines�not(*ždocumented�in�"Guide�to�Writing�Device*žDrivers�for�Versados".*C*†8/12/83‚Steve�FranckƒRemoved�restriction�that�TRAP�#0�routines�be-*žin�low�32K�of�address�space,�and�changed�to**žword-wide,�position-independent�offsets..*žTRAP0�and�TABLE0�were�combined�at�this�time,"*žand�the�ENTRY�routine�was�added.*  **‚Included�files:*8*‰UTILITY.MC�Macros�of�general�utility�(e.g.�PUSH,�POP).2*‰ENV.EQ”Equates�dependent�on�processor�chip�type.2*‰STR.EQ”Equates�for�supervisor�code�under�RMS68K.*ŠNOLISTŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.ENV.EQŠINCLUDE�9995.&.STR.EQŠLIST  * *‚XDEF's.*2ŠXDEFƒHI_DIR_NUM‰Highest�TRAP�#0�directive�number.�:¦@®;¶O¾IÆ"0ŠXDEFƒTABLE0�Start�address�of�the�TRAP�#0�table.0ŠXDEFƒTRAP0ŽEntry�point�for�the�TRAP�#0�handler.  *6*‚XREF's.‚TABLE0's�routine�names�are�XREFed�in�TABLE0.*+ŠXREFƒKILLERT0‹Routine�to�crash�the�system.  ŠSECTION�LEVEL00ŠOPT„BRSŠPAGEO*v*****************************************************************************O**********************************************************************************É***1***…ROUTINE:‚TRAP0�--�CALL�A�TRAP�#0�ROUTINE.š******É***J***…FUNCTIONE :‚When�an�entity�running�in�supervisor�mode�but�not�linked�***D***‡with�RMS68K�wants�to�invoke�some�exec�function,�he�moves�the†***D***‡directive�number�of�the�function�into�D0�and�does�a�TRAP�#0.†***E***‡The�mpu�vectors�here�and�we�use�the�TRAP�#0�table,�TABLE0,�to…***#***‡JMP�to�the�desired�routine.§******É***8***…NOTES:‚TRAP�#0�calls�from�user�mode�are�ignored.“******É***E***…REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒAD‚.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒP ******É******…ENTRY�CONDITIONS:³***7***‡D0ƒ=�directive�#�of�the�routine�to�be�executed.‘***F***‡PC�&�SR�(&�maybe�VOR)�of�caller�are�stacked,�as�with�any�TRAP.„******É***O*******************************************************************************O*^*****************************************************************************‰PAGE***‚Ensure�we�weren't�called�from�user�mode.* TRAP0:9ŠBTSTƒ#5,(SP)ŒCheck�the�SR�on�the�stack�to�see�if�we�were)ŠIF…�THENŠin�supervisor�mode.‚If�not,,ŠRTE—just�return�to�whoever�did�the�TRAP�#0.ŠENDI–*  *K*‚Clean�up�the�stack�to�make�it�look�like�he�just�did�a�JSR�to�the�routine.* +ŠADDQ.L�#2,SPŽRemove�the�SR�from�the�stack.‰IFEQ„CHIPTYPE-680102ŠMOVE.W�2(SP),4(SP)ˆLower�half�of�PC�replaces�VOR.8ŠMOVE.W�(SP)+,(SP)‰Upper�half�of�PC�replaces�lower�half.‰ENDC  *5*‚Validate�the�directive�number�and�call�the�routine.* >ŠCMP.L‚#HI_DIR_NUM,D0…If�the�directive�number�is�out�of�range,ŠBHI.L‚KILLERT0‹call�KILLER.1ŠADD.L‚D0,D0ŽD0�<--�directive�#�*�2�for�use�as�an*§index�into�a�table�of�words.>ŠMOVEƒTABLE0(PC,D0.L),D0�D0�<--�offset�from�start�of�TABLE0�to*§the�routine�he�wants.5ŠJMP„TABLE0(PC,D0)†Jump�to�the�routine;�the�address�= *§*ƒbase�addr�of�TABLE0�+�offset*§*ƒfrom�TABLE0�to�the�routine.ŠPAGEO*v*****************************************************************************O**********************************************************************************É***G***…ROUTINE:‚ENTRY�--�GET�ENTRY�POINT�FOR�AN�EXEC�ROUTINE�(TRAP�#0)„******É***F***…FUNCTION:‚Returns�the�entry�point�address�for�an�exec�routine.…***B***‡Doing�a�JSR�to�the�returned�address�is�faster�than�doing�aˆ***A***‡TRAP�#0,�which�is�useful�for�drivers.‚It�can�also�be�usedˆ***=***‡to�validate�that�a�routine�with�such�a�number�exists.�******É***E***…REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒ.ƒAP‚.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒRƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒP ******É******…ENTRY�CONDITIONS:³***G***‡D1ƒ=�number�of�the�routine�for�which�the�entry�point�is�desired.******É***-***…EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:Ÿ******‡If�the�routine�exists:¬***;***‰A0ƒ=�entry�point�address�for�the�specified�routine.‹***2***‰Return�to�caller�at�the�PC�after�his�call.–***&***‡If�the�routine�does�not�exist:¤***6***‰Return�to�caller�at�the�PC�after�his�call�+�2.’******É***O*******************************************************************************O*^*****************************************************************************‰PAGE* *‚Save�regs.* ENTRY: ‰PUSH.L„D1’Save�the�caller's�D1;  ***‚Ensure�the�directive�number�is�in�range.* *‰CMP.L…#HI_DIR_NUM,D1†if�(D1�>�HI-DIR-NUM)$‰BHI.S…ENTRY_01Œthen�return�(error);  *2* It's in range, so calculate the routine address.* ,‰ADD.L…D1,D1�D1�<--�D1�*�len�(TABLE0_entry);>‰MOVE†TABLE0(PC,D1.L),D1‚D1�<--�offset�to�routine�from�TABLE0;=‰LEA‡TABLE0(PC,D1),A0„A0�<--�address�of�the�TRAP�#0�routine�=*­address�of�TABLE0�+*­offset�(routine�-�TABLE0);  *K* If the address = killer, then make sure that it is the legitimate killer.* If not, then return an error.* ‰CMP.L…#KILLER,A0Šif&‰BNE.S…ENTRY_02Œ(A0�=�addr�(killer))�& ,‰CMP.L…#2*T0KILLER,D1†(D1�<>�index�(killer))$‰BEQ.S…ENTRY_02Œthen�return�(error);  ** Here if we had an error. *†IncrF ement�return�address�by�2,*†and�fall�through�to�ENTRY_02.* ENTRY_01:1‰ADDQ.L„#2,4(SP)ŒPC�(return)�<==�PC�(return)�+�2;  ** Here for all exits.*†restore�regs, *†and�return. ENTRY_02:"‰POP.L…D1’Restore�the�caller's�D1.‰RTS›Return�to�the�caller.‰PAGEO**********************************************************************************É***G***…DATA�STRUCTURE:‚TABLE0�--�TABLE�OF�OFFSETS�TO�TRAP�#0�ROUTINES.„******É***F***…FUNCTION:‚This�table�is�used�to�calculate�addresses�of�TRAP�#0…***C***‡routines.‚There�is�an�entry�for�each�TRAP�#0�directive,�and†***E***‡they�are�in�order�by�directive�number.‚Each�entry�is�the�word„***D***‡displacement�from�the�beginning�of�this�table�to�the�TRAP�#0†***D***‡routine.‚This�technique�helps�make�RMS�position-independent.…******É***O******************************************************************************* *L*‚Use�the�SETUP�macro�to�define�table�entries.‚You�give�the�macro�the�equateN*‚for�the�directive�number�and�the�label�of�the�routine�you�want�to�go�to�when1*‚that�directive�is�called,�and�it�does�the�rest.*0*‚SETUP[.L]�,*I*‚Use�the�.L�if�the�routine�is�Local�to�this�module�rather�than�external.* SETUP…MACRODIR_NUMƒSET„(*-TABLE0)/2ŠIFEQƒDIR_NUM-\1ŒNOLISTŒIFNCƒ'\0','L'ŽXREFƒ\2ŒENDC ŒDC…\2-TABLE0ŒLISTŒMEXITŠENDCSHOULD_BE�SET„\10ŠFAILƒ499�This�directive�is�in�the�wrong�place!!ŠENDM  ŠOPT„MEX,NOCL  TABLE0: *§What�it�does(*§-------------------------------------- *ŠSETUP‚0,KILLERT0‰Unassigned;�call�KILLER. 0ŠSETUP‚T0P,PSEM‹P�operation�(wait)�on�semaphore. 2ŠSETUP‚T0V,VSEM‹V�operation�(signal)�on�semaphore. 0ŠSETUP‚T0READY,READY†Put�task�on�the�ready�list. :ŠSETUP‚T0PAGAL,PAGEALOCƒAllocate�pages�of�physical�memory. :ŠSETUP‚T0PGFR,PAGEFREE„Free�(return)�pages�of�phys�memory. <ŠSETUP‚T0GETTCB,GETTCB„Get�TCB�addr�given�taskname,�session. 3ŠSETUP‚T0FNDSEG,FNDTSEGƒFind�segment�name�in�a�TST. BŠSETUP‚T0LOGPHY,LOGPHY„Validate�logical�addr,�convert�to�physical. 1ŠSETUP‚T0FNDGSG,FNDGSEGƒFind�segment�name�in�GST. .*‰SETUP‚T0ASRINT,ASRINT„Interrupt�target�task.'ŠSETUP‚10,KILLERŠInterrupt�target�task. /ŠSETUP‚T0QEVNTN,EXQEVNTN‚Place�event�in�an�ASQ. ;ŠSETUP‚T0FNDSEM,FNDUSEMƒFind�entry�in�user�semaphore�table. 8ŠSETUP‚T0GTXTCB,GTXTCB„Get�TCB�using�session�provided�in =ŠSETUP‚T0PAUSE,PAUSE†Pause�while�waiting�for�I/O�to�complete. A*‰SETUP‚T0DSRVX,DSRVX†Deallocate�server�function�when�task�stops.ŠSETUP‚15,KILLER A*‰SETUP‚T0DSEMX,DSEMX†Deallocate�user�semaphores�when�task�stops.ŠSETUP‚16,KILLER 5*‰SETUP‚T0DASQX,DASQX†Deallocate�ASQ�when�task�stops.ŠSETUP‚17,KILLER A*‰SETUP‚T0DSEGX,DSEGX†Deallocate�memory�segments�when�task�stops.ŠSETUP‚18,KILLER ?*‰SETUP‚T0EXEQDQ,EXEQDQ„Send�message�to�server�when�task�stops.ŠSETUP‚19,KILLER )*§Detach�task�from�exception�monitor�when!*‰SETUP‚T0DMONX,DMONX†task�stops.ŠSETUP‚20,KILLER (*‰SETUP‚T0EXABRT,EXABRT„Abort�user�task.ŠSETUP‚21,KILLER &ŠSETUP‚T0WAKEUP,WAKEUPXƒWakeup�a�task. (*§Place�event�in�ASQ�while�NOT�servicing&ŠSETUP‚T0QEVNTT,EXQEVNTT‚an�interrupt. $*§Place�event�in�ASQ�while�servicing&ŠSETUP‚T0QEVNTI,EXQEVNTI‚an�interrupt. $*‰SETUP‚T0UPDATQ,UPDTASQƒUpdate�ASQ.ŠSETUP‚25,KILLER "*§Validate�ODD�logical�address�and,ŠSETUP‚T0LOGPHO,LOGPHYOƒconvert�to�physical. 3*‰SETUP‚T0PAGALL,PAGEALLE‚Allocate�pages�of�memory.ŠSETUP‚27,KILLER 7ŠSETUP‚T0RDTIM,RDTIMER„Get�time�of�day�in�milliseconds. '*§Disconnect�task�from�user�vector�when!*‰SETUP‚T0DIOVX,DIOVX†task�stops.ŠSETUP‚29,KILLER +*‰SETUP‚T0ADDPA,ADDPA†Add�entry�to�the�PAT.ŠSETUP‚30,KILLER 9ŠSETUP‚T0CRTCB,TCBCR†Create�a�TCB.‚(INIT�uses�this�call.)*‰SETUP‚31,KILLER *ŠSETUP‚T0KILLER,KILLERT0‚Crash�the�system. 6*‰SETUP‚T0FREEPA,FREEPA„Return�PAT�entry�to�free�list.ŠSETUP‚33,KILLER 1ŠSETUP‚T0RQPA,EXRQPA†Request�periodic�activation. =ŠSETUP.L�T0ENTF RY,ENTRY…Get�entry�point�for�a�trap�#0�routine. #*§Schedule�routine�for�execution�in'ŠSETUP‚T0SCHED,BKG_SCHEDULEƒbackground. <ŠSETUP‚T0GUARD,CALL_GUARDED‚Call�subroutine�in�guarded�mode.    DHI_DIR_NUM�EQU�(*-TABLE0)/2-1‡Highest�directive�#�for�TRAP�#0�calls.   ‰ENDéééé‰IFEQ„CHIPTYPE-68000/TRAP1„IDNTƒ5,1‡68000�TRAP�#0�handler�and�table.‰ENDC‰IFEQ„CHIPTYPE-68010/TRAP1„IDNTƒ5,1‡68010�TRAP�#0�handler�and�table.‰ENDCO*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***D***…FILE:‚TRAP1�--�EVERYTHING�DEALING�WITH�THE�TRAP�#1�MECHANISM‡******•FOR�REAL-TIME�TASKS. ******É***J***…ENVIRONMENT:‚Part�of�the�RMS68K�exec�for�the�Motorola�68000�family.***(***‡Copyright�1983�by�Motorola,�Inc.¢******É***#***…FUNCTION:‚In�this�file�are:¨***4***�1.)‚the�TRAP�#1�handler�for�real-time�tasks,Œ***=***�2.)‚the�TRAP�#1�table�for�real-time�tasks�containing:ƒ***"***•A.)‚offsets�to�directives,™***%***•B.)‚offsets�to�exit�routines.–******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------&*†7/27/84‚Mark�Lanus…Original�writing.*  **‚Included�files:*8*‰UTILITY.MC�Macros�of�general�utility�(e.g.�PUSH,�POP).2*‰ENV.EQ”Equates�dependent�on�processor�chip�type.2*‰STR.EQ”Equates�for�supervisor�code�under�RMS68K.(*‰TCB.EQ”Equates�for�task�control�block.**‰UDR.EQ”Equates�for�user�directive�table.1*‰TR1RTCD.EQ�Return�codes�for�TRAP�#1�directives.**ŠNOLISTŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.ENV.EQŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.UDR.EQŠINCLUDE�9995.&.TR1RTCD.EQŠLIST  * *ˆxdef's.* 0‰XDEF†TRAP1�Entry�point�for�the�TRAP�#1�handler. /‰XDEF†TTB_01ŽBeginning�and�ending�addresses�for‰XDEF†TTE_01Žtrust�table�entry.  * *ˆxref's.ÎC×QßXçRïJ÷Mÿk .* ‰XREF†CKEXMON ‰XREF†ISRRTE ‰XREF†TRACER ‰XREF.S„RUNNER‰XREF.S„TRACFLAG‰XREF.S„UDRBEG ‰SECTIONƒLEVEL00 ‰OPT‡MEX,NOCL‰PAGEO*v*****************************************************************************O********************G **************************************************************É***1***…ROUTINE:‚TRAP1�--�CALL�A�TRAP�#1�ROUTINE.š******É******…FUNCTION:»***D***‡When�a�task�wants�to�invoke�some�exec�function,�he�moves�the†***D***‡directive�number�of�the�function�into�D0�and�does�a�TRAP�#1.†***B***‡The�mpu�vectors�here�and�we�use�the�TRAP�#1�table,�TABLE1,ˆ***&***‡to�JMP�to�the�desired�routine.¤******É******É***E***…REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆ.�******‡A:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ. ******É******…ENTRY�CONDITIONS:³***7***‡D0ƒ=�directive�#�of�the�routine�to�be�executed.‘***8***‡A0ƒ=�parameter�block�(if�required�by�directive).�***F***‡PC�&�SR�(&�maybe�VOR)�of�caller�are�stacked,�as�with�any�TRAP.„******É***O*******************************************************************************O*^*****************************************************************************‰PAGE**ˆif&*ˆ(interrupt_mask�(super_stack)�>�0)�|,*ˆ(supervisor_state_bit�(super_stack)�=�set)*ˆthen�go�to�isrrte;* TRAP1:‰TESTIM3‰BNE.S…ISR_RTE�Branch�if�not�from�normal�user�mode.  *1*ˆforce�the�condition�codes�on�the�stack�to�,+*ˆand�perform�a�level_1�partial�state�save;* =‰MOVE.B„#EQ_CC,COND_CODE(A7)…save�cond�code�of��on�stack. ‰SAVE_STATEŠL1_PART  *"*ˆif�(requestor�<>�real-time�task)*ˆthen�go�to�not_rt_task;* ‰BTSTW…#TSKARTIM,TCBATTR(A6)‰BEQ.S…NOT_RT_TASK  */*ˆmultiply�D0�by�4;�/*‚Get�index�into�table1‡*/ *ˆif�(D0�<�0)7*ˆthen�go�to�user_dir;Š/*‚User�configured�directive.‚*/* ‰ASL.W…#2,D0‰BMI.S…USER_DIR  *$*ˆif�(D0�>�biggest�directive�number)*ˆthen�exit�(bad�directive);* ‰CMP.W…#HI_T1_NUM*4,D0‰BHI.S…BAD_DIR  * *ˆA4�<==�addr�(parameter�block);.*ˆD2�<==�(option_bits)�&�(offset�(directive)); *ˆif�(target_tcb_required�=�set)*ˆthen�get�(target_tcb);#*ˆgo�to�directive�pointed�to�by�D0;* ‰MOVE.L„A0,A4‰MOVE.L„TABLE1(PC,D0.W),D2 ‰IF‚‚THEN.S‰GET_TARGET_TCB‰ENDI ‰JMP‡TABLE1(PC,D2.W)‰PAGE*:*ˆHere�are�some�branch�instructions.‚The�purpose�in�having=*ˆthis�branch�to�branch�architecture,�was�to�make�the�trap�#1>*ˆhandler�for�real-time�tasks�as�fast�as�possible,�even�though<*ˆthis�architecture�would�slow�down�the�trap�#1�handling�for*ˆnon�real-time�tasks.*=*ˆThe�priorities�on�handling�trap�#1�requests�are�as�follows:**�1.)‚real-time�tasks,*�2.)‚non�real-time�tasks,!*�3.)‚user�configured�directives.  *1*ˆUser�executed�a�trap�#1�while�executing�an�ISR.* ISR_RTE: ‰BRA.L…ISRRTE  *&*ˆClient�task�is�not�a�real-time�task.* NOT_RT_TASK:‰BRA.L…TRAP1_10  ***ˆTrap�is�for�a�user�configured�directive.* USER_DIR:‰BRA.L…TRAPUSR  *(*ˆTrap�contained�a�bad�directive�number:* BAD_DIR:$‰EXIT†RTCDDIRNŒexit�(bad�directive);‰PAGE@*****************************************************************"*ˆENTRY�CONDITIONS�FOR�DIRECTIVES:*+*�A4�<==�parameter�address�(if�applicable);!*�A6�<==�client�task�tcb�address;*?***************************************************************‰PAGEO*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***I***…FUNCTION:‚In�this�file�is�the�#TRAP�#1�table�containing�one�entry‚***<***�for�every�TRAP�#1�directive.‚Each�entry�contains�the„******�following�fields:¨******É***.***•1.)‚byte�describing�directive�options:�***%***šA.)‚parameter�block�required:‘*** ***šB.)‚target�tcb�required:–******É***5***•2.)‚byte�describing�length�of�parameter�block†******š(if�required):¡******É***5***•3.)‚word�containing�offset�to�directive�code:†******É***O******************************************************G *************************O*******************************************************************************O*^*****************************************************************************‰PAGE*:*ˆThe�SETUP1�macro�is�used�for�defining�entries�in�TABLE1.?*ˆInputs�to�this�macro�are�the�equate�for�the�directive�number,>*ˆand�the�lable�of�the�routine�which�processes�that�directive.<*ˆSETUP1�will�generate�a�16�bit�offset,�from�the�begining�of*ˆTABLE1,�to�the�directive.* * *ˆexample:*A*ˆSETUP1‚,,,,* TT‡EQU‡%10000000PB‡EQU‡%01000000T1TRGTSK�EQU‡31T1PARBLK�EQU‡30 SETUP1ƒMACRODIR_NUM‚SET‡(*-TABLE1)/4‰IFNE†DIR_NUM-\1SHOULD_BE‚SET…\10‹FAIL„499‘This�directive�is�in�the�wrong�place!!‹MEXIT‰ENDC‰IFC‡'\5','TT'‹DC.B„TT+PB�get�(pb�&�tt);‹DC.B„\4’len�(pb);‹NOLIST ‹XREF.S‚\2‹LIST#‹DC.W„\2-TABLE1‹offset�(directive);‹MEXIT‰ENDC‰IFC‡'\3','PB'‹DC.B„PB’get�(pb);‹DC.B„\4’len�(pb);‹NOLIST ‹XREF.S‚\2‹LIST#‹DC.W„\2-TABLE1‹offset�(directive);‹MEXIT‰ENDC‰DC.B†%00000000‹get�();‰DC.B†0“len�(pb)�=�0;‰NOLIST ‰XREF.S„\2‰LIST#‰DC.W†\2-TABLE1‹offset�(directive);ˆENDM  ‰PAGETABLE1:2‡SETUP1ƒT10,ERROR_01�Error�-�bad�directive�number. 4‡SETUP1ƒT1GTSEG,SEGALOC,PB,24,TTƒAllocate�a�segment. 6‡SETUP1ƒT1DESEG,SEGDEAL,PB,24,TTƒDeallocate�a�segment. 3‡SETUP1ƒT1TRSEG,TFRSEG,PB,24,TT„Transfer�a�segment. <‡SETUP1ƒT1ATTSEG,ATTSEG,PB,24†Attach�to�a�shareable�segment. >‡SETUP1ƒT1SHRSEG,SEGSHAR,PB,24,TT‚Grant�shared�segment�access. ;‡SETUP1ƒT1MOVELL,MOVELL,PB,28,TTƒMove�from�logical�address. ;‡SETUP1ƒT1DCLSHR,DCLSHAR,PB,24…Declare�a�segment�shareable. 5‡SETUP1ƒT1SNAPTRAC,SNAPTRACˆMove�trace�table�to�user. :‡SETUP1ƒT1RCVSA,RCVSA,PB,28,TT…Receive�segment�attributes. /‡SETUP1ƒT1GTTID,GTTASKID,PB,08…Get�TCB�address. '‡SETUP1ƒT1CRTCB,CRTCB,PB,28ˆCreate�TCB. 0‡SETUP1ƒT1GTTNAME,GTTNAME,PB,08,TT�Get�taskname. *‡SETUP1ƒT1START,TSKSTART,PB,10…Start�task. (‡SETUP1ƒT1ABORT,ABORTŽAbort�task�(self). *‡SETUP1ƒT1TERM,TERM�Terminate�task�(self). 6‡SETUP1ƒT1TERMT,TERMT,PB,10ˆTerminate�task�(not�self). -‡SETUP1ƒT1SUSPND,SUSPEND‹Suspend�task�(self). 7‡SETUP1ƒT1RESUME,RESUME,PB,08,TTƒResume�suspended�task. )‡SETUP1ƒT1WAIT,TSKWAIT�Block�task�(self). 7‡SETUP1ƒT1WAKEUP,WAKEUP,PB,08,TTƒWakeup�a�waiting�task. #‡SETUP1ƒT1DELAY,DELAYŽDelay�(self). -‡SETUP1ƒT1RELINQ,RELINQŒRelinquish�execution. :‡SETUP1ƒT1TSKATTR,TSKATTR,PB,08,TT�Return�task�attributes. 6‡SETUP1ƒT1SETPRI,SETPRI,PB,09,TTƒSet�current�priority. -‡SETUP1ƒT1STOP,STOPT,PB,08‰Stop�running�task. 6‡SETUP1ƒT1EXPVCT,EXPVCT,PB,36†Claim�exception�vectors. 1‡SETUP1ƒT1TRPVCT,TRPVCT,PB,56†Claim�trap�vectors. =‡SETUP1ƒT1TSKINFO,TSKINFO,PB,14,TT�Move�task's�TCB�to�caller. =‡SETUP1ƒT1RQSTPA,RQSTPA,PB,26,TTƒRequest�periodic�activation. /‡SETUP1ƒT1DELAYW,DELAYWŒDelay�with�wait�option. 1‡SETUP1ƒT1GTASQ,ASQALOC,PB,22,TTƒAllocate�an�ASQ. *‡SETUP1ƒT1DEASQ,ASQFREEŒDeallocate�an�ASQ. )‡SETUP1ƒT1SETASQ,ASQSTATSŠSet�ASQ�status. -‡SETUP1ƒT1RDEVNT,ASQREAD‹Read�event�from�ASQ. 5‡SETUP1ƒT1QEVNT,ASQEVENT,PB,18,TT‚Queue�event�to�ASQ. (‡SETUP1ƒT1WTEVNT,WTEVENT‹Wait�for�event. +‡SETUP1ƒT1RTEVNT,RTEVENT‹Return�from�event. ,‡SETUP1ƒT1GTEVNT,GTEVENT‹Get�event�from�ASQ. ,‡SETUP1ƒT139,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT140,ERROR_01ŽError�-�bad�directive. 0‡SETUP1ƒT1ATSEM,ATSEM,PB,10ˆAttach�to�semaphore. .‡SETUP1ƒT1WTSEM,WTSEM,PB,10ˆWait�on�semaphore. -‡SETUP1ƒT1SGSEM,SGSEM,PB,10ˆSignal�semaphore. 2‡SETUP1ƒT1DESEM,DESEM,PB,10ˆDetach�from�semaphore. -‡SETUP1ƒT1CRSEM,CRSEM,PB,10ˆCreate�semaphore. <‡SETUP1ƒT1DESEMA,DESEMAŒDetach�all�semaphores�for�this�task. ,‡SETUP1ƒT147,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT148,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT149,ERROR_01ŽError�-�bad�diH rective. ,‡SETUP1ƒT150,ERROR_01ŽError�-�bad�directive. =‡SETUP1ƒT1SERVER,SERVER,PB,06†Establish�server�for�user�task. 4‡SETUP1ƒT1DSERVE,DSERVEŒDetach�from�server�function. 7‡SETUP1ƒT1DERQST,DERQSTŒSet�user/server�request�status. <‡SETUP1ƒT1AKRQST,AKRQST,PB,20,TTƒAcknowledge�server�request. ,‡SETUP1ƒT155,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT156,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT157,ERROR_01ŽError�-�bad�directive. 2‡SETUP1ƒT1CDIR,CDIR,PB,08ŠConfigure�user�directiv. )‡SETUP1ƒT159,SUPER‘Enter�supervisor�mode. "‡SETUP1ƒT1CMR,CMR’Channel�request. 4‡SETUP1ƒT1CISR,CISR,PB,20,TT‡Claim�interrupt�vector. 6‡SETUP1ƒT1SINT,SINT,PB,04ŠSimulate�user�I/O�interrupt. ,‡SETUP1ƒT163,ERROR_01ŽError�-�bad�directive. ;‡SETUP1ƒT1EXMON,EXMON,PB,16,TT…Attach�to�exception�monitor. >‡SETUP1ƒT1DEXMON,DEMON,PB,16,TT„Detach�from�exception�monitor. <‡SETUP1ƒT1EXMMSK,EXMMSK,PB,12,TTƒSet�exception�monitor�mask. 6‡SETUP1ƒT1RSTATE,RSTATE,PB,12,TTƒReceive�task's�state. 2‡SETUP1ƒT1PSTATE,PSTATE,PB,12,TTƒSet�task's�state. B‡SETUP1ƒT1REXMON,REXMON,PB,12,TTƒExecute�task�under�exmon�control. ,‡SETUP1ƒT170,ERROR_01ŽError�-�bad�directive. ,‡SETUP1ƒT171,ERROR_01ŽError�-�bad�directive. 9‡SETUP1ƒT1MOVEPL,MOVEPL,PB,28†Move�from�physical�address. 0‡SETUP1ƒT1STDTIM,STDTIM,PB,08†Set�date�and�time. 0‡SETUP1ƒT1GTDTIM,GTDTIM,PB,08†Get�date�and�time. )‡SETUP1ƒT1FLUSHC,FLUSHCŒFlush�user�cache.  >HI_T1_NUM�EQU�(*-TABLE1)/4-1�Highest�TRAP�#1�directive�number. ‰PAGE*3*ˆThis�is�the�routine�which�processes�trap�#1�calls*ˆfrom�non�real-time�tasks.* *"*ˆTrace�this�trap�#1,�if�required.* TRAP1_10:-‰BTST†#TRCFTRP1,TRACFLAGŒDo�we�want�to�trace?‰BEQ.S…TRAP1_20–Branch�if�no. !‰BSR‡TRACER˜Trace�this�directive. ‰DC.W†$FF15 *'*ˆSend�a�message�to�EXMON,�if�requried.* TRAP1_20:0‰BTST†#TSKIEXM,TCBATTI(A6)ŠDoes�task�have�EXMON?‰BEQ.S…TRAP1_30–Branch�if�no. 3‰MOVE.L„TCBEMMSK(A6),D1�Move�mask�to�data�register.(‰BTST†#TEMTRAP1,D1’Is�TRAP�#1�monitored?‰BEQ.S…TRAP1_30–Branch�if�no. %‰MOVE.L„#1,D7™Pass�TRAP�#�to�CKEXMON.&‰BSR‡CKEXMON—Go�send�message�to�EXMON.  */*ˆmultiply�D0�by�4;�/*‚Get�index�into�table1‡*/ *ˆif�(D0�<�0)7*ˆthen�go�to�trap_usr;Š/*‚User�configured�directive.‚*/* TRAP1_30: ‰ASL.W…#2,D0‰BMI.S…TRAPUSR  *$*ˆif�(D0�>�biggest�directive�number)*ˆthen�exit�(bad�directive);* ‰CMP.W…#HI_T1_NUM*4,D0‰BHI.S…TRAP1BAD  *.*ˆGet�address�of�parameter�block,�if�required.* ‰LEA‡TABLE1(PC),A3‰MOVE.L„(A3,D0.W),D2‰BTST†#T1PARBLK,D2‰BEQ.S…TRAP1_GO ‰MOVE.L„D2,D5‰SWAP†D5‰AND.L…#$FF,D5-‰MOVE.L„A0,D6�LOGICAL�PARAMETER�BLOCK�ADDRESS‰TR0.LOGPHY‚&‰BRA.S…TRAP1_40ŒBRANCH�IF�GOOD�ADDRESS ‰NOP›BAD�ADDRESS&‰EXIT†RTCDPBLKŒBAD�ADDRESS�RETURN�CODE  TRAP1_40:.‰MOVE.L„D6,A4�PARAMETER�PHYSICAL�ADDRESS�TO�A4  *&*ˆGet�target�TCB�address,�if�required.* $‰BTST†#T1TRGTSK,D2ˆNEED�TARGET�TASK?‰BEQ.S…TRAP1_GOŒBRANCH�IF�NO ‰TR0.GETTCB‚(A4)‰BRA.S…TRAP1_50ŒBRANCH�IF�FOUND‰EXIT†RTCDTASKŒBAD�TARGET�TASK TRAP1_50:&‰MOVE.L„A0,A5�TARGET�TCB�ADDRESS�TO�A5 **ˆNow�go�to�directive�code.* TRAP1_GO: ‰JMP‡(A3,D2)   *'*ˆHere�is�another�branch�from�a�branch,$*ˆemployed�for�performance�purposes.* TRAP1BAD:‰EXIT†RTCDDIRN‰PAGETRAPUSR:&‰MOVE.L„UDRBEG,A2‹USER�DIRECTIVE�TABLE‰MOVE.L„A2,D2�DOES�TABLE�EXIST?‰BEQ.S…TRAP1BADŒBRANCH�IF�NO ,‰ASR.W…#2,D0�GET�UNMODIFIED�DIRECTIVE�NUMBER.‰NEG.W…D0’CHANGE�DIRECTIVE�#�TO�POSITIVE�VALUE2‰CMP.W…UDRCNT(A2),D0‡IS�VALUE�WITHIN�TABLE�LIMITS?&‰BGT.S…TRAP1BADŒBRANCH�IF�NOT�IN�TABLE ‰SUB.W…#1,D0�ENTRY�NUMBER‰MULU†#UDRESIZ,D0‰*�ENTRY�SIZE(‰LEA‡UDRENTRY(A2,D0),A2‚POINTER�TO�ENTRY!‰TST.L…UDRADDR(A2)‰ADDRESS�EXIST?‰BEQ.S…TRAP1BADŒBRANCH�IF�NO .‰MOVE.W„UDROPT(A2),D2‡GET�OPTION�&�EXIT�INDEX.)‰BCLR†#4,D2�THIS�TRAP�FOR�1�SESSION�ONLY?‰BNE.S…TRAPUSR1ŒBRH ANCH�IF�NO "‰MOVE.L„UDRSESS(A2),D1†GET�SESSION'‰CMP.L…TCBSESSN(A6),D1…DOES�IT�COMPARE?‰BNE.S…TRAP1BADŒBRANCH�IF�NO TRAPUSR1:(‰MOVE.L„(A7),TCBA6(A6)†MOVE�A6�INTO�TCB.%‰CLR.W…TCBRTCD(A6)‰CLEAR�RETRUN�CODE.(‰MOVE.W„D2,-(A7)ŒPUT�EXIT�INDEX�ON�STACK ‰IFEQ†CHIPTYPE-680101‰MOVE.W„#$84,-(A7)ŠSIMULATE�TRAP1�ON�M68010�STACK‰ENDC )‰PEAˆTRAP1XIT(PC)‡RETURN�ADDRESS�TO�STACK‰MOVE.W…SR,-(A7)‹SR�TO�STACK $‰MOVE.L„UDRADDR(A2),A2†ENTRY�ADDRESS ‰JMP‡(A2)  **ˆRETURN�FROM�DIRECTIVE* TRAP1XIT:'‰MOVE.W„TCBRTCD(A6),D0†Get�return�code.*‰EXIT.NEƒERROR�Exit�if�error�in�directive. ‰MOVE.W„(A7)+,D0ŒGet�exit�index.5‰EXIT.EQƒSUB‘If�(index�=�0)�then�take�subroutine�exit ‰IF.W†D0��#2�THEN.S4‰TR0.READY�(A6)�If�(index�=�2)�then�make�task�ready.‰ENDI 2‰EXIT†POSTEMPTŒIn�either�case,�take�postempt�exit.‰ENDééé=/*=/*†M68XXX.TSKATTR.AF=/*,=/* Chain file to assemble M68XXX.TSKATTR.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.TSKATTR.LS=/*=/IFC \1ƒ=ARG�M68XXX.TSKATTR.LS=/ENDIF=/*3=ASM M68XXX.TSKATTR.SA,M68XXX.TSKATTR.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééééé I ‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‰PAGE9TSKATTR‚IDNTƒ5,1‰68xxx�DIRECTIVE--RECEIVE�TASK�ATTRIBUTES*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*********************‡*‚T�S�K�A�T�T�R‚*ƒRETURN�TASK�ATTRIBUTES*‡*‚REV�1.00ƒHLD6**‡*‚06/29/79‡**‡********************3*†THIS�ROUTINE�RETURNS�TASK�ATTRIBUTES�TO�REQUESTOR***‹ENTRY:�A6�HAS�ADDR�OF�TCB*’A5�HAS�ADDR�OF�TARGET�TASK *’A4�HAS�PARAMETER�BLOCK�ADDRESS*—0�-�TASK�NAME*—4�-�SESSION�CODE**‹EXIT�:�D0�HAS�RETURN�CODE&*’D0�=�0„GOOD�RETURN,�ATTRIBUTES�IN�A0*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST$*ŠRTCDSTAT�-10ƒTASK�HAS�PENDING�STOP*)*’A0�HAS�ATTRIBUTES�FROM�TCB�IN�BITS�0-15*™USERID�IN�BITS�16-31***‰SECTION�LEVEL04* ‰XDEF†TSKATTR‰PAGE**ˆReturn�attributes.* TSKATTR:0ŠMOVE.L‚TCBUSER(A5),TCBA0(A6)„RETURN�USER�NUMBERŠMOVE.W‚TCBATTR(A5),TCBA0+2(A6)  **ˆCheck�stop�pending�bit:* 9‰BTST„#TSK2TRMP,TCBSTAT2(A5)Šif�(task�is�not�terminating))‰EXIT.EQƒSUB›then�exit�(subroutine�exit);&‰EXIT†RTCDSTAT–else�return�(error_10);‰ENDéé D=/*=/*†M68XXX.TSKBORN.AF=/*,=/* Chain file to assemble M68XXX.TSKBORN.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.TSKBORN.LS=/*=/IFC \1ƒ=ARG�M68XXX.TSKBORN.LS=/ENDIF=/*3=ASM M68XXX.TSKBORN.SA,M68XXX.TSKBORN.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*}=/*=ENDéééééI é !‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰LIST‰PAGE1TSKBORN‚IDNTƒ5,1…68xxx�DIRECTIVE--CREATE�NEW�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�TSKBORN…2.00�**ˆ*’**ˆ*�GGC3�03/21/79„**ˆ*�7616�05/24/79„**ˆ*�HLD6�03/02/81„**ˆ**********************ˆCREATE�AND�LINK�A�NEW�TCB*9*†ENTRY:‚A6ƒREQUESTOR'S�TCB�ADDRESS�(MUST�BE�SYSTEM�TASK)"*ŽA4ƒPARAMETER�BLOCK�IN�USER�SPACE*�(A4)‚NEW�TASK�NAME*Œ4(A4)‚SESSION�CODE*Œ8(A4)‚W‚DIRECTIVE�OPTION*‹10(A4)‚MONITOR*‹14(A4)‚SESSION�CODE%*‹18(A4)‚W‚CURRENT�AND�LIMIT�PRIORITY*‹20(A4)‚ATTRIBUTES*‹22(A4)‚ENTRY�POINT*‹26(A4)‚W‚USER�NUMBER*0*„EXIT:‚SUCCESS�D0=0‚NEW�TCB�CREATED/INITIALIZED*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE*ŠRTCDTFUL�-�5ƒASN�TABLE�FULL6*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�TASK�ALREADY�EXISTS)*ŠRTCDNMEM�-�8ƒMEMORY�SPACE�NOT�AVAILABLE* *”01234567*‚USES�REGISTERS‚D�********’A�*****‰SECTION�LEVEL04* ‰XDEF†ASGNMON ‰XDEF†CRTCB ‰XDEF†TCBCR ‰XREF.S„SEMTCB ‰XREF.S„TCBHD‰XREF.S„TDEFTYP ‰XREF†CRASN‰PAGE*'*ˆTrap�#0�entry�--�used�by�initializer.**‡A3�=�ADDRESS�OF�MINI-TCB/*‡D4�=�PRIORITIES/ATTRIBUTES‡D5�=�ENTRY�ADDRESS)*‡D6�=�USER�NUMBER‘D7�=�DIRECTIVE�OPTIONS* TCBCR:&‰LEA‡-2(A3),A4‹POINTER�TO�MONITOR�TASK%‰MOVE.W„#$8001,D3‹CALLER'S�ATTRIBUTES ,‰BSR.S…CRTCB_SUB‹Call�create_tcb�subroutine.‰RTS›Good�return. $‰ADD.L…#2,(A7)�Error�-�signal�error,‰RTS›and�return.‰PAGE*&*ˆTrap�#1�entry�--�used�by�directives.* 0CRTCB„MOVE.L„A4,A3�BOTH�POINT�TO�PARAMETER�BLOCK2‰MOVEM.Lƒ18(A4),D4-D6ˆMOVE�PARAMETERS�TO�REGISTERS"‰SWAP†D6’PUT�USER�NUM�IN�LOWER�1/2"‰MOVE.W„8(A4),D7ŒDIRECTIVE�OPTIONS *] 3^ ;T Cd K *‰MOVE.W„TCBATTR(A6),D3†CALLER'S�ATTRIBUTES#‰CLR.B…D3’CLEAR�INTERNAL�ATTRIBUTES ,‰BSR.S…CRTCB_SUB‹Call�create_tcb�subroutine.‰BRA.S…CRTCB_GOODŠGood�return. ,‰EXIT†ERROR�Error�-�go�to�error�return,�with*¦error�code�in�D0.W. CRTCB_GOOD:'‰EXIT†SUB‘Good�return�-�return�to�user.‰PAGE* *ˆCheck�for�duplicate�task�name.* CRTCB_SUB:‰TR0.GETTCB„(A3)6‰BRA.S…CRTCB_01ŒRETURNS�HERE�IF�IT�IS�ALREADY�IN�TABLE5‰BRA.S…CRTCB_02ŒRETURNS�HERE�IF�NOT�IN�LIST-OK,�GO�ON* CRTCB_01:%‰MOVE.L„#RTCDDPRQ,D0ˆSave�error�code,‰ADD.L…#2,(A7)�signal�error,‰RTS›and�return.  *3*ˆAllocate�two�pages�of�memory�for�new�tcb�and�tst.* CRTCB_02:‰CLR.L…D0’CLEAR�FOR�SHORT�LOAD*‰MOVE.B„TDEFTYP,D0ŠGET�DEFAULT�MEMORY�TYPE‰SWAP†D0’PUT�TYPE�IN�UPPER�1/2!‰MOVE.W„#2,D0�GET�2�PAGES�FOR�TCB‰TR0.PAGAL�D0’REQUEST�MEMORY"‰BRA.S…CRTCB_03ŒRETURNS�HERE�IF�OK 9‰MOVE.L„#RTCDNMEM,D0ˆNot�enough�memory�-�save�error�code,‰ADD.L…#2,(A7)�signal�error,‰RTS›and�return.  **ˆClear�tcb�and�tst�areas.* CRTCB_03:&‰MOVE.L„A0,A5�Hold�address�of�new�tcb.2‰MOVE.W„#$200/4-1,D2ˆNumber�of�longwords�to�clear. CRTCB_04: ‰CLR.L…(A0)+�Clear�one�longword.#‰DBRA†D2,CRTCB_04‰Branch�till�done.  **ˆInitialize�the�newJ �tcb.* (‰MOVE.L„(A3),TCBNAME(A5)„Save�task�name.)‰MOVE.L„4(A3),D0ŒSession�from�parameters. $‰BTST†#0,D3�Was�this�a�trap�#0�call?‰BNE.S…CRTCB_07ŒBranch�if�yes. +‰BTST†#TSKASYST,D3ˆIs�client�a�system�task?8‰BEQ.S…CRTCB_05ŒIf�not,�use�client's�session�and�user�#. ‰TST.L…D0’Is�session�=�0?)‰BNE.S…CRTCB_07ŒIf�not�zero,�then�use�it..‰BRA.S…CRTCB_06ŒIf�zero,�use�client's�session. CRTCB_05:+‰MOVE.W„TCBUSER(A6),D6†CALLER'S�USER�NUMBER CRTCB_06:(‰MOVE.L„TCBSESSN(A6),D0…CALLER'S�SESSION CRTCB_07:'‰MOVE.W„D6,TCBUSER(A5)†SAVE�USER�NUMBER&‰MOVE.L„D0,TCBSESSN(A5)…SESSION�TO�TCB  *#*ˆAssign�a�monitor�to�the�new�task.* ‰BSR„ASGNMON  **ˆSet�task's�attributes.* 6TCLRATTR�EQU„$FFFF-1<�MAX‰BLS.S…CRTCB_12ŒBRANCH�IF�NO CRTCB_11:)‰MOVE.B„TCBLPRI(A6),D4†USE�CALLER'S�LIMIT CRTCB_12:(‰MOVE.B„D4,TCBLPRI(A5)†SAVE�MAX�PRIORITY$‰CMP.B…D4,D0�IS�CURR�PRIORITY�>�MAX?‰BLS.S…CRTCB_13ŒBRANCH�IF�NO "‰MOVE.B„D4,D0�USE�LIMIT�AS�CURRENT CRTCB_13:,‰MOVE.B„D0,TCBCPRI(A5)†SAVE�CURRENT�PRIORITY/‰MOVE.B„D0,TCBRPRI(A5)†SAVE�READY�LIST�PRIORITY  **ˆInitialize�constants.* *‰MOVE.L„#'!TCB',(A5)ˆEye�catcher�for�dump.7‰MOVE.B„#$80,TCBSTATE(A5)ƒSet�initial�state�to�dormant.:‰MOVE.W„#1,TCBASQSM(A5)…Initialize�semaphore�count�to�one.  * *ˆInitialize�task�segment�table.* 2‰MOVE.W„#1,TCBTSTSM(A5)�SEMAPHORE�WAITER�CODE=NONE$‰MOVE.L„A5,A2™COMPUTE�ADDRESS�OF�TST‰ADD.L…#TSTBEGIN,A2’FOLLOWS�TCB$‰MOVE.L„A2,TCBTST(A5)‘POINTER�IN�TCB(‰MOVE.L„#'!TST',TST(A2)�DUMP�EYE�CATCHER1‰MOVE.B„#SEGMENTS,TSTNSEGS(A2)ˆNUMBER�OF�SEGMENTS2‰MOVE.W„#TSTMMU+24,TSTLMMU(A2)ˆPOINT�TO�MMU�IN�USE+‰MOVE.W„#TSTATTR+24,TSTLATTR(A2)†ATTRIBUTES  *#*ˆGet�exclusive�access�to�tcb�list.* ‰IFNEƒMULTPROC ‰TR0.P‚SEMTCB‰ENDC  *0*ˆSearch�'tcb-all'�list�for�duplicate�task�name.* ‰MOVE.L„TCBHD,A0 ‰MOVE.L„TCBNAME(A5),D0†TASK�NAME‰MOVE.L„TCBSESSN(A5),D1…SESSION CRTCB_20:)‰CMP.L…#0,A0�IS�THIS�END�OF�TCB-ALL�LIST?3‰BEQ.S…CRTCB_40ŒIf�yes�--�Good.�No�conflict.�Go�on. +‰CMP.L…TCBNAME(A0),D0†DOES�TASK�NAME�MATCH?‰BNE.S…CRTCB_21ŒBRANCH�IF�NO ,‰CMP.L…TCBSESSN(A0),D1…IS�SESSION�SAME�ALSO?)‰BEQ.S…CRTCB_30ŒBRANCH�IF�YES�-�DUPLICATE CRTCB_21:*‰MOVE.L„TCBALL(A0),A0‡GET�NEXT�TCB�IN�LIST(‰BRA.S…CRTCB_20ŒBRANCH�BACK�TO�TEST�NEXT  *,*ˆDuplicate�name�found,�free�memory�for�tcb.* CRTCB_30:‰IFNE†MULTPROC3‰TR0.V…SEMTCBŽRELEASE�EXCLUSIVE�ACCESS�TO�TCB�LIST.‰ENDC&‰TR0.PGFR‚(A5),#2�Free�memory�for�tcb. ‰NOP›Ignore�bad�return.$‰MOVE.L„#RTCDDPRQ,D0ˆSet�error�code,‰ADDQ.L„#2,(A7)�signal�error,‰RTS›adn�return.  **ˆGet�Address�Space�Number* CRTCB_40:$‰BSR‡CRASN�Attempt�to�assign�an�ASN.$‰BRA.S…CRTCB_50ŒBranch�if�it�worked. $‰MOVE.L„#RTCDTFUL,D0ˆSet�error�code,‰ADD.L…#2,(A7)�signal�error,‰RTS›and�return.  **ˆPut�new�tcb�in�tcb�all�list.* CRTCB_50:-‰MOVE.L„TCBHD,TCBALL(A5)„New�forward�pointer.-‰MOVE.L„A5,TCBHDŒPut�at�head�of�tcb-all�list.  J ‰IFNE†MULTPROC ‰TR0.V…SEMTCB‰ENDC  ‰RTS›Normal�return.‰PAGE*+*ˆSubroutine�to�assign�monitor�to�new�task.*ˆUsed�by�CRTCB�and�TSKSTART.* ASGNMON:‰BTST†#15,D7ŽMONITOR�SUPPLIED?‰BNE.S…ASGMON_2ŒBRANCH�IF�YES ‰BTST†#14,D7ŽMONITOR�PROPAGATED?‰BEQ.S…ASGMON_9ŒBRANCH�IF�NO $‰MOVE.L„TCBMON(A6),D0‡PROPAGATE�NAME)‰MOVE.L„TCBMON+4(A6),D1…PROPAGATE�SESSION‰BRA.S…ASGMON_5ŒSTORE�THEM ASGMON_2:'‰MOVE.L„14(A4),D1‹GET�SPECIFIED�SESSION$‰MOVE.L„10(A4),D0‹GET�SPECIFIED�NAME!‰BEQ.S…ASGMON_3ŒBRANCH�IF�NO�NAME 0‰BTST†#TSKASYST,TCBATTR(A6)‰IS�REQUESTOR�A�USER?‰BEQ.S…ASGMON_4–BRANCH�IF�YES ‰TST.L…D1œIS�SESSION�SUPPLIED?‰BEQ.S…ASGMON_4–BRANCH�IF�NO-‰BRA.S…ASGMON_5–USE�NAME�AND�SESSION�SUPPLIED  ASGMON_3:)‰MOVE.L„TCBNAME(A6),D0�USE�REQUESTOR�NAME ASGMON_4:-‰MOVE.L„TCBSESSN(A6),D1�USE�REQUESTOR�SESSION ASGMON_5:‰MOVE.L„D0,TCBMON(A5)‘PUT�NAME#‰MOVE.L„D1,TCBMON+4(A5)�PUT�SESSION ASGMON_9:‰RTS‰ENDééééééé=/*=/*†M68XXX.TSKINFO.AF=/*,=/* Chain file to assemble M68XXX.TSKINFO.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.TSKINFO.LS=/*=/IFC \1ƒ=ARG�M68XXX.TSKINFO.LS=/ENDIF=/*3=ASM M68XXX.TSKINFO.SA,M68XXX.TSKINFO.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*}=/*=ENDéééK ééé S'M68XXX TSKINFO SA h hQqqTSKMOVE AF q qqqTSKMOVE SA z zÈqqTSKSTARTAF “ “qqTSKSTARTSA œ œ%‹qqTSKWAIT AF Å ÅqqTSKWAIT SA Î Î<qqUSERVECTAF × ×qqUSERVECTSA à à eqqWAKEUP AF ñ ñqqAKEUP SAÿÿÿÿÿÿÿÿqq‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰LIST‡PAGEBTSKINFO‚IDNT„5,1„68xxx�DIRECTIVE--MOVE�TARGET�TASK'S�TCB�TO�BUFFER*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**Š********************Š*‚T�S�K�I�N�F�O‚**Š*‘**Š*‚REV�1.00�HLD6‚**Š*†06/29/80ƒ**Š*********************ŠENTRY:‚A6‚REQUESTOR'S�TCB*’A4‚PARAMETER�TABLE�POINTER*–0(A0)ƒTASK�NAME*–4(A0)„SESSION&*–8(A0)„OPTIONS�(BIT�15�ON�=�MOVE�TCB)*•10(A0)„BUFFER�ADDRESS*’A5‚TARGET�TCB�ADDRESS*<*ŠTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OD�D0*8*ŠRTCDPBLK‚-�2…PARAM�BLOCK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK‚-�3…SOURCE�TASK�DOES�NOT�EXIST3*ŠRTCDALOW‚-�9…ONLY�SYSTEM�TASK�ALLOWED�TO�COPY�TCB1*ŠRTCDADR1‚-12…BUFFER�NOT�IN�USER'S�ADDRESS�SPACE$*ŠRTCDOPTƒ-15…OPTIONS�NOT�RECOGNIZED*ŒSECTION‚LEVEL04* ‰XDEF†TSKINFO‰PAGE**ˆCheck�buffer�address.* TSKINFO:4‰BTST†#TSKASYST,TCBATTR(A6)‰IS�CALLER�A�SYSTEM�TASK?‰EXIT.EQƒRTCDALOW–ERROR�IF�NO. &‰TR0.LOGPHY‚,10(A4),#512‰BRA.S…TSKINFO2‰NOP '‰EXIT†RTCDADR1–BUFFER�NOT�IN�USER�SPACE  * *ˆFound�buffer�--�check�options.* TSKINFO2:!‰BTST†#15,8(A4)•CHECK�TCB�OPTION."‰EXIT.EQƒRTCDOPT—ERROR�IF�NOT�SET.  * *ˆMove�tcb.* ‰MOVE.L„D6,A3™BUFFER�ADDRESS%‰MOVE.L„#128-1,D0•MOVE�128�LONG�WORDS TSKINFO5:&‰MOVE.L„(A5)+,(A3)+“MOVE�TCB�TO�BUFFER‰DBRA†D0,TSKINFO5 !‰EXIT†SUB›EXIT�(SUBROUTINE�EXIT);‰ENDéK  `R=/*=/*†M68XXX.TSKMOVE.AF=/*,=/* Chain file to assemble M68XXX.TSKMOVE.SA=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M68XXX.TSKMOVE.LS=/*=/IFC \1ƒ=ARG�M68XXX.TSKMOVE.LS=/ENDIF=/*3=ASM M68XXX.TSKMOVE.SA,M68XXX.TSKMOVE.RO,\1;MRZ=055=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*}=/*=ENDéééééé i‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰LIST‰PAGEATSKMOVE‚IDNT…5,1ƒ68xxx�DIRECTIVES--MOVE�LOGICAL�AND�MOVE�PHYSICAL*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**‡*******************6*‡*‚T�S�K�M�O�V�E‚*ƒMOVE�DATA�FROM�ONE�TASK�TO�ANOTHER*‡*‘*0*‡*‚2.00…HLD6‚*†OR�FROM�PHYSICAL�ADDRESS�TO�TASK*‡*…06/29/79„**‡*…02/26/81„**‡*********************†ENTRY:‚A6‚REQUESTOR'S�TCB*ŽA4‚PARAMETER�TABLE�POINTER&*�(A4)�SENDER'S�NAME‚0=USE�REQUESTOR'S*Œ4(A4)ŠSESSN�#&*Œ8(A4)‚START�ADDRESS�OF�SOURCE�BUFFER**‹12(A4)‚RECEIVER'S�NAME‚0=USE�REQUESTOR'S*‹16(A4)�SESSN�#'*‹20(A4)‚RECEIVING�BUFFER�START�ADDRESS *‹24(A4)‚LENGTH�OF�DATA�IN�BYTES**„EXIT‚D0�=�0‚SUCCESS*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARAM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒSOURCE�TASK�DOES�NOT�EXIST)*ŠRTCDNFND�-�7ƒDESTINATION�TASK�NOT�FOUND8*ŠRTCDALOW�-�9ƒUSER�TASK�CANNOT�MOVE�DATA�TO�SYSTEM�TASK=*ŠRTCDLGCF�-11ƒTRYING�TO�MOVE�ODD�TO�EVEN�OR�EVEN�TO�ODD�ADDR5*ŠRTCDADR1�-12ƒSOURCE�BUFFER�NOT�IN�USER'S�ADDR�SPACE:*ŠRTCDADR2�-13ƒDESTINATION�BUFFER�NOT�IN�USER'S�ADDR�SPACE*‰SECTION�LEVEL03* ‰XDEF„MOVELL ‰XDEF„MOVEPL*‰PAGEMOVEPL:‰MOVE.L‚8(A4),D6‰BRA.SƒTSKMOV4  *(*ˆCheck�'from'�task�and�block�addresses.* MOL VELL:%‰MOVE.L‚TCBTST(A5),D1‰IS�THERE�A�TST?‰BEQ.SƒTSKMOV2EŽNO ‰TR0.LOGPHO‚,8(A4),24(A4)(‰BRA.SƒTSKMOV4�GOOD�RETURN�-�FOUND�ENTRY 3‰BRA.SƒTSKMOV2EŽONLY�PART�OF�BUFFER�IN�TASK'S�SPACE ‰TST.LƒD5”POINTER�TO�TST�ENTRY?$‰BEQ.SƒTSKMOV2EŽBRANCH�IF�NO�-�ERROR +‰TST.BƒTSTCTL+1(A0,D5)‡IS�IT�AN�MMIO�ENTRY?%‰BNE.SƒTSKMOV4�BRANCH�IF�YES�-�USE�IT TSKMOV2E:'‰EXIT„RTCDADR1ŽBUFFER�NOT�IN�USER�SPACE  *&*ˆCheck�'to'�task�and�block�addresses.* TSKMOV4: rY {V ƒ(‰MOVE.L„D6,D7�SAVE�'FROM'�BUFFER�ADDRESS 6‰BTSTW…#TSKARTIM,TCBATTR(A6)‰IS�TASK�A�REAL-TIME�TASK.‰BEQ.S…TSKMOV4B–BRANCH�IF�NO. "‰MOVE.L„12(A4),D0•IF�TCBA_DDR�=�0,$‰BEQ.S…TSKMOV4D–THEN�GO�TO�TSKMOV4D. #‰MOVE.L„D0,A0™IF�TCB_ADDR�POINTS�TO‰CMP.L…#'!TCB',(A0)•!TCB,"‰BEQ.S…TSKMOV5—THEN�GO�TO�TSKMOV5; "‰BRA.S…TSKMOV4C–ELSE�REPORT�ERROR; TSKMOV4B:‰TR0.GETTCB‚12(A4)ŒFIND�TCB‰BRA.SƒTSKMOV5 TSKMOV4C:#‰EXIT„RTCDNFNDŽCAN'T�FIND�'TO'�TASK  **ˆFound�task�-�check�addresses.* TSKMOV4D:'‰MOVE.L„A6,A0�USE�CLIENT�TASK�TCB_ADDR; TSKMOV5:4‰BTSTƒ#TSKASYST,TCBATTR(A6)�IS�CALLER�A�SYSTEM�TASK?‰BNE.S‚TSKMOV5AŽBRANCH�IF�YES 7‰BTSTƒ#TSKASYST,TCBATTR(A0)�IS�'TO'�TASK�A�SYSTEM�TASK?‰BEQ.S‚TSKMOV5AŽBRANCH�IF�NO (‰EXITƒRTCDALOWŽUSER�CAN'T�MOVE�TO�SYSTEM TSKMOV5A:%‰MOVE.L‚TCBTST(A0),D1…IS�THERE�A�TST?‰BEQ.SƒTSKMOV6EŠNO ‰TR0.LOGPHO‚,20(A4),24(A4))‰BRA.SƒTSKMOV7‹BRANCH�IF�GOOD�ENTRY�FOUND 4‰BRA.SƒTSKMOV6EŠBUFFER�PARTLY�IN�TASK'S�MEMORY�SPACE (‰TST.LƒD5�WAS�AN�ENTRY�POINTER�RETURNED?$‰BEQ.SƒTSKMOV6EŠBRANCH�IF�NO�-�ERROR /‰TST.BƒTSTCTL+1(A0,D5)ƒIS�THIS�AN�MMIO�SEGMENT?%‰BNE.SƒTSKMOV7‹BRANCH�IF�YES�-�USE�IT TSKMOV6E:'‰EXIT„RTCDADR2ŠBUFFER�NOT�IN�USER�SPACE  *%*ˆFound�both�buffers�-�move�the�data.* TSKMOV7:,‰PEA…TSKMOV2E(PC)‚ERROR�RETURN�FOR�BUS�ERROR"‰MOVE.W‚#'BE',-(A7)ƒBUS�ERROR�FLAG‰MOVE.L‚D7,A2‰'FROM'�ADDRESS‰MOVE.L‚D6,A3‰'TO'�ADDRESS‰MOVE.L‚24(A4),D3…LENGTH‰ADD.LƒD6,D7‰ADD�ADDRESSES‰BTST„#0,D7‰IS�RESULT�EVEN?-‰BEQ.SƒTSKMOV8‡BRANCH�IF�YES�-�GOOD�ADDRESSES .‰ADD.Lƒ#6,A7‰REMOVE�BUS�ERROR�STUFF�FROM�STACK.‰EXIT„RTCDLGCF†CAN'T�MOVE�EVEN-ODD�OR�ODD-EVEN TSKMOV8:$‰BTST„#0,D6‰ARE�BOTH�ADDRESSES�EVEN?‰BEQ.SƒTSKMOV9‡YES -‰MOVE.B‚(A2)+,(A3)+ƒBOTH�ODD�-�MAKE�THEM�EVEN/‰NOP˜This�NOP�causes�the�execution�unit�to�wait)*§for�the�bus�interface�unit�to�finish�on&*§a�68020,�in�case�we�get�a�bus�error.‰SUB.Lƒ#1,D3‰DECREMENT�COUNT‰BEQ.SƒTSKMOVR‡IF�0�--�DONE TSKMOV9:‰MOVE.L‚D3,D4‰SAVE�LENGTH‰LSR.Lƒ#2,D3‰DIVIDE�BY�4/‰BRA.SƒTSKMOV11†BRANCH�IF�NO�LONG�WORDS�TO�MOVE TSKMOV10:#‰MOVE.L‚(A2)+,(A3)+ƒMOVE�LONG�WORDS TSKMOV11:/‰DBRA„D3,TSKMOV10ƒDECREMENT�COUNT�OF�LONG�WORDS/‰NOP˜This�NOP�causes�the�execution�unit�to�wait)*§for�the�bus�interface�unit�to�finish�on&*§a�68020,�in�case�we�get�a�bus�error.#‰AND.Lƒ#3,D4‰BITS�0�AND�1�OF�LENGTH‰BRA.SƒTSKMOV14†NO�MORE�TO�MOVE TSKMOV12:‰MOVE.B‚(A2)+,(A3)+ƒMOVE�BYTES TSKMOV14:*‰DBRA„D4,TSKMOV12ƒDECREMENT�COUNT�OF�BYTES/‰NOP˜This�NOP�causes�the�execution�unit�to�wait)*§for�the�bus�interface�unit�to�finish�on&*§a�68020,�in�case�we�get�a�bus�error. TSKMOVR:4‰ADD.Lƒ#6,A7‰REMOVE�'BE'�AND�ERROR�RETURN�FROM�STACK!‰EXIT„SUB“exit�(subroutine�exit);‰ENDéL ééé=/*=/*†M68XXX.TSKSTART.AF=/*-=/* Chain file to assemble M68XXX.TSKSTART.SA=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to M68XXX.TSKSTART.LS=/*=/IFC \1ƒ=ARG�M68XXX.TSKSTART.LS=/ENDIF=/*5=ASM M68XXX.TSKSTART.SA,M68XXX.TSKSTART.RO,\1;MRZ=060=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*}=/*=ENDéééééé ‹‰PAGE**ˆINCLUDE�FILES**ˆINCLUDEƒ9995.&.STR.EQ*ˆINCLUDEƒ9995.&.TR1RTCD.EQ*ˆINCLUDEƒ9995.&.TCB.EQ*ˆINCLUDEƒ9995.&.TST.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰INCLUDEƒ9995.&.TR1RTCD.EQ‰INCLUDEƒ9995.&.TCB.EQ‰INCLUDEƒ9995.&.TST.EQ‰LIST‰PAGE5TSKSTART�IDNTƒ5,2†68xxx�DIRECTIVE--START�DORMANT�TASK*$*ˆCOPYRIGHTED�1980�BY�MOTOROLA,�INC.**ˆ*********************ˆ*�TSKSTART„2.00�**ˆ*’**ˆ*�GGC3�03/21/79„**ˆ*�7616�05/02/79„**ˆ*�HLD6�03/24/81„*'*ˆ*�baw‚01/30/85‚fix�for�real�time�task*ˆ*********************!*ˆSTART�A�TASK�AT�ITS�ENTRY�POINT*"*ƒENTRY:�A6‚REQUESTORS�TCB�ADDRESS*ŠA4‚PARAMETER�BLOCK*‰(A4)�TASK�NAME*ˆ4(A4)�SESSION�NO.1*ˆ8(A4)�W‚DIRECTIVE‚15�ON=MONITOR‚13�ON=REGISTERS*ˆ10(A4)�MONITOR�NAME*ˆ14(A4)�SESSION�CODE'*ˆ18(A4)‚REGISTERS�IN�SUPERSTACK�FORMAT**�IF�REQUESTOR�IS�USER�TASK�ZERO�TOP�OF�SR*(*ƒEXIT:‚D0�=�0‚IF�TASK�PUT�ON�READY�LIST*<*ˆTHE�FOLLOWING�RETURN�CODES�ARE�RETURNED�IN�LOWER�1/2�OF�D0*6*ŠRTCDPBLK�-�2ƒPARM AM�BLK�ADDR�NOT�IN�USER'S�ADDR�SPACE)*ŠRTCDTASK�-�3ƒTARGET�TASK�DOES�NOT�EXIST/*ŠRTCDDPRQ�-�6ƒDUPLICATE�REQUEST�-�TASK�STARTED1*ŠRTCDALOW�-�9ƒUSER�TASK�CANNOT�START�SYSTEM�TASK**.*ˆCHECK�PARAMETER�BLOCK�FOR�ALL�IN�USER�MEMORY*‰SECTION�LEVEL04*‰XDEF‚TSKSTART‰XREF.S�ASGNMON‰PAGE**…CHECK�PARAMETER�BLOCK�AGAIN* 5TSKSTART�MOVE.W�SR,-(A7)ƒSave�current�interrupt�level#‰BTST‚#13,8(A4)ƒREGISTERS�SUPPLIED?‰BEQ.S�TSKSTR0A *‰MOVE.L�#82,D5„82�BYTES�IF�REGISTERS�GIVEN‰BRA.S‚TSKSTR0B )TSKSTR0A‚BTST‚#15,8(A4)ƒMONITOR�SUPPLIED?ŠBEQ.S‚TSKSTR1ƒBRANCH�IF�NO +ŠMOVE.L‚#18,D5„18�BYTES�IF�MONITOR�SUPPLIED,TSKSTR0B‚MOVE.L�TCBA0(A6),D6…LOGICAL�ADDRESS.ŠTR0.LOGPHYƒ…CHECK�PHYSICAL�ADDR%ŠBRA.SƒTSKSTR1…BRANCH�IF�GOOD�ADDRESS ŠNOPŠMOVE.W‚(A7)+,SRŠEXIT„RTCDPBLK 'TSKSTR1�TST.Lƒ(A4)ˆIS�TASK�NAME�=�ZERO?ˆBNE.SƒTSKSTR4†BRANCH�IF�NO **ŠSELECT�A�TASK�TO�START* 5ˆMOVE.L‚TCBSESSN(A6),D1ƒWANT�TASK�IN�CALLER'S�SESSION ”Y �X ¥N ­U µ8(ˆMOVE.L‚TCBHD,A5‰1ST�TCB�ON�TCB-ALL�LIST(TSKSTR2‚CMP.Lƒ#0,A5‰IS�THIS�END�OF�LIST?,ˆBEQ.SƒTSKSTR5‰BRANCH�IF�YES�-�NO�TASK�FOUND +ˆCMP.LƒTCBSESSN(A5),D1„CHECK�SESSION�NUMBER!ˆBNE.SƒTSKSTR3‰BRANCH�IF�NO�MATCH 2ˆBTST„#TSKASYST,TCBATTR(A5)‚IS�THIS�A�SYSTEM�TASK?ˆBNE.SƒTSKSTR3ŒBRANCH�IF�YES -ˆBTST„#TSKSDORM,TCBSTATE(A5)‚IS�TASK�DORMANT?ˆBEQ.SƒTSKSTR3ˆBRANCH�IF�NO 0ˆBTST„#TSKSDORM,TCBSTATE+2(A5)‚WAS�TASK�STOPPED?2ˆBNE.SƒTSKSTR9AˆBRANCH�IF�YES�-�FOUND�ONE�TO�START 1TSKSTR3�MOVE.L‚TCBALL(A5),A5ƒGET�ADDR�OF�NEXT�TCB&ˆBRA.SƒTSKSTR2‹BRANCH�BACK�TO�CHECK�IT  *(*‡LOOK�FOR�TASK�NAMED�IN�PARAMETER�BLOCK* $TSKSTR4�TR0.GETTCB‚(A4)„LOOK�FOR�TCBˆBRA.S„TSKSTR6ƒBRANCH�IF�FOUND  **…NO�TASK�FOUND�-�RETURN�ERROR* -TSKSTR5�CLR.LƒTCBA0(A6)‡NO�TASK�NAME�RETURNEDˆMOVE.W‚(A7)+,SRˆEXIT„RTCDTASKˆERROR�-�NO�TASK  **‡CHECK�FOR�LEGAL�REQUEST* 6TSKSTR6�MOVE.L‚A0,A5‚TCB�ADDRESS�OF�TASK�TO�BE�STARTEDˆCMP.LƒA5,A6‚IS�TASK�=�CALLER?$ˆBEQ.SƒTSKSTR7„BRANCH�IF�YES�-�ERROR 4ˆBTST„#TSKASYST,TCBATTR(A5)‚IS�TARGET�A�SYSTEM�TASK?ˆBEQ.SƒTSKSTR8†BRANCH�IF�NO 4ˆBTST„#TSKASYST,TCBATTR(A6)‚IS�CALLER�A�SYSTEM�TASK?ˆBNE.SƒTSKSTR8†BRANCH�IF�YES  TSKSTR7:)‰MOVE.W‚(A7)+,SR�RESTORE�INTERRUPT�LEVEL.‰EXIT„RTCDALOW�ERROR  ,TCBPC(A5),#2%‰BRA.S‚TSKSTRR1ŒBRANCH�IF�GOOD�RETURN ‰NOP(‰MOVE.W�(A7)+,SR�RESTORE�INTERRUPT�LEVEL(‰EXITƒRTCDADR1�ERROR�-�BAD�ENTRY�ADDRESS  7TSKSTRR1�MOVE.L�D6,TCBPC(A5)ŠPHYSICAL�ADDRESS�FOR�ENTRY  *1*ˆCHANGE�ALL�LOGICAL�ADDRESSES�IN�TST�TO�PHYM SICAL* /‰MOVE.W‚TSTLMMU(A0),D5‡OFFSET�TO�LAST�MMU�ENTRY4TSKSTRR2�BTST„#SEGAUSED,TSTAATTR(A0,D5)‚EMPTY�ENTRY?‰BEQ.SƒTSKSTRR3�BRANCH�IF�YES +‰MOVE.W‚TSTPO(A0,D5),D0†GET�PHYSICAL�OFFSET+‰ADD.WƒD0,TSTLB(A0,D5)†ADD�TO�LOGICAL�BEGIN)‰ADD.WƒD0,TSTLE(A0,D5)†ADD�TO�LOGICAL�END)‰CLR.WƒTSTPO(A0,D5)‰CLEAR�PHYSICAL�OFFSET&TSKSTRR3�SUB.Lƒ#8,D5�NEXT�ENTRY�OFFSET'‰CMP.Wƒ#TSTMMU,D5‹ALL�SEGMENTS�CHECKED?‰BGE…TSKSTRR2�BRANCH�IF�NO  **ˆSET�INITIAL�REGISTERS* 4TSKSTRT6�CLR.W‚TCBSTATE+2(A5)†CLEAR�SAVED�STATE�WORD'‰BTSTƒ#13,8(A4)‡ARE�REGISTERS�SUPPLIED?‰BEQ.S‚TSKSTRT7ˆBRANCH�IF�NO #‰LEA„18(A4),A3†POINT�TO�SUPPLIED�D0'‰MOVEM.L�(A3)+,D0-D7ƒGET�DATA�REGISTERS)‰MOVEM.L�D0-D7,TCBD0(A5)‚PUT�IN�TCB�STACK*‰MOVEM.L�(A3)+,D0-D6ƒGET�ADDRESS�REGISTERS)‰MOVEM.L�D0-D6,TCBA0(A5)�PUT�IN�TCB�STACK  **†SHOULD�TASK�BE�ON�READY�LIST* )TSKSTRT7‚OR.Wƒ#$700,SR‡INHIBIT�INTERRUPTS.ŠBCLR‚#TSKSDORM,TCBSTATE(A5)‚CLEAR�DORMANT�BIT&ŠMOVE.W�TCBSTATE(A5),D0„GET�STATE�WORD0ŠAND.W‚#TSKSWMSK-1<