Welcome, Guest. Please login or register.

Author Topic: wb program init in assembler  (Read 5250 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline peroxidechickenTopic starter

  • Full Member
  • ***
  • Join Date: Apr 2002
  • Posts: 170
    • Show only replies by peroxidechicken
wb program init in assembler
« on: March 02, 2003, 10:47:11 AM »
I expected to find some how-to and why-for info in the rom kernal manuals about the message(s) passed to a program if it's started from workbench.  I've seen plenty of others' source with 'check-if-cli/wb - wait/get/reply message' routines done once - I've even seen forbid & permit employed in this process.  

Can anybody enlighten me with a step-through of how and why a program initializes itself?  

Speaking of processes, despite finding this in the rkrm, I'm still unclear on the difference between tasks and processes - anybody?  
H2O2
 

Offline Steady

Re: wb program init in assembler
« Reply #1 on: March 03, 2003, 10:10:37 AM »
I have that information at home. If someone doesn't beat me to it in the next 24 hours, I will give you what I can.

As for tasks/ processes:

A task is the structure used by exec to manage each of the tasks. However, a simple task cannot use AmigaDOS (dos.library et al). This means either direct or indirect use.

A process is a task structure with extra fields that contain information that AmigaDOS needs to manage I/O and other such tasks.

ie: if you want to use dos, you need a process. When you start a program via CLI or Workbench you will get a full Process structure. It is only when you launch another task via your program that you have to think about what it will be used for.
 

Offline itix

  • Hero Member
  • *****
  • Join Date: Oct 2002
  • Posts: 2380
    • Show only replies by itix
Re: wb program init in assembler
« Reply #2 on: March 03, 2003, 02:10:25 PM »
If your task is launched from WB you *MUST* read WBMessage first. And before you exit you reply to this message in Forbid() state.

In short (using pseudo-C) it goes like this:

start:
  wbmsg = NULL;

  task = FindTask(NULL)

 if (task->pr_CLI == 0 )
 {
   WaitPort(&task->pr_MsgPort);
  wbmsg = GetMsg(&task->pr_MsgPort);
 }

 ; your code here

 if ( wbmsg != NULL )
 {
   Forbid();
  ReplyMsg(wbmsg);
 }
 return return_code;

My Amigas: A500, Mac Mini and PowerBook
 

Offline xeron

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 2533
    • Show only replies by xeron
    • http://www.petergordon.org.uk
Re: wb program init in assembler
« Reply #3 on: March 03, 2003, 03:02:22 PM »
Heh. I'll shut up then  :-D
Playstation Network ID: xeron6
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: wb program init in assembler
« Reply #4 on: March 03, 2003, 04:43:33 PM »
@Tickly:

Careful there! You should know what you're talking about when you try to instruct people.

That Forbid() is *absolutely required* and there must *not* be Permit()!

That Forbid() guarantees the Workbench don't have a change to UnLoadSeg() the seglist of the program while the program is still executes.

If there is no Forbid(), the ReplyMsg() results in task scheduling, and Workbench get change to run. Workbench UnLoadSeg() the seglist, and the last few instructions are executed on unallocated memory. This will lead into crashes.

There is no need for final Permit(), since the process will RemTask(NULL) itself eventually (default Task EndPC), and this completely removes the process anyway.

However, programs run from CLI *MUST* call Permit() for each Forbid() since the final 'rts' drops back to shell, and does not terminate the process.

I hope I didn't get too technical here. Anyway the point is, that itix's example is 100% correct. This is the standard way to handle program startup.

PS. This all is explained on developer CD and various other programming guides.

[edit: some cleanup]
 

Offline xeron

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 2533
    • Show only replies by xeron
    • http://www.petergordon.org.uk
Re: wb program init in assembler
« Reply #5 on: March 03, 2003, 04:50:30 PM »
Yeah, I should know this stuff, but the truth is i've never written my own code to handle this (some coder gave me a "wbstartup.i" which i've always used in assembler, and in C i just used the compiler startup code.

In future i promise to check my facts first ;)
Playstation Network ID: xeron6
 

Offline xeron

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 2533
    • Show only replies by xeron
    • http://www.petergordon.org.uk
Re: wb program init in assembler
« Reply #6 on: March 03, 2003, 05:01:47 PM »
Quote

