English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 14 February 2019, 20:02   #21
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
Quote:
Originally Posted by StingRay View Post
I have checked, the intro lacks blitter waits which are most likely the reason for the system freeze upon exit! Just saving hardware registers etc. is not enough to let the intro run properly on anything else than a plain 7 MHz Amiga, you need to add the blitter waits!
Thanks for that important hint, StingRay. I will include an extra blitter wait after the demo exits, so there won't be any blitter operarions in memory areas which are already freed. Let's see what the positive consequences will be...
dissident is offline  
Old 14 February 2019, 20:09   #22
Hedeon
PPC Hacker

 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 1,084
Quote:
Originally Posted by Toni Wilen View Post
Missing Permit() is REQUIRED when program was started from WB. Check Workbench chapter in RKRM.
He means the missing is required. Not the Permit(). That needs to be missing in case of a WB program. That is does not work for you is either:

1) Your code is faulty somewhere
2) You are not really starting from WB and the WB code (ReplyMsg) gets executed anyway.

You refer to the wrong part of the RKM. See Toni's remark about that.

Last edited by Hedeon; 14 February 2019 at 20:15.
Hedeon is offline  
Old 14 February 2019, 21:20   #23
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
Quote:
Originally Posted by ross View Post
Now you have intrigued me because I do not use Permit() before rts and it normally works.

If i'm not wrong it's mandatory to do the ReplyMsg() in Forbid() state and exit w/o a Permit() to prevent WB prematurely unloadseg the exe.
Yes, you are right. The Libraries Manual says:
Quote:
When the application code exits back to the startup code, the startup code closes and frees all opens and allocations it made. It will then Forbid(), and ReplyMsg() the WBStartup message, notifying Workbench that the application Process may be terminated and its code unloaded from memory.
dissident is offline  
Old 14 February 2019, 21:30   #24
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
Quote:
Originally Posted by Toni Wilen View Post
Missing Permit() is REQUIRED when program was started from WB. Check Workbench chapter in RKRM.
Sure, the WB-Message must only be replied, if the program was started with an icon from WB.

Quote:
Originally Posted by Toni Wilen View Post
When WB gets the message back, it will UnloadSeg() and free all memory. If task switching is enabled, program may get unloaded before following instruction(s) are executed.
Yes, this was already clear to me, but thanks for the hint.
dissident is offline  
Old 15 February 2019, 14:58   #25
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
Quote:
Originally Posted by Hedeon View Post
He means the missing is required. Not the Permit(). That needs to be missing in case of a WB program. That is does not work for you is either:

1) Your code is faulty somewhere
2) You are not really starting from WB and the WB code (ReplyMsg) gets executed anyway.

You refer to the wrong part of the RKM. See Toni's remark about that.
Well, now it is much clearer why the additional Permit() works for the mentioned demo. I don't call this demo by a separate process. I load it with LoadSeg() and execute it with a jsr command. So the demo doesn't return the normal way to CLI, it returns to my main program. Normally as I know now, the return to the CLI is like a Permit() and task rescheduling is enabled. But after the demo has returned, I do many other things in my main program until I return to CLI. It seems, in this case, the additional Permit() is needed as a counterpart for the Forbid() of the demo like Commodore suggested in their autodocs.
dissident is offline  
Old 19 February 2019, 10:08   #26
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
I analyzed the functions Forbid() and Permit() to check, if there are differences between Kick1.3 and 3.1:

Kickstart 1.3
Code:
Forbid
   addq.b #1,$127(a6)  ;TDNESTCNT
   rts
Code:
Permit
   subq.b #1,$127(a6)  ;TDNESTCNT
   bge.s $fc1bc        ;If counter >=0 then skip
   tst.b $126(a6)      ;IDNESTCNT
   bge.s $fc1bc        ;If counter >=0 then skip
   btst #7,$124(a6)    ;SysFlags
   beq.s $fc1bc        ;If bit7 not set then skip  
   move.l a5,-(a7)
   lea $fc1be(pc),a5
   jsr -$1e(a6)        ;Supervisor()
   move.l (a7)+,a5
$fc1bc
   rts

$fc1be
   btst #5,(a7)        ;Check stack frame format: Format$2 or Format $3 ?
   beq.s $fc1fc6       ;No -> skip
   rte

$fc1fc6
   jmp -$2a(a6)        ;Schedule() - check the list of ready tasks and inform if the current task needs to be switched
