asm_dip/toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc
2024-11-24 23:13:28 -05:00

210 lines
4.5 KiB
PHP

MZ::
.signature dw "MZ"
.bytes_in_last_page dw .LENGTH and 1FFh
.number_of_pages dw (.LENGTH-1) shr 9 + 1
.number_of_relocations dw .NUMBER_OF_RELOCATIONS
.number_of_header_paragraphs dw .HEADER_LENGTH shr 4
.minimum_heap dw (.LENGTH+.RESERVED_LENGTH-1) shr 4 - (.LENGTH-1) shr 4
.maximum_heap dw 0FFFFh
.initial_ss dw 0
.initial_sp dw 0
.checksum dw 0
.initial_ip dw 0
.initial_cs dw 0
.relocations_offset dw .relocations
.overlay_number dw 0
.relocations dw .NUMBER_OF_RELOCATIONS dup (?,?)
rb 0Fh - ($%+0Fh) and 0Fh
.HEADER_LENGTH = $
.RELOCATION_INDEX = 0
.ENTRY_DEFINED = 0
.HEAP_DEFINED = 0
.STACK_DEFINED = 0
.STACK_LENGTH = 1000h
org 0
macro entry? definition
local v
if MZ.ENTRY_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_cs
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_ip
else
err 'value out of range'
end if
MZ.ENTRY_DEFINED = 1
else
err 'invalid argument'
end match
end macro
macro heap? definition
local v,min
if MZ.HEAP_DEFINED
err 'setting already specified'
else
v = definition
if v >= 0 & v < 10000h
load min : word from MZ : MZ.minimum_heap
v = v + min
if v > 0FFFFh
v = 0FFFFh
end if
store v : word at MZ : MZ.maximum_heap
else
err 'value out of range'
end if
MZ.HEAP_DEFINED = 1
end if
end macro
macro stack? definition
local v
if MZ.STACK_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_ss
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_sp
else
err 'value out of range'
end if
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = 0
else
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = definition
end match
end macro
element MZ.segment
macro segment? definition
rb 0Fh - ($%+0Fh) and 0Fh
match name =use16?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use16
else match name =use32?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use32
else match name, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
end match
org 0
end macro
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
iterate <dw,word>, dw,word, dd,dword
calminstruction word? value
compute value, value
check value relativeto MZ.segment
jno plain
local offset
compute offset, $%
emit word, value - MZ.segment
check $% > offset
jno done
compute offset, offset - MZ.HEADER_LENGTH
compute offset, offset and 0FFFFh + (offset and not 0FFFFh) shl 12
asm store offset:4 at MZ : MZ.relocations + MZ.RELOCATION_INDEX shl 2
compute MZ.RELOCATION_INDEX, MZ.RELOCATION_INDEX + 1
done:
exit
plain:
emit word, value
end calminstruction
calminstruction dw? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call word, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit word
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dw? definitions&
local cmd
arrange cmd, =label label : =word
assemble cmd
arrange cmd, =dw definitions
assemble cmd
end calminstruction
end iterate
calminstruction align? boundary,value:?
compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
postpone
if MZ.STACK_LENGTH
rb 0Fh - ($%+0Fh) and 0Fh
store ($%-MZ.HEADER_LENGTH) shr 4 : word at MZ : MZ.initial_ss
rb MZ.STACK_LENGTH
store MZ.STACK_LENGTH : word at MZ : MZ.initial_sp
end if
MZ.LENGTH = $%%
MZ.RESERVED_LENGTH = $%-$%%
MZ.NUMBER_OF_RELOCATIONS = MZ.RELOCATION_INDEX
end postpone