page , 132 title PL/M Application Startup Code subttl Copyright (c) 2011-2012,2018-2024, the ACME Software Deli ; ============================================================================ ; This program is distributed in the hope that it will be useful, but ; WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE ; ; Permission to use for any purpose, modify, copy, and make enhancements ; and derivative works of the software is granted if attribution is given to ; R.M. Gillmore, dba the ACME Software Deli, as the author ; ; While the ACME Software Deli does not work for money, there is nonetheless a ; a significant amount of work involved. The ACME Software Deli maintains the ; rights to all code written, though it may be used and distributed as long as ; the following conditions are maintained. ; ; 1. The copyright statement at the top of each code block is maintained in ; your distribution. ; 2. You do not identify yourself as the ACME Software Deli ; 3. Any changes made to the software are sent to the ACME Software Deli ; ============================================================================ page name asmStartModule .186 ; _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*-_ ; the segments are in this order for good reason. if the order is changed, ; there is a real good chance that it will break lots of applications ; ; the segment/group order MUST be: ; 'Const' ; 'Code' ; 'Data' ; 'Stack' ; 'Memory' ; _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*- _-*-_ plmLibrary_Const segment 'Const' plmLibrary_Const ends plmLibrary_Code segment public 'Code' db '@(#)DOS Library Copyright (c) 2011-2012,2018-2024, the ACME Software Deli', 0 modMemFailed db 'Unable to modify memory block at startup. error: ', 0 ifndef SMALL db '@(#)asmStart.a86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 endif plmLibrary_Code ends protectedData segment public 'Data' protectedData ends plmLibrary_Data segment public 'Data' plmLibrary_Data ends stack segment public 'Stack' stack ends memory segment public 'Memory' ; org 0 ;memoryVariable label word memory ends extrn plmStart:far extrn printStringAsciiZ:far extrn wordToHexString:far extrn initializeDataArea:far extrn storePSP:far extrn getPSP:far extrn exit:far plmLibrary_CGroup group plmLibrary_Code plmLibrary_DGroup group plmLibrary_Data plmLibrary_Code segment public 'Code' assume Cs:plmLibrary_CGroup DOS equ 21h FATAL_ERROR equ 2 ; -------------------------------------------------------------------------------- ; Function: Start ; ; This is first code executed when the Operating System (DOS) turns control over ; to the application. These are the high-level steps taken for every application ; ; * Capture the current context, storing for possible use at a later time ; * Release memory that the application is not using ; * Initialize the memory segments in the Data category ; * Turn control to the command line and environment parsers who will ; then turn control to the core of the application's functionality ; -------------------------------------------------------------------------------- public asmStart asmStart proc far call storePSP modifyMemBlock: ; determine how much conventional memory the application really needs, ; and free the remainder (this should allow the DOS memory allocation ; to work as defined) ; adjust the stack to 64k bytes, then set the stack ptr to the top of ; that stack ( that will mean that we will need to adjust the and of ; available memory manually ) mov Sp, 0 ; we want a maximum stack segment mov Bx, Ss add Bx, 1000h ; adjusted location of the Memory segment ; calculate the size of the memory block to be modified ; now we will determine the number of paragraphs to keep mov Dx, Es ; the first segment (the PSP) sub Bx, Dx ; BX will contain the number of paragraphs ; occupied by the current application add Bx, 10h ; allow room for DOS MCB stc ; in order to sense the clearing of the carry ; flag, it must first be set mov Ax, 4a00h ; modify memory block size int DOS jnc memBlockModified ; when we get to this block, there has been an error attempting to release ; RAM that we are not using ; report the error to the console to be seen (the error code is in AX, so ; take care to preserve it) push Ax ; save the error code mov Ax, plmLibrary_DGroup mov Ds, Ax assume Ds:plmLibrary_DGroup mov Bx, seg modMemFailed push Bx lea Bx, modMemFailed push Bx call printStringAsciiZ add sp, 4 ; adjust stack pointer by the number of words ; pushed on the stack mov Ax, plmLibrary_DGroup ; restore the data segment mov Ds, Ax pop Ax ; retrieve the error code jmp short leaveApplication memBlockModified: mov Dx, plmLibrary_data ; put the first data segment into DX push Dx call initializeDataArea add sp, 2 ; recover the parameter stack area ; get the address of the program segment prefix and call the startup code call getPSP push Dx ; save the PSP address as argument push Ax ; to plmStart() call plmStart add sp, 4 ; two registers were pushed for the call leaveApplication: push ax call exit asmStart endp plmLibrary_Code ends end asmStart