Kickstart 3.1

Code:
Forbid
   addq.b #1,$127(a6)  ;TDNESTCNT
   rts
Code:
Permit
   subq.b #1,$127(a6)  ;TDNESTCNT
   bge.s $f82946       ;If counter >=0 then skip
   tst.b $126(a6)      ;IDNESTCNT
   bge.s $f82946       ;If counter >=0 then skip
   tst.w  $124(a6)     ;SysFlags
   bmi.s $f82948       ;If bit7 set then skip
$f82946
   rts

$f82948
   move.l a5,-(a7)
   lea $f82956(pc),a5
   jsr -$1e(a6)        ;Supervisor() 
   move.l (a7)+,a5
   rts

$f82956
   btst #5,(a7)        ;Check stack frame format: Format$2 or Format $3 ?
   bne.s $f82960       ;Yes -> skip
   jmp -$2a(a6)        ;Schedule() - check the list of ready tasks and inform if the current task needs to be switched
$f82960 
   rte
Apart from some optimizing they work identically on Kickstart 1.3 and 3.1.


Quote:
Originally Posted by meynaf View Post
IIRC this is TDNestCnt. But it's a counter, not a mere flag (calls to Forbid must be matched by the same number of calls to Permit).
I found an interesting passage in the "Amiga System Programmers guide" published by Abacus which confirms meynaf's statemant:

Quote:
It is also possible to nest several ForbidO or DisableO calls. Two counters are maintained, TDNestCnt and IDNestCnt (Task Disable Nesting Counter and Interrupt Disable Nesting Counter). Everytime Forbid() is called, TDNestCnt is incremented by 1, and decremented by 1 on each call to Permit(). Task switching is possible only when TDNestCnt < 0. This means that the number of Permit() calls must be the same as the number of ForbidO calls before task switching is reenabled. This applies to Enable(), DisableO and IDNestCnt.
Thus TDNestCnt = -1 ($ff) means that the Task-Switching is enabled. This values is also used by TDNestCnt/IDNestCnt in the ExecBase structure. So if there was a Permit() too much, then TDNestCnt would be -2 ($fe) and Task-Switching will be still active.

In "AmigaOS – internal structure of operating system" published by Zbigniew Trzcionkowski I found an explanation of the internal exec function Schedule() which is called by Permit() if SysFlag = negative and the stack frame has not the Format$2 or Format $3:

Quote:
4.3 How Amiga scheduler does work

Alas from stuffs for developpers it is only possible to determine names of exec’s private functions used for scheduling. This chapter despite of basing on amateur analyses should show the hidden gearworks of AmigaOS.
Each task in AmigaOS is represented by appropriate structure. Every amiga task can be in one of the following states:
- in state of running (TS_RUN flag)
- be on TaskReady list (tasks wating for processor’s time – TS_READY flag)
- be on TaskWait list (tasks of waiting for event – TS_WAIT flag)
AmigaOS provides preemptive multitasking – in the other works the only real multitasking, where each task can be held at any time and replaced with another. This work is done by so called scheduler and in case of Amiga scheduler is a mechanism built into the system of interrupts.

4.3.1 Interrupts
During initialisation of the system special routines are set up to handle processor’s interrupts. AmigaOS offers multilevel interrupt handling – each program can add it’s own code to be executed during interrupt by adding node appropriate system list. User’s code will be called by the system interrupt handling routine . Apparently the ExitIntr(), function called at the end of the each system interrupt handling routines calls internally function Schedule().

The Schedule() function takes several decisions:
1. if there is another interrupt pending current task is left untouched
2. if exec/TaskReady list is empty then current task is left untouched
3. if exec/TaskReady list contains task with higher priority then perform Switch()
4. if time for task has exceeded then do Switch()
5. otherwise current task is left untouched

The Switch() function stores in the structure describing task state of the processor in terms of program counter, registers etc. Such switched off task is stored in appropriate list TaskReady or TaskWait. Another procedure is Dispatch(). The Dispach() function check if on the top of the TaskReady list is task ready to run (it is possible it’s once again the same one switched off before). If there is no task waiting for processor’s time we can see unusual in normal programming loop inside which the processor is stopped:

Code:
stop     #$2000
move.l   D0,D0
bra.s    check_again
When this particular loop gets task then the state of the processor stored before with Switch() function. Functions Switch() and the restoring one are depending on the system configuration. If the computer is equipped with arithmetic coprocessor then it’s registers also have to be saved. In simplies case it looks like that:

