ANHANG A: .RUN PROGRAMM BEISPIEL
Abschnitt 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