VM02/plasma2/loadrel.pla

812 lines
17 KiB
Plaintext
Executable File

CONST FALSE = 0
CONST TRUE = NOT FALSE
CONST IOBUFFER = $BB00
CONST SYMBUFF = $B000
WORD HIMEM = $BF00 ; MUST BE FIRST DEFINED VARIABLE
WORD LOMEM = $0800
WORD MODICT = $0000
WORD ENTRY
BYTE PLASMASTR[] = "PLASMA 0.2"
BYTE MEMSETSTR[] = "MEMSET"
BYTE MEMCPYSTR[] = "MEMCPY"
BYTE ROMCALLSTR[] = "ROMCALL"
BYTE SYSCALLSTR[] = "SYSCALL"
BYTE COUTSTR[] = "COUT"
BYTE CINSTR[] = "CIN"
BYTE PRSTRSTR[] = "PRSTR"
BYTE RDSTRSTR[] = "RDSTR"
BYTE NULLSTR[] = ""
BYTE BADMODSTR[] = "MODULE NOT FOUND"
BYTE ASMADR[] = "ASM ADDRESS: $"
BYTE LOADADR[] = "LOAD ADDRESS: $"
BYTE DATASZ[] = "DATA SIZE: $"
BYTE RELOFSTSTR[] = "REL OFFSET: $"
BYTE FIX16STR[] = "FIXUP 16-BIT ADDRESS: $"
BYTE FIX8STR[] = "FIXUP 8-BIT ADDRESS: $"
BYTE RLDLBL[] = "RELOCATION DIRECTORY:"
BYTE ESDLBL[] = "SYMBOL TABLE:"
BYTE MATCHEXTRNSTR = "MATCH EXTRN: "
BYTE PRESSANYKEY[] = "PRESS ANY KEY TO CONTINUE..."
BYTE PERR
;
; SYMBOL TABLE TYPE CONSTANTS
;
CONST LOBYTE_TYPE = $01
CONST HIBYTE_TYPE = $02
CONST WORD_TYPE = $03
CONST FUNC_TYPE = $04
CONST CONST_TYPE = $08
FUNC INITPLASMA,LOADMOD ; MUST BE FIRST DEFINED FUNCTIONS
;
; CODE GENERATION FUNCTIONS
;
CONST OPTBL = $D000
FUNC GEN_ZERO, GEN_ADD, GEN_SUB, GEN_MUL, GEN_DIV, GEN_MOD, GEN_INCR, GEN_DECR
FUNC GEN_NEG, GEN_COMP, GEN_BAND, GEN_IOR, GEN_XOR, GEN_SHL, GEN_SHR, GEN_IDXW
FUNC GEN_NOT, GEN_LOR, GEN_LAND, GEN_LA, GEN_LLA, GEN_CB, GEN_CW, GEN_SWAP
FUNC GEN_DROP, GEN_DUP, GEN_PUSH, GEN_PULL, GEN_BRLT, GEN_BRGT, GEN_BREQ, GEN_BRNE
FUNC GEN_ISEQ, GEN_ISNE, GEN_ISGT, GEN_ISLT, GEN_ISGE, GEN_ISLE, BRFLS, BRTRU
FUNC GEN_JUMP, GEN_IJMP, GEN_CALL, GEN_ICAL, GEN_ENTER, GEN_LEAVE, GEN_RET, GEN_XCALL
FUNC GEN_LB, GEN_LW, GEN_LLB, GEN_LLW, GEN_LAB, GEN_LAW, GEN_DLB, GEN_DLW
FUNC GEN_SB, GEN_SW, GEN_SLB, GEN_SLW, GEN_SAB, GEN_SAW, GEN_DAB, GEN_DAW
FUNC GEN_NOP
WORD PCPTR
WORD GEN_OPTBL[]
WORD = GEN_ZERO, GEN_ADD, GEN_SUB, GEN_MUL, GEN_DIV, GEN_MOD, GEN_INCR, GEN_DECR
WORD = GEN_NEG, GEN_COMP, GEN_BAND, GEN_IOR, GEN_XOR, GEN_SHL, GEN_SHR, GEN_IDXW
WORD = GEN_NOT, GEN_LOR, GEN_LAND, GEN_LA, GEN_LLA, GEN_CB, GEN_CW, GEN_SWAP
WORD = GEN_DROP, GEN_DUP, GEN_PUSH, GEN_PULL, GEN_BRLT, GEN_BRGT, GEN_BREQ, GEN_BRNE
WORD = GEN_ISEQ, GEN_ISNE, GEN_ISGT, GEN_ISLT, GEN_ISGE, GEN_ISLE, BRFLS, BRTRU
WORD = GEN_JUMP, GEN_IJMP, GEN_CALL, GEN_ICAL, GEN_ENTER, GEN_LEAVE, GEN_RET, GEN_XCALL
WORD = GEN_LB, GEN_LW, GEN_LLB, GEN_LLW, GEN_LAB, GEN_LAW, GEN_DLB, GEN_DLW
WORD = GEN_SB, GEN_SW, GEN_SLB, GEN_SLW, GEN_SAB, GEN_SAW, GEN_DAB, GEN_DAW
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
WORD = GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP, GEN_NOP
DEF BADMOD
PRSTR(@BADMODSTR)
COUT($0D)
END
DEF CROUT
RETURN COUT($0D)
END
DEF PRBYTE(VAL)
RETURN ROMCALL(VAL, 0, 0, 0, $FDDA)
END
DEF PRWORD(VAL)
ROMCALL(VAL >> 8, VAL, 0, 0, $F941)
END
DEF ADDSYM(TYPE, ADDR, SYMSTR)
(LOMEM).0 = TYPE
(LOMEM):1 = ADDR
(LOMEM).3 = ^SYMSTR
MEMCPY(SYMSTR + 1, LOMEM + 4, ^SYMSTR)
LOMEM = LOMEM + 4 + ^SYMSTR
END
DEF INITPLASMA
BYTE PARAMS[2]
CROUT
PRSTR(@PLASMASTR)
CROUT
^$BFD8 = 0 ; CLOSE ALL OPEN FILES
PARAMS.0 = 1
PARAMS.1 = 0
SYSCALL($CC, @PARAMS)
MEMSET($0000, $BF58, 24) ; RESET SYS BITMAP
^$BF58 = $C0
^$BF6F = $01
;
; SET INIT MEMORY BOUNDARIES
;
HIMEM = $BF00
LOMEM = $0800
MODICT = LOMEM
;
; INIT SYMBOL DICTIONARY
;
ADDSYM(FUNC_TYPE, @MEMSET, @MEMSETSTR)
ADDSYM(FUNC_TYPE, @MEMCPY, @MEMCPYSTR)
ADDSYM(FUNC_TYPE, @ROMCALL, @ROMCALLSTR)
ADDSYM(FUNC_TYPE, @SYSCALL, @SYSCALLSTR)
ADDSYM(FUNC_TYPE, @COUT, @COUTSTR)
ADDSYM(FUNC_TYPE, @CIN, @CINSTR)
ADDSYM(FUNC_TYPE, @PRSTR, @PRSTRSTR)
ADDSYM(FUNC_TYPE, @RDSTR, @RDSTRSTR)
ADDSYM(0, 0, @NULLSTR) ; THIS MARKS END OF MODULE DICTIONARY
END
DEF ALLOC(SIZE)
WORD ADDR
ADDR = LOMEM
LOMEM = LOMEM + SIZE
RETURN ADDR
END
DEF RELEASE(ADDR)
LOMEM = ADDR
END
;
; BASIC FILE I/O
;
DEF GETFILEINFO(PATH, INFOPTR)
BYTE PARAMS[18]
PARAMS.0 = 10
PARAMS:1 = PATH
PERR = SYSCALL($C4, @PARAMS)
IF NOT PERR
MEMCPY(@PARAMS.3, INFOPTR, 15)
FIN
RETURN PERR
END
DEF OPEN(PATH, BUFF)
BYTE PARAMS[6]
PARAMS.0 = 3
PARAMS:1 = PATH
PARAMS:3 = BUFF
PARAMS.5 = 0
PERR = SYSCALL($C8, @PARAMS)
RETURN PARAMS.5
END
DEF CLOSE(REFNUM)
BYTE PARAMS[2]
PARAMS.0 = 1
PARAMS.1 = REFNUM
PERR = SYSCALL($CC, @PARAMS)
RETURN PERR
END
DEF READ(REFNUM, BUFF, LEN)
BYTE PARAMS[8]
PARAMS.0 = 4
PARAMS.1 = REFNUM
PARAMS:2 = BUFF
PARAMS:4 = LEN
PARAMS:6 = 0
PERR = SYSCALL($CA, @PARAMS)
RETURN PARAMS:6
END
;
; CODE GENERATION
;
; ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR : 00 02 04 06 08 0A 0C 0E
DEF GEN_ZERO
^LOMEM = $00
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ADD
^LOMEM = $02
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SUB
^LOMEM = $04
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_MUL
^LOMEM = $06
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DIV
^LOMEM = $08
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_MOD
^LOMEM = $0A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_INCR
^LOMEM = $0C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DECR
^LOMEM = $0E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW : 10 12 14 16 18 1A 1C 1E
DEF GEN_NEG
^LOMEM = $10
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_COMP
^LOMEM = $12
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_BAND
^LOMEM = $14
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_IOR
^LOMEM = $16
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_XOR
^LOMEM = $18
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SHL
^LOMEM = $1A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SHR
^LOMEM = $1C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_IDXW
^LOMEM = $1E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; NOT,LOR,LAND,LA,LLA,CB,CW,SWAP : 20 22 24 26 28 2A 2C 2E
DEF GEN_NOT
^LOMEM = $20
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LOR
^LOMEM = $22
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LAND
^LOMEM = $24
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LA
^LOMEM = $26
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LLA
^LOMEM = $28
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_CB
(LOMEM).0 = $2A
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_CW
(LOMEM).0 = $2C
(LOMEM):1 = (PCPTR):1
LOMEM = LOMEM + 3
PCPTR = PCPTR + 3
END
DEF GEN_SWAP
^LOMEM = $2E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; DROP,DUP,PUSH,PULL,BRLT,BRGT,BREQ,BRNE : 30 32 34 36 38 3A 3C 3E
DEF GEN_DROP
^LOMEM = $30
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DUP
^LOMEM = $32
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_PUSH
^LOMEM = $34
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_PULL
^LOMEM = $36
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_BRLT
^LOMEM = $38
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_BRGT
^LOMEM = $3A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_BREQ
^LOMEM = $3C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_BRNE
^LOMEM = $3E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU : 40 42 44 46 48 4A 4C 4E
DEF GEN_ISEQ
^LOMEM = $40
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ISNE
^LOMEM = $42
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ISGT
^LOMEM = $44
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ISLT
^LOMEM = $46
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ISGE
^LOMEM = $48
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ISLE
^LOMEM = $4A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF BRFLS
^LOMEM = $4C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF BRTRU
^LOMEM = $4E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; JUMP,IJMP,CALL,ICAL,ENTER,LEAVE,RET,XCALL : 50 52 54 56 58 5A 5C 5E
DEF GEN_JUMP
^LOMEM = $50
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_IJMP
^LOMEM = $52
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_CALL
^LOMEM = $54
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ICAL
^LOMEM = $56
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_ENTER
^LOMEM = $58
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LEAVE
^LOMEM = $5A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_RET
^LOMEM = $5C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_XCALL
^LOMEM = $5E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
; LB,LW,LLB,LLW,LAB,LAW,DLB,DLW : 60 62 64 66 68 6A 6C 6E
DEF GEN_LB
^LOMEM = $60
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LW
^LOMEM = $62
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LLB
(LOMEM).0 = $64
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_LLW
(LOMEM).0 = $66
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_LAB
^LOMEM = $68
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_LAW
^LOMEM = $6A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DLB
(LOMEM).0 = $6C
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_DLW
(LOMEM).0 = $6E
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
; SB,SW,SLB,SLW,SAB,SAW,DAB,DAW : 70 72 74 76 78 7A 7C 7E
DEF GEN_SB
^LOMEM = $70
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SW
^LOMEM = $72
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SLB
(LOMEM).0 = $74
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_SLW
(LOMEM).0 = $76
(LOMEM).1 = (PCPTR).1
LOMEM = LOMEM + 2
PCPTR = PCPTR + 2
END
DEF GEN_SAB
^LOMEM = $78
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_SAW
^LOMEM = $7A
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DAB
^LOMEM = $7C
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_DAW
^LOMEM = $7E
LOMEM = LOMEM + 1
PCPTR = PCPTR + 1
END
DEF GEN_OP
*(GEN_OPTBL + ^PCPTR)()
END
DEF GEN_DEF(NPARAM, FRAMESZ)
END
DEF GEN_END(NPARAM, FRAMESZ)
END
DEF GENCODE(PCODEPTR, PCODELEN, RLD, ES)
END
;
; REL MODULE FIXUPS
;
DEF DUMPRLD(RLD)
COUT('$')
PRBYTE(^RLD)
COUT(':')
COUT(' ')
COUT('$')
PRWORD(*(RLD + 1))
COUT(' ')
COUT('$')
PRBYTE(^(RLD + 3))
CROUT
RETURN RLD + 4
END
DEF DUMPESD(ESD)
WHILE ^ESD & $80
COUT(^ESD)
ESD = ESD + 1
LOOP
COUT(^ESD)
COUT(':')
COUT(' ')
COUT('$')
PRBYTE(^(ESD + 1))
COUT(' ')
COUT('$')
PRWORD(^(ESD + 2))
CROUT
RETURN ESD + 4
END
DEF MATCHSTR(STR1, STR2)
BYTE I
IF ^STR1 == ^STR2
FOR I = ^STR1 DOWNTO 1
IF (STR1).[I] <> (STR2).[I]
RETURN FALSE
FIN
NEXT
RETURN TRUE
FIN
RETURN FALSE
END
DEF SEARCHDICT(SYMSTR)
WORD DICTPTR
DICTPTR = MODICT
;
; SEARCH MODULE DICTIONARY LOOKING FOR MATCH
;
WHILE DICTPTR
IF ^DICTPTR
; CROUT
; PRSTR(DICTPTR + 3)
IF MATCHSTR(DICTPTR + 3, SYMSTR)
; COUT('$')
; PRWORD(*(DICTPTR + 1))
RETURN *(DICTPTR + 1)
FIN
DICTPTR = DICTPTR + 4 + ^(DICTPTR + 3) ; NEXT ENTRY
ELSE
DICTPTR = *(DICTPTR + 1) ; NEXT MODULE SYM TABLE
FIN
LOOP
END
DEF DUMPDICT
WORD DICTPTR
DICTPTR = MODICT
;
; SEARCH MODULE DICTIONARY LOOKING FOR MATCH
;
WHILE DICTPTR
IF ^DICTPTR
CROUT
PRSTR(DICTPTR + 3)
COUT('$')
PRWORD(*(DICTPTR + 1))
CROUT
DICTPTR = DICTPTR + 4 + ^(DICTPTR + 3) ; NEXT ENTRY
ELSE
DICTPTR = *(DICTPTR + 1) ; NEXT MODULE SYM TABLE
FIN
LOOP
END
DEF TOUPPER(C)
IF C >= 'a'
IF C <= 'z'
RETURN C - $20
FIN
FIN
RETURN C
END
DEF MATCHEXTRN(INDEX, ESD)
BYTE SYMSTR[$81], I
WORD SYMPTR
;
; FIND MATCHING ESD INDEX
;
WHILE ^ESD
; DUMPESD(ESD)
SYMPTR = ESD
I = 1
WHILE ^ESD & $80
SYMSTR[I] = TOUPPER(^ESD & $7F)
I = I + 1
ESD = ESD + 1
LOOP
SYMSTR[I] = TOUPPER(^ESD & $7F)
SYMSTR = I
; CROUT
IF ^(ESD + 1) & $10
; PRSTR(@MATCHEXTRNSTR)
; PRSTR(@SYMSTR)
IF ^(ESD + 2) == INDEX
RETURN SEARCHDICT(@SYMSTR)
FIN
FIN
ESD = ESD + 4
LOOP
RETURN 0
END
DEF FIXUP(SEGPTR, RLD, OFST, ESD)
WORD FIXVAL, FIXADDR, EXTRNVAL
WHILE ^RLD
; DUMPRLD(RLD)
FIXADDR = SEGPTR + *(RLD + 1)
IF ^RLD & $80
;
; 16 BIT FIXUP
;
; PRSTR(@FIX16STR)
; PRWORD(FIXADDR)
; CROUT
FIXVAL = *FIXADDR
IF ^RLD & $10
;
; EXTERNAL SYMBOL
;
EXTRNVAL = MATCHEXTRN(^(RLD + 3), ESD)
IF EXTRNVAL
FIXVAL = FIXVAL + EXTRNVAL
ELSE
RETURN -1
FIN
ELSE
FIXVAL = FIXVAL + OFST
FIN
IF ^RLD & $20 ; REVERSE HI AND LO BYTES
FIXVAL = ((FIXVAL >> 8) & $FF) ? (FIXVAL << 8)
FIN
*FIXADDR = FIXVAL
ELSE
;
; 8 BIT FIXUP
;
; PRSTR(@FIX8STR)
; PRWORD(FIXADDR)
; CROUT
IF ^RLD & $10
;
; EXTERNAL SYMBOL
;
FIXVAL = MATCHEXTRN(^(RLD + 3), ESD)
IF NOT EXTRNVAL
RETURN -1
FIN
ELSE
IF ^RLD & $40
FIXVAL = ^FIXADDR << 8 ? ^(RLD + 3)
FIXVAL = FIXVAL + OFST
ELSE
FIXVAL = ^(RLD + 3) << 8 ? ^FIXADDR
FIXVAL = FIXVAL + OFST
FIN
FIN
IF ^RLD & $40
^FIXADDR = FIXVAL >> 8
ELSE
^FIXADDR = FIXVAL
FIN
FIN
RLD = RLD + 4
LOOP
END
DEF LOADMOD(MODSTR)
BYTE REFNUM, I, INFO[15], SYMSTR[81]
WORD RELOFST, MODPTR, MODSYMTBL, MODSYMSZ, LEN, DATALEN, RLD, ESD
WORD PCODESEG, PCODEPTR, PCODELEN, CODEPTR, CODELEN
GETFILEINFO(MODSTR, @INFO)
IF INFO.1 <> $FE ; REL FILE TYPE
RETURN @BADMOD
FIN
RELOFST = INFO:2
; PRSTR(@ASMADR)
; PRWORD(RELOFST)
; CROUT
;
; READ REL FILE
;
REFNUM = OPEN(MODSTR, IOBUFFER)
LEN = READ(REFNUM, LOMEM, 32768)
CLOSE(REFNUM)
; PRSTR(@LOADADR)
; PRWORD(LOMEM)
; CROUT
;
; GET POINTERS TO IMPORTANT SECTIONS
;
IF (LOMEM):4 <> $BEE2
RETURN BADMOD
FIN
DATALEN = *LOMEM
MODPTR = LOMEM + 2
LOMEM = LOMEM + LEN
ENTRY = MODPTR + 6
PCODEPTR = MODPTR + (MODPTR):0
RELOFST = MODPTR - (MODPTR):4
RLD = MODPTR + DATALEN
ESD = RLD
WHILE ^ESD ; SKIP OVER RLD
ESD = ESD + 4
LOOP
ESD = ESD + 1
; PRSTR(@RELOFSTSTR)
; PRWORD(RELOFST)
; CROUT
;
; EXPAND BYTECODE
;
PCODELEN = RLD - PCODEPTR
IF CODELEN
CODEPTR = LOMEM
GENCODE(PCODEPTR, PCODELEN, RLD, ESD)
CODELEN = LOMEM - CODEPTR
FIN
;
; RUN THROUGH DATA FIXUP TABLE
;
IF FIXUP(MODPTR, RLD, RELOFST, ESD) < 0
RETURN @BADMOD
FIN
;
; CREATE SYMBOL TABLE FOR EXPORTS
;
WHILE ^ESD
; DUMPESD(ESD)
I = 1
WHILE ^ESD & $80
SYMSTR[I] = TOUPPER(^ESD & $7F)
I = I + 1
ESD = ESD + 1
LOOP
SYMSTR[I] = TOUPPER(^ESD & $7F)
SYMSTR = I
IF ^(ESD + 1) & $08 ; ENTRY SYMBOL
ADDSYM(FUNC_TYPE, *(ESD + 2), @SYMSTR)
FIN
ESD = ESD + 4
LOOP
ADDSYM(0, MODICT, @NULLSTR) ; LINK TO PREVIOUS MODULE DICTIONARY
MODSYMTBL = ESD
;
; MOVE SYM TABLE TO END OF DATA SEGMENT
;
MODSYMSZ = LOMEM - MODSYMTBL
MEMCPY(MODSYMTBL, RLD, MODSYMSZ)
;
; UPDATE POINTERS
;
MODICT = RLD
LOMEM = RLD + MODSYMSZ
; DUMPDICT
RETURN ENTRY
END
INITPLASMA
(LOADMOD(RDSTR($BA)))()
PRSTR(@PRESSANYKEY)
WHILE ^$C000 < 128
LOOP
^$C010
DONE