用意したもの
  • Neko Project 21/W
  • MS-DOS 6.2
  • Windows 3.1
  • MASM32
  • MASM611


IBM PC互換機であればMASM61のsamples/winclockをビルドすれば参考になるはず。
PC-98だとml.exeがDOSエクステンダを使用していてA20制御の機種依存により以下のエラーが出る。

Phar Lap err 33: Can't enable address line 20.

そこでMASM32を使用し、MASM61から必要なファイルを補う方法を採用する。

MASM61の展開

PC-98ではsetupできないがdecomp.exeでファイルの解凍は可能。
packing.txtからバッチファイルを作ってもいい。

以下、samples/winclockを参考にしたMessageBoxプログラムの作成例。

dev.bat
@echo off
path %path%;C:\masm32\bin
cmd
 

masm61\libからappentry.asm、libw.libを作業ディレクトリにコピーする。
masm61\includeのwin.incを使うとエラーになるが、2400行のmmをmm_などにすれば利用可能。

+ appentry.asm
;-----------------------------------------------------------------------------;
; APPENTRY.ASM :Windows Application Startup Routine
;-----------------------------------------------------------------------------;
; From Microsoft Windows Software Developers Kit (c) Microsoft
; Chapter 22: Windows Application Startup
;-----------------------------------------------------------------------------;
;
; To create a Windows application, the WinMain function has to be called
; by some startup code contained in the executable file. This startup code is 
; in the APPENTRY.ASM file. Since INVOKE directives depend on the memory model
; in use, APPENTRY.ASM expects MODEL to be set with the memory model of
; the application. APPENTRY.OBJ is then created from APPENTRY.ASM.
;
; for example:    ml -c -DMODEL=small appentry.asm
; 
; In the link line, APPENTRY.OBJ has to be the first file in the chain,
; because the first 16 bytes of data in the DATA segment are reserved by 
; Windows. A run file name has to be specified to the linker, otherwise
; the linker will create an APPENTRY.EXE executable.
;
; for example:	link  appentry+winapp,winapp.exe,,libw,winapp
;
; For PWB, this amounts to selecting APPENTRY.ASM as the first entry in the
; list (put APPENTRY.ASM at the Top of List)
; Since MODEL is required, an IFNDEF handles the case in which it isn't
; defined, outputting an error and avoiding assembly of the rest.
;
;-----------------------------------------------------------------------------;
 
 
IFNDEF MODEL
	.ERR <MODEL hasn't been defined>
	EXTERNDEF  __astart:PROC
ELSE
	.model MODEL, pascal            ; set model to MODEL, language
					; to pascal (as required by Windows)
					; MODEL should be defined in ML
					; command line
 
; Numeric Equates
 
STACKSLOP = 256                         ; amount of stack slop space required
maxRsrvPtrs = 5                         ; number of Windows reserved pointers
 
; External/Public definitions
 
EXTERNDEF       rsrvptrs:WORD           ; pointers to Windows reserved pointers
PUBLIC          __astart                ; application startup routine
 
; Type definitions for functions used. 
; Faster and more efficient than including 'windows.inc'
 
UINT            TYPEDEF WORD
HINSTANCE       TYPEDEF UINT
HTASK           TYPEDEF UINT
LPSTR           TYPEDEF FAR PTR BYTE
 
 
; Prototypes for functions used
 
Dos3Call        PROTO FAR PASCAL
InitApp         PROTO FAR PASCAL,       :HTASK
WaitEvent       PROTO FAR PASCAL,       :HINSTANCE
InitTask        PROTO FAR PASCAL
WinMain         PROTO NEAR PASCAL,      :HINSTANCE, :HINSTANCE, :LPSTR, :UINT
 
	.data
 
	 DWORD  0                       ; Windows reserved data space.
rsrvptrs WORD   maxRsrvPtrs             ; 16 bytes at the top of the DATA seg.
	 WORD   maxRsrvPtrs DUP (0)     ; Do not alter
 
hPrev    WORD    0                      ; space to save WinMain parameters
hInst    WORD    0
lpszCmd  DWORD   0
cmdShow  WORD    0
 
	.code
 
__astart:
	xor bp,bp                       ; zero bp
	push bp
	INVOKE InitTask                 ; Initialize the stack
	or ax,ax
	jz noinit
	add cx,STACKSLOP                ; Add in stack slop space.
	jc noinit                       ; If overflow, return error.
	mov hPrev,si
	mov hInst,di
	mov word ptr lpszCmd,bx
	mov word ptr lpszCmd+2,es
	mov cmdShow,dx
	xor ax,ax                       ; Clear initial event that
	INVOKE WaitEvent, ax            ;   started this task.
	INVOKE InitApp, hInst           ; Initialize the queue.
	or ax,ax
	jz noinit
 
	INVOKE WinMain, hInst,hPrev,lpszCmd,cmdShow
ix:
	mov ah,4Ch
	INVOKE Dos3Call                 ; Exit with return code from app.
noinit:
	mov al,0FFh                     ; Exit with error code.
	jmp short ix
 
ENDIF                                   ; End of IFNDEF MODEL
 
	end __astart                    ; start address
 

ml /c /DMODEL=small appentry.asm

msgbox16.asm
.model	small, pascal, nearstack
.286
 
; include win.inc するとエラーが発生するので抜粋
UINT		TYPEDEF		WORD
NULL		EQU		0t
LPSTR		TYPEDEF		FAR PTR SBYTE
LPCSTR		TYPEDEF		FAR PTR SBYTE
HANDLE		TYPEDEF		UINT
HWND		TYPEDEF		UINT
@proto_583		TYPEDEF		PROTO FAR PASCAL :HWND, :LPCSTR, :LPCSTR, :UINT
MessageBox		PROTO		@proto_583
MB_OK		EQU		000000000h
 
extern __astart:proc
 
		.const
 
appname		sbyte	"msgbox16", 0
msg		sbyte	"hello, world", 0
 
		.code
 
WinMain		proc, hInstance:HANDLE, hPrevInstance:HANDLE, lpszCmdLine:LPSTR, nCmdShow:SWORD
 
		invoke	MessageBox, NULL, addr msg, addr appname, MB_OK
		mov	al, 0
		ret
 
WinMain		endp
 
		end
 

msgbox16.def
name		msgbox
 
exetype		windows 3.1
 
;stub		'winstub.exe'
 
code		preload moveable
data		preload moveable multiple
 
heapsize	1024
stacksize	5120
 
exports
 

ml /c msgbox16.asm

link16 msgbox16+appentry, , , libw, msgbox16

モジュール定義ファイル(.def)なしでも若干内容は変わるがリンク可能。

link16 /st:5120 msgbox16 appentry, , , libw;

DiskExplorer等でmsgbox16.exeをPC-98にコピーし、Windows 3.1から実行する。

最終更新:2018年09月04日 06:08
添付ファイル