Code:
lea      $42(A5),A2       ;addresss of stack address
move.l   A2,USP           ;set user stack pointer
move.l   (A5)+,-(SP)      ;push on stack program counter(PC)
move.w   (A5)+,-(SP)      ;push on stack status register(SR)
movem.l  (A5),D0-D7/A0-A6 ;restore other registers
rte                       ;enter Supervisor mode. rte writes the values into PC and SR
Quote:
Originally Posted by meynaf View Post
But does the task really exit ? If run from WB directly, it does. If run from some cli, then the cli is the current task and it does not get deleted after the program exits. Besides, the demo might leave the forbid/permit counter in any state...
To my mind, this is the most comprehensible explanation of this special case.

Quote:
Originally Posted by StingRay View Post
There must be another reason for the freeze, I just tried returning to the system without calling Permit() on my 3.1 machine and it worked without any problem.
Many old OCS demos trash memory and/or don't restore interrupt/hardware vectors correctly which can lead to problems such as system freezes.
Quote:
Originally Posted by Toni Wilen View Post
Was task structure or execbase also in stored/restored part of chip ram?
You are both right with your statemants. The error is based on different reasons.

Generally I was wrong with my assumption about the need to do an extra call of the Permit() function in the case of my test intro. Forbid() and Permit() write directly into the ExecBase structure.

On my test system, the exec.library is placed at the beginning of CHIP memory. So if I save the lower 1MB CHIP memory before I execute the intro, I capture the exec base structure at a certain state. This state may change by system interrupts writing to the execbase structure or called exec functions by the intro.

If I restore CHIP memory after the intro is quit, I restore an exec base structure with old data which might have changed by interrupts or the intro. If the exec.library is in FAST memory that's unimportant, but in my case this could lead to the strange behaviour of freezing the system. I assume, that the counters TDNestCnt and IDNestCnt contain the wrong values (not negative, but >=0) or other important execbase entries are out of date and make the system freeze after I return to CLI.
dissident is offline  
Old 26 February 2019, 13:01   #27
mschulz
Registered User

 
Join Date: Nov 2018
Location: Germany
Posts: 13
Quote:
Originally Posted by dissident View Post
I analyzed the functions Forbid() and Permit() to check, if there are differences between Kick1.3 and 3.1:
Code:
   btst #5,(a7)        ;Check stack frame format: Format$2 or Format $3 ?
Just for clearance (in case anyone may need it and looks seriously at the code comment). The btst #5 instruction above does not check the stack frame format. It checks if the code (executed through Supervisor call) shall return to supervisor mode or to user mode.

The former is the case if Permit() was called in supervisor. In that case no rescheduling will take place as it would have very fatal consequences. On the other hand, if Permit() was called in user mode (bit 5 of upper byte of SR - supervisor, is clear) then it will trigger scheduler if TDNestCnt < 0 and IDNestCnt < 0 and ATTN_Resched (bit 7) flag in SysFlags is set.
mschulz is offline  
Old 27 February 2019, 11:46   #28
dissident
Registered User

 
Join Date: Sep 2015
Location: Germany
Posts: 224
Quote:
Originally Posted by mschulz View Post
Just for clearance (in case anyone may need it and looks seriously at the code comment). The btst #5 instruction above does not check the stack frame format. It checks if the code (executed through Supervisor call) shall return to supervisor mode or to user mode.

The former is the case if Permit() was called in supervisor. In that case no rescheduling will take place as it would have very fatal consequences. On the other hand, if Permit() was called in user mode (bit 5 of upper byte of SR - supervisor, is clear) then it will trigger scheduler if TDNestCnt < 0 and IDNestCnt < 0 and ATTN_Resched (bit 7) flag in SysFlags is set.
Yes, you are right. Thanks for your hint. Your explanation makes it much clearer for me now.
dissident is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Exit winuae? magoomba New to Emulation or Amiga scene 7 26 October 2018 23:50
pc task 4.4:) 8bitbob support.Apps 5 25 October 2016 23:01
Startup Code (from Icon ) - Forbid function Asman Coders. System 2 04 January 2014 11:45
Cannot exit from Some games @UAE project.WHDLoad 13 19 November 2008 14:28
OS 3.9 can't exit and some more problems Tea support.WinUAE 1 09 July 2003 13:51

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 23:38.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.
Page generated in 0.07654 seconds with 15 queries