However, programs run from CLI *MUST* call Permit() for each Forbid() since the final 'rts' drops back to shell, and does not terminate the process


This is true, but in most cases Forbid()/Permit() pairs can and should be avoided; Semaphores come in very handy here :)
Playstation Network ID: xeron6
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: wb program init in assembler
« Reply #7 on: March 03, 2003, 05:22:21 PM »
;
; Workbench startup code
;

_LVOForbid   EQU -$84
_LVOFindTask EQU -$126
_LVOGetMsg   EQU -$174
_LVOReplyMsg EQU -$17A
_LVOWaitPort EQU -$180

pr_MsgPort   EQU $5C
pr_CLI       EQU $AC


; WBStartUp code - entry point
;
startupcode:

move.l  (4).w,a6

; Save original CLI commandline args.
;
move.l  d0,d2
move.l  a0,a2

; Find process pointer of self.
;
sub.l   a1,a1
jsr     _LVOFindTask(a6)
move.l  d0,a4

; If pr_CLI is non-NULL then the program was started from shell.
; In this case don't bother with further processing. Just
; jump to main routine (and exit in there).
;
tst.l   pr_CLI(a4)
bne.b   _main

; Wait for the Workbench startup message to arrive.
;
lea     pr_MsgPort(a4),a0
jsr     _LVOWaitPort(a6)

; Get the Workbench startup message pointer.
;
lea     pr_MsgPort(a4),a0
jsr     _LVOGetMsg(a6)
move.l  d0,-(sp)

; Call the actual program code. Argument pointer (a0) will
; be NULL. D0 contain pointer to WBStartup Message
; (see workbench/startup.i).
;
move.l  d0,d2
sub.l   a2,a2
bsr.b   _main

; Save RC for final return.
;
move.l  d0,d2

; Forbid to avoid Workbench from unloading our seglist while
; we execute it.
;
move.l  (4).w,a6
jsr     _LVOForbid(a6)

; Reply WBStartup message. This will instruct Workbench to
; unload the seglist of the program.
;
move.l  (sp)+,a1
jsr     _LVOReplyMsg(a6)

; Set final RC and return with original stack pointer.
;
move.l  d2,d0
rts


_main:

move.l  d2,d0
move.l  a2,a0

;
; ...actual program code follows, exit with 'rts', d0 containing RC.



[NOTE: This code snippet doesn't explain the WBStartup message itself. Check workbench/startup.i for details.]
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: wb program init in assembler
« Reply #8 on: March 03, 2003, 05:26:05 PM »
Quote
This is true, but in most cases Forbid()/Permit() pairs can and should be avoided; Semaphores come in very handy here :)

This is true, but in most cases ObtainSemaphore()/ReleaseSemaphore() pairs can and should be avoided; Locking-free design come in very handy here :))

Ok, now I'm being a smartass, you're right, semaphores should be used when possible. Forbid()/Permit() should only be used when there is no alternative.
 

Offline xeron

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 2533
    • Show only replies by xeron
    • http://www.petergordon.org.uk
Re: wb program init in assembler
« Reply #9 on: March 03, 2003, 05:27:30 PM »
Quote

This is true, but in most cases ObtainSemaphore()/ReleaseSemaphore() pairs can and should be avoided; Locking-free design come in very handy here :))


Considering that the Amiga doesn't have proper threads, when using multithreaded programs, Semaphores can be very useful for things like access to memory pools, lists that could be modified by other threads, etc. etc.
Playstation Network ID: xeron6
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: wb program init in assembler
« Reply #10 on: March 03, 2003, 05:35:26 PM »
Quote
Considering that the Amiga doesn't have proper threads, when using multithreaded programs, Semaphores can be very useful for things like access to memory pools, lists that could be modified by other threads, etc. etc.

Well that's what Semaphores are for.

But if you can make without, the better. Totally asyncronous routines are even better (albeit harder to implement, and not suited for everything).

Are we both happy now? ;-)
 

Offline xeron

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 2533
    • Show only replies by xeron
    • http://www.petergordon.org.uk
Re: wb program init in assembler
« Reply #11 on: March 03, 2003, 05:38:14 PM »
Yeah, tbh, my pedanticism is a little bit of face saving. I have my pride, you know :)
Playstation Network ID: xeron6