FAQ007 = How do you write/access ASM code in QBasic?
This program (copy and save as BAS file) contain a set of routines used for EMS support which you can add to your RPG game or other QB program.
The routines are briefly explained in the source code, but I'll give you some more explaination here.
Most important functions:
SUB AsmPrepare
- This function reads and prepares all assembly routines in the data statements
- Data statements begin with a number which must be unique for every routine. All Functions that use CALL ABSOLUTE use this number to identify their own assembly routine. A number of '-1' tells AsmPrepare there are no more routines.
FUNCTION EmsInstalled
>>> Checks if EMS is supported.
- Returns zero if EMS is supported and ready to use
- Returns nonzero if there is a problem
FUNCTION EmsPageFrameSegment (PageFrameSeg)
- Fills PageFrameSeg with the current 'EMS Page Frame Segment'
>>> This Segment must be read once. The Segment is used to copy data to or from the EMS.
- Returns nonzero if there is a problem
FUNCTION EmsAllocate (NumPages, Handle)
- Creates a EMS handle. The handle is returned in Handle
- It Allocates NumPages EMS pages and assignes it to the handle (A page is 16384 bytes)
>>> This Handle must be kept for use with other EMS function. A program can use multiple pieces of EMS by using multiple handles. A program can, by example, store graphics in one EMS handle and an array of variables in another.
- Returns nonzero if there is a problem
FUNCTION EmsRelease (Handle)
- Releases EMS memory assighed to the Handle and destroys the Handle
>>> This function must be called for every handle you have created with FUNCTION EmsAllocate.
- Returns nonzero if there is a problem
FUNCTION EmsMap (Handle, Page, NumPages)
>>> This function assignes up to 4 EMS pages to physical pages in the base memory at the EMS Page Frame Segment. (see FUNCTION EmsPageFrameSegment)
- Handle identifies which EMS handle is used to map memory to.
- Page must contain the first page of the handle which is mapped to the base memory.
>>> After the call, the bytes in this page are accessible from EmsPageFrameSegment:0000 to EmsPageFrameSegment:3FFF
- NumPages must contain the number of pages that are sequentionally assigned to the base memory.
>>> Data in the pages after the selected page are accessible from from EmsPageFrameSegment:4000 to EmsPageFrameSegment:7FFF, EmsPageFrameSegment:8000 to EmsPageFrameSegment:BFFF and EmsPageFrameSegment:C000 to EmsPageFrameSegment:FFFF. Assigning multiple pages creates a continuous range consisting of the seperate ranges.
- Returns nonzero if there is a problem
Less important functions:
FUNCTION EmsPages (TotalPages, AvailablePages)
- Fills TotalPages with the number of free EMS pages
- Fills AvailablePages with the number of available EMS pages
>>> AvailablePages will often clip at 1024. If in this case if AvailablePages is 1024 it means there are more free pages.
- Returns nonzero if there is a problem
FUNCTION EmsNumHandles (NumHandles)
- Fills NumHandles with the current number of EMS handles in use by QB and your program (or the peogram only if it's compiled).
- Returns nonzero if there is a problem
FUNCTION EmsNumPages (Handle, NumPages)
- Fills NumPages with the number of pages that are assigned to the Handle using EmsAllocate
- Returns nonzero if there is a problem
DEFINT A-Z
DIM SHARED AsmString(9) AS STRING * 50, AsmPointer(9), AsmSegment(9)
AsmPrepare
'
'Your code here
'
END
MemCopyAsmData:
DATA 0,1E8B760C8B460A8EC08B7E088B4E068B460E8ED8F3A41F
EmsInstalledAsmData:
DATA 1,B440CD67B0008B7E068905
EmsPageFrameSegmentAsmData:
DATA 2,B441CD67B0008B7E0689058B7E08891D
EmsPagesAsmData:
DATA 3,B442CD67B0008B7E0689058B7E0A89158B7E08891D
EmsAllocateAsmData:
DATA 4,8B5E0AB443CD67B0008B7E0689058B7E088915
EmsReleaseAsmData:
DATA 5,B4458B5606CD67
EmsNumPagesAsmData:
DATA 6,8B560AB44CCD67B0008B7E0689058B7E08891D
EmsMapAsmData:
DATA 7,8B560C8B5E0A8B4E0830C0B444CD6780FC007507FEC043E2F2B00030C08B7E068905
EmsNumHandlesAsmData:
DATA 8,B44BCD6730C08B7E0689058B7E08891D
DATA -1
SUB AsmPrepare STATIC
DO
READ Number
IF Number = -1 THEN EXIT SUB
FOR a = 0 TO asmbytes - 1
POKE AsmPointer(Number) + a, VAL("&h" + MID$(AsmHex$, a * 2 + 1, 2))
NEXT
LOOP
END SUB
'Create a handle and allocate EMS pages to the handle
'
'MOV BX,[BP+0A] ;NumPages
'MOV AH,43
'INT 67
'MOV AL,00
'MOV DI,[BP+06] ;Status
'MOV [DI],AX
'MOV DI,[BP+08] ;Handle
'MOV [DI],DX
'
'IN: WORD number of logical pages to allocate
'OUT: WORD handle if successfull
'
FUNCTION EmsAllocate (NumPages, Handle) STATIC
RESTORE EmsAllocateAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(BYVAL NumPages, Handle, Status, AsmPointer(Number))
EmsAllocate = Status
END FUNCTION
'Get EMS manager status
'
'MOV AH,40
'INT 67
'MOV AL,00
'MOV BX,[BP+06] ;Status
'MOV [BX],AX
'
FUNCTION EmsInstalled STATIC
RESTORE EmsInstalledAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(Status, AsmPointer(Number))
EmsInstalled = Status
END FUNCTION
'Assign up to 4 EMS pages to the EMS page frame segment.
'
'MOV DX,[BP+0C] ;Handle
'MOV BX,[BP+0A] ;Page
'MOV CX,[BP+08] ;NumPages
'XOR AL,AL
';000B
'MOV AH,44
'INT 67
'CMP AH,00
'JNZ 001B
'INC AL
'INC BX
'LOOP 000B
'MOV AL,00
';001B
'MOV DI,[BP+06] ;Status
'MOV [DI],AX
'
'IN: WORD handle
' WORD logical page number or FFFFh to unmap (QEMM)
' WORD number of physical pages (1-4)
'
FUNCTION EmsMap (Handle, Page, NumPages) STATIC
RESTORE EmsMapAsmData
READ Number
a = NumPages
IF a > 4 THEN a = 4
IF a < 1 THEN a = 1
DEF SEG = AsmSegment(Number)
CALL Absolute(BYVAL Handle, BYVAL Page, BYVAL a, Status, AsmPointer(Number))
EmsMap = Status
END FUNCTION
'Get number of handles in use of the program
'
'MOV AH,4B
'INT 67
'MOV DI,[BP+06] ;Status
'MOV [DI],AX
'MOV DI,[BP+08] ;NumHandles
'MOV [DI],BX
'
'OUT: WORD number of handles
'
FUNCTION EmsNumHandles (NumHandles) STATIC
RESTORE EmsNumHandlesAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(NumHandles, Status, AsmPointer(Number))
EmsNumHandles = Status
END FUNCTION
'Get pages owned by a handle
'
'MOV DX,[BP+0A]
'MOV AH,4C
'INT 67
'MOV AL,00
'MOV DI,[BP+06]
'MOV [DI],AX
'MOV DI,[BP+08]
'MOV [DI],BX
'
'IN: WORD handle
'OUT: WORD number of logical pages
'
FUNCTION EmsNumPages (Handle, NumPages) STATIC
RESTORE EmsNumPagesAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(BYVAL Handle, NumPages, Status, AsmPointer(Number))
EmsNumPages = Status
END FUNCTION
'Get the page frame segment
'
'MOV AH,41
'INT 67
'MOV AL,00
'MOV DI,[BP+06] ;Status
'MOV [DI],AX
'MOV DI,[BP+08] ;PageFrameSeg
'MOV [DI],BX
'
'OUT: WORD segment of page frame
'
FUNCTION EmsPageFrameSegment (PageFrameSeg) STATIC
RESTORE EmsPageFrameSegmentAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(PageFrameSeg, Status, AsmPointer(Number))
EmsPageFrameSegment = Status
END FUNCTION
'Get the total and free number of EMS pages
'
'MOV AH,42
'INT 67
'MOV AL,00
'MOV DI,[BP+06] ;Status
'MOV [DI],AX
'MOV DI,[BP+08] ;AvailablePages
'MOV [DI],BX
'MOV DI,[BP+0A] ;TotalPages
'MOV [DI],DX
'
'OUT: WORD number of unallocated pages
' WORD total number of pages
'
FUNCTION EmsPages (TotalPages, AvailablePages) STATIC
RESTORE EmsPagesAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(TotalPages, AvailablePages, Status, AsmPointer(Number))
EmsPages = Status
END FUNCTION
'Discard a handle and Release memory
'
'MOV AH,45
'MOV DX,[BP+06] ;Handle
'INT 67
'
'IN: WORD handle
'
SUB EmsRelease (Handle) STATIC
RESTORE EmsReleaseAsmData
READ Number
DEF SEG = AsmSegment(Number)
CALL Absolute(BYVAL Handle, AsmPointer(Number))
END SUB
'Copy in memory
'
'PUSH DS
'MOV SI,[BP+0C] ;SrcPtr
'MOV AX,[BP+0A] ;DstSeg
'MOV ES,AX
'MOV DI,[BP+08] ;DstPtr
'MOV CX,[BP+06] ;NumBytes
'MOV AX,[BP+0E] ;SrcSeg
'MOV DS,AX
'REPZ
'MOVSB
'POP DS
'
'IN: WORD Source segment
' WORD Source pointer
' WORD Destination segment
' WORD Destination pointer
' WORD Number of bytes to copy
'
SUB MemCopy (SrcSeg, SrcPtr, DstSeg, DstPtr, NumBytes&) STATIC
RESTORE MemCopyAsmData
READ Number
IF NumBytes& > 32767 THEN
a = NumBytes& - 65536
ELSE
a = NumBytes&
END IF
DEF SEG = AsmSegment(Number)
CALL Absolute(BYVAL SrcSeg, BYVAL SrcPtr, BYVAL DstSeg, BYVAL DstPtr, BYVAL a, AsmPointer(Number))
END SUB
This message has been edited by iorr5t on Oct 30, 2003 12:40 PM