home *** CD-ROM | disk | FTP | other *** search
- unit Amiga;
-
- INTERFACE
- {$ifdef WORKBENCH_2}
- Uses Exec, AmigaDOS, Graphics, Hardware, Intuition, Timer, Utility;
- {$else}
- Uses Exec, AmigaDOS, Graphics, Hardware, Timer;
- {$endif}
-
-
- (* String conversion *)
- function PtrToPas (c: STRPTR): string;
- function StringToC (var p: string): STRPTR;
-
- (* Exec support *)
- procedure BeginIO (ioRequest: pIORequest);
- function CreateExtIO (port: pMsgPort; size: integer): pIORequest;
- function CreatePort (name: STRPTR; pri: integer): pMsgPort;
- function CreateStdIO (port: pMsgPort): pIOStdReq;
- function CreateTask (name: STRPTR; pri: longint;
- initPC: pointer; stackSize: longint): pTask;
- procedure DeleteExtIO (ioReq: pIORequest);
- procedure DeletePort (port: pMsgPort);
- procedure DeleteStdIO (ioReq: pIOStdReq);
- procedure DeleteTask (task: pTask);
- procedure NewList (list: pList);
-
- (* Graphics support *)
- procedure AddTOF (i: pIsrvstr; p: pointer; a: longint);
- procedure RemTOF (i: pIsrvstr);
-
- (* AmigaDOS support *)
- function DOSPacket (pid: pMsgPort; action: longint;
- var args; nargs: integer): longint;
-
- (* Timer support *)
- function TimeDelay (unit_: longint; secs, microsecs: long): longint;
-
- (* 2.0 only BOOPSI support *)
- {$ifdef WORKBENCH_2}
- function CallHookA (hook: pHook; object, paramPacket: pointer): long;
- function CoerceMethodA (cl, obj: pointer; message: Msg): long;
- function DoMethodA (obj: pointer; message: Msg): long;
- function DoSuperMethodA (cl, obj: pointer; message: Msg): long;
- procedure HookEntry (hook: pHook; object, paramPacket: pointer);
- {$endif}
-
-
- IMPLEMENTATION
- (* String conversion *)
- function PtrToPas (c: STRPTR): string; xassembler;
- asm
- movem.l 4(sp),a0-a1
- addq.l #1,a1
- move.w #254,d0
- @1:
- move.b (a0)+,d1
- beq @2
- move.b d1,(a1)+
- dbra d0,@1
- @2:
- addq.b #1,d0
- not.b d0
- move.l 8(sp),a0
- move.b d0,(a0)
- end;
-
-
- function StringToC (var p: string): STRPTR; xassembler;
- asm
- move.l 4(sp),a0
- move.l a0,8(sp)
- moveq #0,d0
- move.b (a0),d0
- bra @2
- @1:
- move.b 1(a0),(a0)+
- @2:
- dbra d0,@1
- clr.b (a0)
- end;
-
-
- (* Exec support *)
- procedure BeginIO (ioRequest: pIORequest); xassembler;
- asm
- move.l 4(sp),a1
- move.l a6,-(sp)
- move.l tIORequest.io_Device(a1),a6
- jsr DEV_BEGINIO(a6)
- move.l (sp)+,a6
- end;
-
-
- function CreateExtIO (port: pMsgPort; size: integer): pIORequest;
- var IOReq: pIORequest;
- begin
- CreateExtIO := NIL;
- if port <> NIL then
- begin
- IOReq := AllocMem(size, MEMF_CLEAR or MEMF_PUBLIC);
- if IOReq <> NIL then
- with IOReq^.io_Message, mn_Node do
- begin
- ln_Type := NT_Message;
- mn_Length := size;
- mn_ReplyPort := port;
- CreateExtIO := IOReq
- end
- end
- end;
-
-
- procedure DeleteExtIO (ioReq: pIORequest);
- begin
- with IOReq^, io_Message do
- begin
- mn_Node.ln_Type := $FF;
- mn_ReplyPort := pMsgPort(-1);
- io_Device := pDevice(-1);
- FreeMem_(IOReq, mn_Length)
- end
- end;
-
-
- function CreateStdIO (port: pMsgPort): pIOStdReq;
- begin
- CreateStdIO := pIOStdReq(CreateExtIO(port, sizeof(tIOStdReq)))
- end;
-
-
- procedure DeleteStdIO (ioReq: pIOStdReq);
- begin
- DeleteExtIO(pIORequest(ioReq))
- end;
-
-
- function CreatePort (name: STRPTR; pri: integer): pMsgPort;
- var port: pMsgPort; sigbit: shortint;
- begin
- CreatePort := NIL;
- sigbit := AllocSignal(-1);
- if sigbit <> -1 then
- begin
- port := AllocMem(sizeof(tMsgPort), MEMF_CLEAR or MEMF_PUBLIC);
- if port = NIL then
- FreeSignal(sigbit)
- else
- with port^, mp_Node do
- begin
- ln_Name := name;
- ln_Pri := pri;
- ln_Type := NT_MSGPORT;
-
- mp_Flags := PA_SIGNAL;
- mp_SigBit := sigbit;
- mp_SigTask := FindTask(NIL);
-
- if name <> NIL then
- AddPort(port)
- else
- NewList(@mp_MsgList);
- CreatePort := port
- end
- end
- end;
-
-
- procedure DeletePort (port: pMsgPort);
- begin
- with port^, mp_MsgList do
- begin
- if mp_Node.ln_Name <> NIL then
- RemPort(port);
-
- mp_SigTask := pTask(-1);
- lh_Head := pNode(-1);
- FreeSignal(mp_SigBit);
- FreeMem_(port, sizeof(tMsgPort))
- end
- end;
-
-
- function CreateTask (name: STRPTR; pri: longint;
- initPC: pointer; stackSize: longint): pTask;
- type
- mementrynum = (ME_TASK, ME_STACK, NUMENTRIES);
- pfakememlist = ^tfakememlist;
- tfakememlist = record
- list: tMemList;
- entry: array [ME_TASK..ME_STACK] of tMemEntry;
- end;
- var
- fakememlist: tfakememlist;
- ml: pfakememlist;
- newtask: pTask;
- namelen: integer;
-
- begin
- CreateTask := NIL;
- stacksize := (stacksize + 3) and not 3;
-
- {allocate the memory}
- with fakememlist, list do
- begin
- FillChar(ml_Node, sizeof(ml), 0);
- ml_NumEntries := integer(NUMENTRIES);
- entry[ME_TASK].me_Reqs := MEMF_PUBLIC | MEMF_CLEAR;
- entry[ME_TASK].me_Length := sizeof(tTask);
- entry[ME_STACK].me_Reqs := 0;
- entry[ME_STACK].me_Length := stacksize;
-
- ml := pfakememlist(AllocEntry(@list));
- if ml = NIL then exit;
-
- newtask := pTask(ml^.entry[ME_TASK].me_Addr)
- end;
-
- {initialise the task structure}
- with newtask^, tc_Node, ml^ do
- begin
- ln_Type := NT_TASK;
- ln_Pri := pri;
- ln_Name := name;
-
- tc_SPLower := entry[ME_STACK].me_Addr;
- tc_SPUpper := pointer(longint(tc_SPLower) + stacksize);
- tc_SPReg := tc_SPUpper;
-
- NewList(@tc_MemEntry);
- AddHead(@tc_MemEntry, pNode(ml))
- end;
-
- {add the task to the system}
- initpc := AddTask(newtask, initpc, NIL); {throw away result}
- CreateTask := newtask
- end;
-
-
- procedure DeleteTask (task: pTask);
- begin
- RemTask(task)
- end;
-
-
- procedure NewList (list: pList);
- begin
- with list^ do
- begin
- lh_Head := pNode(@lh_Tail);
- lh_Tail := NIL;
- lh_TailPred := pNode(@lh_Head)
- end
- end;
-
-
- (* Graphics support *)
- procedure ttskasm; xassembler;
- asm
- move.l d2,-(sp)
- move.l tIsrvstr.ccode(a1),a0
- move.l tIsrvstr.Carg(a1),-(sp)
- jsr (a0)
- move.l (sp)+,d2
- moveq #0,d0
- end;
-
-
- procedure AddTOF (i: pIsrvstr; p: pointer; a: longint);
- begin
- { note: TOF interrupt routines should be procedures }
- { and should accept a single longint parameter }
- with i^ do
- begin
- Iptr := i;
- code := @ttskasm;
- ccode := p;
- Carg := a
- end;
- AddintServer(INTB_VERTB, pinterrupt(i))
- end;
-
-
- procedure RemTOF (i: pIsrvstr);
- begin
- RemintServer(INTB_VERTB, pinterrupt(i))
- end;
-
-
- (* AmigaDOS support *)
- function DOSPacket (pid: pMsgPort; action: longint;
- var args; nargs: integer): longint;
- var
- replyport: pMsgPort; packet: pStandardPacket; i: integer; junkp: pointer;
-
- begin
- DOSPacket := 0;
- replyport := CreatePort(NIL, 0);
- if replyport <> NIL then
- begin
- packet := AllocMem(sizeof(tStandardPacket), MEMF_CLEAR or MEMF_PUBLIC);
- if packet <> NIL then
- begin
- with packet^, sp_Pkt do
- begin
- sp_Msg.mn_node.ln_Name := @sp_Pkt;
- dp_Link := @sp_Msg;
- dp_port := replyport;
- dp_type := action;
- Move(args, dp_Arg1, nargs * sizeof(longint));
- PutMsg(pid, @sp_Msg);
- junkp := WaitPort(replyPort);
- DOSPacket := dp_res1
- end;
- FreeMem_(packet, sizeof(tStandardPacket))
- end;
- DeletePort(replyport)
- end
- end;
-
-
- (* Timer support *)
- procedure DoTimer_; xassembler;
- asm
- movem.l d2-d3/a2-a4/a6,-(sp)
- move.l SysBase,a6
- move.l a0,a4
- move.l d0,d2
- move.l d1,d3
- lea -$4A(sp),sp
- move.l sp,a3
- lea $28(a3),a2
- move.b #4,8(a2)
- clr.b 9(a2)
- clr.l $A(a2)
- clr.b $E(a2)
-
- moveq #-1,d0
- jsr -$14A(a6) { AllocSignal }
- cmp.b #$FF,d0
- beq @3
- move.b d0,$F(a2)
- sub.l a1,a1
- jsr -$126(a6) { FindTask }
- move.l d0,$10(a2)
- lea $14(a2),a0
- move.l a0,8(a0)
- addq.l #4,a0
- clr.l (a0)
- move.l a0,-(a0)
-
- lea @4(pc),a0
- move.l a3,a1
- move.l d2,d0
- moveq #0,d1
- jsr -$1BC(a6) { OpenDevice }
- tst.l d0
- bne @2
-
- move.l a2,$E(a3)
- move.l a3,a1
- move.w d3,$1C(a1)
- move.l (a4),$20(a1)
- move.l 4(a4),$24(a1)
- jsr -$1C8(a6) { DoIO }
- move.l $20(a3),(a4)
- move.l $24(a3),4(a4)
-
- move.l a3,a1
- jsr -$1C2(a6) { CloseDevice }
- moveq #0,d0
- move.b $F(a2),d0 { FreeSignal }
- jsr -$150(a6)
- bra @1
-
- @4:
- dc.b 'timer.device',0
-
- @2:
- moveq #0,d0
- move.b $F(a2),d0
- jsr -$150(a6) { FreeSignal }
- @3:
- moveq #-1,d0
- @1:
- lea $4A(sp),sp
- movem.l (sp)+,d2-d3/a2-a4/a6
- end;
-
-
- function TimeDelay (unit_: longint;
- secs, microsecs: long): longint; assembler;
- asm
- move.l unit_,d0
- moveq #TR_ADDREQUEST,d1
- move.l microsecs,-(sp)
- move.l secs,-(sp)
- move.l sp,a0
- jsr DoTimer_
- move.l d0,@result
- addq.l #8,sp
- end;
-
-
- (* BOOPSI support *)
- {$ifdef WORKBENCH_2}
- function CallHookA (hook: pHook;
- object, paramPacket: pointer): long; xassembler;
- asm
- move.l a2,-(sp)
- lea $C(sp),a0
- move.l (a0)+,a1
- move.l (a0)+,a2
- move.l (a0),a0
- pea @2(pc)
- move.l tHook.h_SubEntry(a0),-(sp)
- rts
- @2:
- move.l (sp)+,a2
- move.l d0,16(sp)
- end;
-
-
- procedure HookEntry (hook: pHook;
- object, paramPacket: pointer); xassembler;
- asm
- subq.l #4,sp
- move.l a0,-(sp)
- move.l a2,-(sp)
- move.l a1,-(sp)
- move.l tHook.h_SubEntry(a0),a0
- jsr (a0)
- move.l (sp)+,d0
- end;
-
-
- function DoMethodA (obj: pointer; message: pMsg): long; xassembler;
- asm
- move.l a2,-(sp)
- move.l 12(sp),a2 { object }
- move.l a2,d0
- beq @2
- move.l 8(sp),a1 { message }
- move.l -4(a2),a0 { class ptr precedes object }
-
- pea @2(pc)
- move.l tHook.h_Entry(a0),-(sp)
- rts
- @2:
- move.l (sp)+,a2
- move.l d0,12(sp)
- end;
-
-
- function DoSuperMethodA (cl, obj: pointer;
- message: pMsg): long; xassembler;
- asm
- move.l a2,-(sp)
- movem.l 8(sp),a1-a2 { message, object }
- move.l a2,d0
- beq @2
- move.l 16(sp),d0 { class }
- beq @2
- move.l d0,a0
- move.l tIClass.cl_Super(a0),a0
-
- pea @2(pc)
- move.l tHook.h_Entry(a0),-(sp)
- rts
- @2:
- move.l (sp)+,a2
- move.l d0,16(sp)
- end;
-
-
- function CoerceMethodA (cl, obj: pointer;
- message: pMsg): long; xassembler;
- asm
- move.l a2,-(sp)
- movem.l 8(sp),a1-a2 { message, object }
- move.l a2,d0
- beq @2
- move.l 16(sp),d0 { class }
- beq @2
- move.l d0,a0
-
- pea @2(pc)
- move.l tHook.h_Entry(a0),-(sp)
- rts
- @2:
- move.l (sp)+,a2
- move.l d0,16(sp)
- end;
- {$endif}
-
- end.
-