===== ANHANG A: .RUN PROGRAMM BEISPIEL =====
Abschnitt [[hardware:doku:techrefguide:abschnitt3#run|3.6.3]] hebt die wichtigsten Entwicklungsbedingungen hervor, die zu berücksichtigen sind wenn man .RUN Programme schreibt.\\
Auf der Emulator-Diskette befinden sich folgende Dateien:\\
|RNRN.ASM|Assembler .RUN Programm|
|MAIN.C|C .RUN Programm Beispiel|
|RU_C.ASM|C Header|
|Build.BAT|Erzeugt Programm unter Verwendung von Turbo C Tools|
Die obigen Dateien illustrieren zwei Programme die Atari Portfolios .RUN Funktion verwenden.\\
RNRN ist ein Assemblerprogramm das die ursprünglichen Aufrufparameter und dann drei Zahlen ausgibt.\\
MAIN illustriert ein in C geschriebenes .RUN Programm. RU_C.ASM ist der nötige "C" Header für Borlands Turbo C Compiler und BUILD.BAT illustriert wie man das Programm mit Turbo C Tools erzeugt.\\
Bemerkungen bezüglich der Verbindung zwischen "C" Dateien und dem RUN Befehl:\\
Für "C" Dateien müssen wesentlich mehr Segmente deklariert werden damit "C" den Code und die Daten an die richtigen Stellen in der .RUN Datei bekommt. Die .COM Datei wird durch Umbenennung in eine .RUN Datei gewandelt.\\
RU_C.ASM ist der Header der für die Verbindung zu einem "C" Programm verwendet werden kann. Wenn "C" Quelldateien ohne die entsprechenden Bibliotheken verwendet werden, kann die Datei R_CU direkt als Header benutzt werden. Falls Code aus Bibliotheken nötig ist, so muss der Header um die nötigen Initialisierungen erweitert werden.\\
Der RU_C.ASM Header funktioniert mit Turbo C und kann als Leitfaden zur Modifikation anderer "C" Header verwendet werden, die bei den unterschiedlichen "C" Compliler Bibliotheken vorkommen.\\
Die meisten "C" Header die mit "C" Compilern geliefert werden können für verschiedene Speichermodelle assembliert werden. Der Beispiel-Code in RU_C.ASM muss in dem "C" Startup Header stehen und muss für SMALL model assembliert werden.\\
Kontaktieren sie Atari bezüglich RUN Startup Codes für die unterschiedlichen C Compiler.\\
\\
\\
\\
TITLE RNRN.ASM
comment *
(c) Copyright DIP, 1989
Example .RUN program
For Appendix 1 of DIP Pocket PC Technical Reference Manual
*
DGROUP group _text,_data,_cdata
STACKSIZE equ 400 ; byte in stack.
; code segment.
_text segment public byte 'CODE'
assume cs:_text,ds:_data
org 0 ; IP is 0 on entry.
;***********************************************************************;
; rnrn_main ;
; ;
; RUN command test routine. ;
; On entry, DS, SS and ES all point to the PSP in RAM. ;
; CS is a ptr into the credit card, so may actually be in ROM! ;
; When this routine is executed, the whole of RAM is allocated to the ;
; process. ;
; ;
; Parameters: ;
; None ;
; Returns: ;
; None ;
;***********************************************************************;
rnrn_main proc near
mov bx,10h ; 10h paras to keep the PSP.
mov ah,04ah ; modify memory.
int 21h
jc rnrn_err ; error reducing memory.
mov bx,OFFSET rnrn_uend ; alloc for initialised data,
sub bx,OFFSET rnrn_dstart ; uninitialised data and a
add bx,0fh ; stack.
mov cl,4
shr bx,cl ; calc paras in init data area.
add bx,STACKSIZE/16 ; add in paras in stack.
mov ah,48h ; allocate memory.
int 21h ; allocate stack and data.
jc rnrn_err ; no memory.
mov ss,ax ; set stack to point to RAM.
mov sp,OFFSET rnrn_uend+STACKSIZE
push es ; preserve PSP pointer.
mov cx,OFFSET rnrn_dend
sub cx,OFFSET rnrn_dstart ; bytes in initialised data.
mov si,OFFSET DGROUP:rnrn_dstart ; copy from here.
push cs
pop ds ; source is on memory card.
xor di,di
mov es,ax ; target is allocated RAM.
cld
rep movsb ; copy init data from card to RAM.
pop es ; restore PSP ptr.
mov si,5dh
mov cx,11
rnrn_fcb1:
mov dl,es:[si] ; get char from FCB built into PSP.
inc si
mov ah,2
int 21h ; print name of first parsed FCB.
loop rnrn_fcb1
mov si,6dh
mov cx,11
rnrn_fcb2:
mov dl,es:[si]
inc si
mov ah,2
int 21h ; print name of second parsed FCB.
loop rnrn_fcb2
push ss
pop ds ; DS is ptr to data in RAM.
mov al,_rnrn_val ; get initialised data.
call rnrn_disp ; display the value.
inc _rnrn_val
mov al,_rnrn_val ; get changed data.
call rnrn_disp ; display the value.
mov rnrn_unin,44 ; set a piece of uninitialised data.
mov al,rnrn_unin ; get uninitialised data.
call rnrn_disp ; display the value.
xor al,al ; return errorlevel of 0.
jmp short rnrn_end
rnrn_err:
mov dx,OFFSET DGROUP:rnrn_mem
push cs
pop ds ; write directly from ROM card!
mov ah,9 ; write string.
int 21h ; tell user there was memory error.
mov al,1 ; terminate with error code of 1.
rnrn_end:
push ax ; save errorlevel code in al.
mov ah,1 ; wait for a key.
int 21h
pop ax ; get errorlevel code back.
mov ah,4ch ; terminate process.
int 21h
rnrn_main endp
;***********************************************************************;
; rnrn_disp ;
; ;
; Display the value in AL with a trailing space. ;
; ;
; Parameters: ;
; AL Value to print, less than 100. ;
; Returns: ;
; None ;
;***********************************************************************;
rnrn_disp proc near
aam ; convert to two numbers.
add ax,3030h ; convert to ASCII digits '0'..'9'.
push ax ; save to print 2nd char.
mov dl,ah
mov ah,2 ; print 1st digit.
int 21h
pop dx
mov ah,2 ; print 2nd digit.
int 21h
mov dl,' '
mov ah,2 ; print a space.
int 21h
ret
rnrn_disp endp
_text ends
; initialised and uninitialised RAM data.
; this is para since the segment will start at zero when it is copied
; over into RAM.
_data segment public para 'data'
rnrn_dstart label byte
public _rnrn_val
_rnrn_val db 42
rnrn_dend label byte
rnrn_ustart label byte ; uninitialised data start.
rnrn_unin db ?
rnrn_uend label byte ; uninitialised data end.
; the stack is added on here, after initialised and uninitialised data.
_data ends
_cdata segment public byte 'data'
; initialised data which doesn't get transferred to RAM.
rnrn_mem db "Out of memory$"
_cdata ends
end rnrn_main
\\
\\
\\
\\
\\
\\
\\
/* MAIN.C
Copyright DIP Ltd, 1989
DIP Pocket PC RUN file 'C' interface main program.
*/
char buf[2]; /* this is BSS, unitialised. */
char *str="Hello world"; /* this is _DATA, initialised. */
unsigned int __brklvl; /* required by Turboc library. */
int main()
{
puts(str); /* print initialised hello. */
buf[0]='!'; /* initialise uninitialised data. */
buf[1]=0;
puts(&buf[0]); /* print uninitialised data. */
return(0);
}
void _exit()
/*
Dummy exit function required for the Turboc libraries.
*/
{}
\\
\\
\\
\\
\\
\\
\\
TITLE RU_C.ASM
comment *
Copyright DIP Ltd., 1989
'C' header for creation of DIP Pocket PC .RUN files.
Memory usage:
-------------------------------------------- High memory -------
SP: Stack
----------------------------------------------------------------
Uninitialised data
----------------------------------------------------------------
DS/SS: Initialised data
----------------------------------------------------------------
ES: PSP
-------------------------------------------- Low memory --------
*
; Segment and Group declarations
; code and fixed data (less than 64k).
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
; code ends (marker segment)
_TEXTEND SEGMENT BYTE PUBLIC 'CEND'
_TEXTEND ENDS
; initialised data transferred into RAM.
_DATA SEGMENT PARA PUBLIC 'DATA'
_DATA ENDS
; uninitialised data which is allocated space in RAM.
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
; uninitialised data end (marker segment).
_BSSEND SEGMENT BYTE PUBLIC 'STACK'
_BSSEND ENDS
DGROUP GROUP _DATA,_BSS,_BSSEND ; dgroup is all data segments.
ASSUME CS:_TEXT, DS:DGROUP
extrn _main:near ; main 'C' routine.
STACKSIZE equ 128 ; stack size in bytes.
; At the start, SS, DS and ES all point to the program segment prefix.
; CS is a ptr into the memory card.
_TEXT SEGMENT
org 0 ; ip is zero on entry.
start proc near ; near is irrelevant, use fn 4c to
; terminate.
mov dx,ds ; ensure DS:0 is ptr to 1st data byte.
add dx,10h
mov ds,dx
mov bx,STACKSIZE
add bx,offset DGROUP:edata ; bx has bytes of reqd RAM.
push bx ; this will be stack ptr.
shr bx,1
shr bx,1
shr bx,1
shr bx,1
add bx,11h ; 10h for PSP, 1 for rounding.
mov ah,4ah
int 21h ; reduce RAM to required RAM.
jc abort ; can't reduce.
pop bx ; get calc'd p back.
mov ax,ds
mov ss,ax ; stack is in RAM.
mov sp,bx
push ds
pop es ; target is allocated RAM after PSP.
push cs
pop ds ; source is memory card.
mov si, offset _TEXT:etext ; get ptr to last byte in code.
add si, 0Fh ; round up to 1st byte in data.
and si, 0FFF0h ; data is para aligned on the card.
; ds:si is ptr to start of init data.
xor di,di ; put data at 0 offs into alloc'd RAM.
; es:di is ptr to alloc'd RAM target.
mov cx, offset DGROUP:bdata ; get bytes in initialised data.
inc cx ; round up: ensure last byte is copied.
shr cx,1
cld
rep movsw ; copy init data from memory card.
push es
pop ds ; DS back to ptr to RAM.
mov di,offset DGROUP:bdata ; ptr to where uninit data goes in RAM.
mov cx,offset DGROUP:edata ; ptr to end of all data.
sub cx,di ; calc bytes in BSS.
xor al,al ; clear to zero.
rep stosb
call _main ; invoke program.
mov ah,4ch ; terminate with main's return code.
int 21h
abort:
mov ax,4c01h ; abort with error.
int 21h
start endp
_TEXT ENDS
_TEXTEND SEGMENT BYTE PUBLIC 'CEND'
etext label byte ;Last byte of text segment
_TEXTEND ENDS
_DATA SEGMENT
public _errno
_errno dw 0
_DATA ENDS
_BSS SEGMENT
bdata label byte
_BSS ENDS
_BSSEND SEGMENT
edata label byte
_BSSEND ENDS
end start