From 9aa45cffcf09689f6428cc0554140b2f020d8fc1 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Tue, 31 Jul 2018 08:28:21 -0700 Subject: [PATCH] more --- tool/linker/ex9/buildall.sh | 24 +++++++ tool/linker/ex9/code32.asm | 19 ++++++ tool/linker/ex9/common.mak | 84 +++++++++++++++++++++++++ tool/linker/ex9/drvc.c | 42 +++++++++++++ tool/linker/ex9/entry.asm | 121 ++++++++++++++++++++++++++++++++++++ tool/linker/ex9/entry2.asm | 5 ++ tool/linker/ex9/make.sh | 41 ++++++++++++ 7 files changed, 336 insertions(+) create mode 100755 tool/linker/ex9/buildall.sh create mode 100644 tool/linker/ex9/code32.asm create mode 100644 tool/linker/ex9/common.mak create mode 100644 tool/linker/ex9/drvc.c create mode 100644 tool/linker/ex9/entry.asm create mode 100644 tool/linker/ex9/entry2.asm create mode 100755 tool/linker/ex9/make.sh diff --git a/tool/linker/ex9/buildall.sh b/tool/linker/ex9/buildall.sh new file mode 100755 index 000000000..2960cb58c --- /dev/null +++ b/tool/linker/ex9/buildall.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Unlike the DOS batch files, this script is much more powerful. +# In fact, this script BUILDs the DOS batch files. +# +# NTS: Make sure your editor uses unix LF endings in the file, +# but keeps the CR LF DOS endings for the DOS batch files. + +for i in *; do if [ -d "$i" ]; then + if [ -x "$i/buildall.sh" ]; then + cp -v -u buildall.sh "$i/buildall.sh" || exit 1 + fi + + (cd $i && ( + if [ -x buildall.sh ]; then + ./buildall.sh $* || exit 1 + fi + + if [ -x make.sh ]; then + ./make.sh $* || exit 1 + fi) + ) || exit 1 +fi; done + diff --git a/tool/linker/ex9/code32.asm b/tool/linker/ex9/code32.asm new file mode 100644 index 000000000..154c14150 --- /dev/null +++ b/tool/linker/ex9/code32.asm @@ -0,0 +1,19 @@ + +section _TEXT align=1 class=CODE use32 + +global entry_code32 +entry_code32: + mov eax,0x12345678 + mov esi,_ex_data32 + call function32 + +function32: + ret + +section _DATA align=1 class=DATA use32 + +global _ex_data32 +_ex_data32: + dd 0x89ABCDEF + db 'HELLO',0 + diff --git a/tool/linker/ex9/common.mak b/tool/linker/ex9/common.mak new file mode 100644 index 000000000..a57ce18a1 --- /dev/null +++ b/tool/linker/ex9/common.mak @@ -0,0 +1,84 @@ + +# TODO: OS/2 target: What can we #define to tell the header files which OS/2 +# environment we're doing? (Command prompt app. vs Presentation Manager app vs. +# "fullscreen" app.) + +# this makefile is included from all the dos*.mak files, do not use directly +# NTS: HPS is either \ (DOS) or / (Linux) + +CFLAGS_THIS = -fr=nul -fo=$(SUBDIR)$(HPS).obj -i=.. -i..$(HPS)..$(HPS).. -zl -s +NOW_BUILDING = TOOL_LINKER_EX1 + +!ifneq TARGET_MSDOS 32 +! ifdef TINYMODE +TEST_EXE = $(SUBDIR)$(HPS)test.com +DOSLIBLINKER_OFMT = -of com +! else +TEST_EXE = $(SUBDIR)$(HPS)test.exe +TESTW_EXE = $(SUBDIR)$(HPS)testw.exe +TESTF_EXE = $(SUBDIR)$(HPS)testf.exe +TESTFF_EXE = $(SUBDIR)$(HPS)testff.exe +TESTFC_EXE = $(SUBDIR)$(HPS)testfc.com +DOSLIBLINKER_OFMT = -of exe +! endif +!endif + +DOSLIBLINKER = ../linux-host/lnkdos16 + +$(DOSLIBLINKER): + make -C .. + +# NTS we have to construct the command line into tmp.cmd because for MS-DOS +# systems all arguments would exceed the pitiful 128 char command line limit +.C.OBJ: + %write tmp.cmd $(CFLAGS_THIS) $(CFLAGS_CON) $[@ + @$(CC) @tmp.cmd + +.ASM.OBJ: + nasm -o $@ -f obj $(NASMFLAGS) $[@ + +all: $(OMFSEGDG) lib exe + +exe: $(DOSLIBLINKER) $(TESTW_EXE) $(TEST_EXE) $(TESTF_EXE) $(TESTFF_EXE) $(TESTFC_EXE) .symbolic + +lib: .symbolic + +!ifdef TINYMODE +WLINK_NOCLIBS_SYSTEM = dos com +!else +WLINK_NOCLIBS_SYSTEM = $(WLINK_SYSTEM) +!endif + +!ifdef TESTW_EXE +$(TESTW_EXE): $(SUBDIR)$(HPS)entry.obj $(SUBDIR)$(HPS)drvc.obj $(SUBDIR)$(HPS)code32.obj + %write tmp.cmd option quiet OPTION NODEFAULTLIBS option map=$(TESTW_EXE).map system $(WLINK_NOCLIBS_SYSTEM) file $(SUBDIR)$(HPS)drvc.obj file $(SUBDIR)$(HPS)code32.obj file $(SUBDIR)$(HPS)entry.obj name $(TESTW_EXE) + @wlink @tmp.cmd + @$(COPY) ..$(HPS)..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe +!endif + +!ifdef TEST_EXE +$(TEST_EXE): $(SUBDIR)$(HPS)entry.obj $(SUBDIR)$(HPS)drvc.obj $(SUBDIR)$(HPS)code32.obj + $(DOSLIBLINKER) -i $(SUBDIR)$(HPS)drvc.obj -i $(SUBDIR)$(HPS)code32.obj -i $(SUBDIR)$(HPS)entry.obj -o $(TEST_EXE) $(DOSLIBLINKER_OFMT) -map $(TEST_EXE).map +!endif + +!ifdef TESTF_EXE +$(TESTF_EXE): $(SUBDIR)$(HPS)entry.obj $(SUBDIR)$(HPS)drvc.obj $(SUBDIR)$(HPS)code32.obj + $(DOSLIBLINKER) -i $(SUBDIR)$(HPS)drvc.obj -i $(SUBDIR)$(HPS)code32.obj -i $(SUBDIR)$(HPS)entry.obj -o $(TESTF_EXE) $(DOSLIBLINKER_OFMT) -pflat -map $(TESTF_EXE).map +!endif + +!ifdef TESTFF_EXE +$(TESTFF_EXE): $(SUBDIR)$(HPS)entry2.obj $(SUBDIR)$(HPS)drvc.obj $(SUBDIR)$(HPS)code32.obj + $(DOSLIBLINKER) -i $(SUBDIR)$(HPS)drvc.obj -i $(SUBDIR)$(HPS)code32.obj -i $(SUBDIR)$(HPS)entry2.obj -o $(TESTFF_EXE) $(DOSLIBLINKER_OFMT) -pflat -com100 -map $(TESTFF_EXE).map +!endif + +!ifdef TESTFC_EXE +$(TESTFC_EXE): $(SUBDIR)$(HPS)entry2.obj $(SUBDIR)$(HPS)drvc.obj $(SUBDIR)$(HPS)code32.obj + $(DOSLIBLINKER) -i $(SUBDIR)$(HPS)drvc.obj -i $(SUBDIR)$(HPS)code32.obj -i $(SUBDIR)$(HPS)entry2.obj -o $(TESTFC_EXE) -of comrel -pflat -map $(TESTFC_EXE).map +!endif + +clean: .SYMBOLIC + del $(SUBDIR)$(HPS)*.obj + del $(HW_DOS_LIB) + del tmp.cmd + @echo Cleaning done + diff --git a/tool/linker/ex9/drvc.c b/tool/linker/ex9/drvc.c new file mode 100644 index 000000000..de659388d --- /dev/null +++ b/tool/linker/ex9/drvc.c @@ -0,0 +1,42 @@ + +extern const char hellostr2[]; + +const char hello_world[] = "Hello world. This is code without a C runtime.\r\n"; +const char crlf[] = "\r\n"; + +void dos_putc(const char c); +#pragma aux dos_putc = \ + "mov ah,0x02" \ + "int 21h" \ + modify [ah] \ + parm [dl] + +void dos_puts(const char *p) { + char c; + + while ((c = *p++) != 0) + dos_putc(c); +} + +extern unsigned long ex_data32; + +unsigned int near entry_c(void) { + dos_puts(hello_world); + dos_puts(hellostr2); + + /* in code32.asm there is 32-bit code and data. + * test that we can access it relative to our 16-bit segment. + * the 32-bit code/data is linked together as if part of our 16-bit code and data. + * NTS: Open Watcom's Linker WILL NOT link this test properly, this test will fail. */ + if (ex_data32 == 0x89ABCDEF) { + dos_puts("EX_DATA32 YES\nEX_DATA32 string: "); + dos_puts((const char *)(&ex_data32) + 4ul); + dos_puts(crlf); + } + else { + dos_puts("EX_DATA32 NO"); + } + + return 0; +} + diff --git a/tool/linker/ex9/entry.asm b/tool/linker/ex9/entry.asm new file mode 100644 index 000000000..7700cf43a --- /dev/null +++ b/tool/linker/ex9/entry.asm @@ -0,0 +1,121 @@ +; auto-generated code, do not edit +%ifidni segment_use,use32 +bits 32 ; 32-bit real mode +%else +bits 16 ; 16-bit real mode +%endif + +; code +%ifidni segment_use,use32 +section _TEXT align=1 class=CODE use32 +%else + %ifidni segment_use,use16 +segment _TEXT align=1 class=CODE use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +..start: +global asm_entry +asm_entry: + +extern entry_c_ + +%ifndef TINYMODE + mov ax,_DATA + mov ds,ax +%else + ; the DOSLIB linker can properly link .com executables +%endif + +; unsigned int near entry_c(void) + call entry_c_ + +global _exit_ +_exit_: + mov ah,4Ch + int 21h + +; comrel. +; recent versions of the linker allow us to re-define the location of the COMREL fixup code +%ifidni segment_use,use32 +section __COMREL_RELOC align=4 class=CODE use32 +%else + %ifidni segment_use,use16 +segment __COMREL_RELOC align=4 class=CODE use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +; the linker SHOULD append it's COMREL table + code after any data we insert here +global dummy_junk +dummy_junk: + dw 0x1234 + db 'The linker should put COMREL code right after this string.',0 + +; comrel. +; recent versions of the linker allow us to re-define the location of the COMREL fixup code +%ifidni segment_use,use32 +section __COMREL_RELOCTBL align=4 class=CODE use32 +%else + %ifidni segment_use,use16 +segment __COMREL_RELOCTBL align=4 class=CODE use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +; the linker SHOULD append it's COMREL table + code after any data we insert here +global dummy_junk2 +dummy_junk2: + dw 0xABCD + db 'The linker should put COMREL table right after this string.',0 + +; data +%ifidni segment_use,use32 +section _DATA align=1 class=DATA use32 +%else + %ifidni segment_use,use16 +segment _DATA align=1 class=DATA use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +global _hellostr2 +_hellostr2: + db 'Hello world from ASM',13,10,0 + +; stack +%ifidni segment_use,use32 +section _STACK align=4 class=STACK use32 +%else + %ifidni segment_use,use16 +segment _STACK align=4 class=STACK use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +; stack +%ifidni segment_use,use32 +section _BSS align=4 class=BSS use32 +%else + %ifidni segment_use,use16 +segment _BSS align=4 class=BSS use16 + %else + %error unknown or undefined segment_use + %endif +%endif + +%ifdef TINYMODE +group DGROUP _DATA _TEXT _STACK __COMREL_RELOC +%else + %if TARGET_MSDOS == 32 +group DGROUP _DATA _STACK + %else +group DGROUP _DATA __COMREL_RELOC + %endif +%endif diff --git a/tool/linker/ex9/entry2.asm b/tool/linker/ex9/entry2.asm new file mode 100644 index 000000000..9bd823ec3 --- /dev/null +++ b/tool/linker/ex9/entry2.asm @@ -0,0 +1,5 @@ + +%define TINYMODE + +%include "entry.asm" + diff --git a/tool/linker/ex9/make.sh b/tool/linker/ex9/make.sh new file mode 100755 index 000000000..2969d0884 --- /dev/null +++ b/tool/linker/ex9/make.sh @@ -0,0 +1,41 @@ +#!/usr/bin/bash +rel=../../.. +if [ x"$TOP" == x ]; then TOP=`pwd`/$rel; fi +. $rel/linux-ow.sh + +dos=1 # MS-DOS +dostiny=1 # MS-DOS tiny model +#doshuge=1 # MS-DOS huge model +#dospc98=1 # MS-DOS PC-98 +#win30=1 # Windows 3.0 +#win31=1 # Windows 3.1 +#winnt=1 # Windows NT +#win32=1 # Windows 9x/NT/XP/Vista/etc. +#win32s=1 # Windows 3.1 + Win32s +#os216=1 # OS/2 16-bit 286 +#os232=1 # OS/2 32-bit 386 +#win386=1 +#win38631=1 + +if [ "$1" == "clean" ]; then + do_clean + rm -Rf linux-host + exit 0 +fi + +if [[ "$1" == "build" || "$1" == "" ]]; then + make_buildlist + begin_bat + + what=all + if [ x"$2" != x ]; then what="$2"; fi + if [ x"$3" != x ]; then build_list="$3"; fi + + for name in $build_list; do + do_wmake $name "$what" || exit 1 + bat_wmake $name "$what" || exit 1 + done + + end_bat +fi +