home *** CD-ROM | disk | FTP | other *** search
- \ SAVEEXE.SEQ A SAVE EXE routine. Extracted from F83Y by Tom Zimmer
-
- only forth also hidden definitions also
-
- \ Some code to allow saving the Forth system to disk in the .EXE format.
-
- CODE XCKSUM ( add cnt startv seg - cksum )
- POP DS
- POP AX
- POP CX
- POP BX
- HERE ADD AX, 0 [BX]
- INC BX
- INC BX
- DEC CX
- LOOP PUSH CS
- POP DS
- 1PUSH END-CODE
-
- HEX
-
- CREATE SUVEC 100 , 0 ,
- VARIABLE DPSTART \ A place to save DP for restoral
-
- LABEL SEXE
- MOV SUVEC 2+ DS \ Save DS ins setup vector
- MOV AX, DS \ move DS to AX
- ADD AX, # #CODESEGS #LISTSEGS + \ Add 128K to get to heads
- MOV ES, AX \ move head seg to ES
- MOV BX, UP \ Move UP to BX
- MOV CX, ' YDP >body @ [BX] \ get contents of YDP user variable
- MOV SI, CX \ move it into SI
- DEC SI
- MOV DI, SI \ decrement SI and move to DI
- XOR AX, AX \ Clear AX
- XCHG AX, YSTART \ Exchange AX, and YSTART clearing it
- ADD AX, SUVEC 2+ \ Add to setup vector
- PUSH DS \ save DS
- MOV DS, AX \ move AX to DS
- OR CX, CX 0<> \ if YDP was not zero (0)
- IF STD
- REPZ
- MOVSB \ move HEADS to head space
- CLD
- THEN
- POP DS \ restore DS
- MOV YSEG ES \ set YSEG to ES
- MOV AX, DS \ move DS to AX
- ADD AX, # #CODESEGS \ Add 64k to get to heads
- MOV ES, AX \ move head seg to ES
- MOV BX, UP \ Move UP to BX
- MOV CX, ' XDP >body @ [BX] \ get contents of XDP user variable
- MOV SI, CX \ move it into SI
- DEC SI
- MOV DI, SI \ decrement SI and move to DI
- MOV AX, XSTART \ mov XSTART to AX
- ADD AX, SUVEC 2+ \ Add to setup vector
- PUSH DS \ save DS
- MOV DS, AX \ move AX to DS
- OR CX, CX 0<> \ if XDP was not zero (0)
- IF STD
- REPZ
- MOVSB \ move LISTS to LIST space
- CLD
- THEN
- POP DS \ restore DS
- MOV XSEG ES \ set XSEG to ES
- MOV AX, DPSTART \ Move DPSTART
- MOV XSTART AX \ into XSTART, for use setting DP
- MOV XMOVED # -1 WORD \ Initialize LIST to already moved.
- JMP FAR [] SUVEC \ Jump to forth cold entry.
- END-CODE
-
- \ An empty .EXE header table.
-
- CREATE EHMT
- ( +0) 5A4D , \ EHADR .EXE File marker
- ( +2) 0 , \ EHLMRV File mod 512 including header
- ( +4) 0 , \ EH512Z Number of 512 byte blocks in file
- ( +6) 0 , \ Number of relocation table items
- ( +8) 2 , \ Size of header in segments
- ( +A) 0 , \ Minimum segments needed by program
- ( +C) 0FFFF , \ Additional segments needed by program, infinity
- ( +E) 0FFF0 , \ SS Stack segment, 100h below code strt
- ( +10) 0FFFC , \ Offset for stack pointer.
- ( +12) 0 , \ Word chekcsum, adds up to -1
- ( +14) SEXE , \ Offset to put in IP when passing control
- ( +16) 0FFF0 , \ CS Code segment, 100h below code strt
- ( +18) 1C , \ Displacement in bytes to first relocation item
- ( +1A) 0 , \ Overlay #, or zero (0) for resident code
-
- ( +1C) 0 , \ Null relocation item, and fill to two (2) segments
- ( +1E) 0 ,
-
- DECIMAL
-
- comment:
-
- XCKSUM checksums a block of memory using word addition ( cnt must be even )
-
- SUVEC startup vector, for a long jump to HEX 100 to set up
- CS correctly. Currently the .EXE header has CS set at
- 0FFF0h which fakes out the loader to set CS to the same
- as the Program Sement Prefix. This makes the long jump
- unnecessary, but we put it in so we could easily make
- the .EXE header more conventional.
-
- SEXE entry point specified by .EXE header. Sets the seg part
- of SUVEC, moves FORTH headers up to seg after DS (YSEG),
- does long jump thru SUVEC to start system.
-
- EHMT empty .EXE header. Entries 0Eh and 16h are SS and CS,
- set to -10h, somewhat questionable. If they are changed,
- 10h and 14h must be changed to compensate.
-
- comment;
-
-
- HEX
- 20 CONSTANT EHZ
- 100 EHZ - CONSTANT EHADR
- EHADR 2+ CONSTANT EHLMRV
- EHADR 4 + CONSTANT EH512Z
- EHADR 12 + CONSTANT EHCKSM
- EHADR 10 + CONSTANT EHSP
-
- comment:
-
- Constants for EXE header. Header is put immediately before
- 100h for write-out. See DOS 2.0 appendix H for explanation.
-
- EHADR header address
- EHZ header size
- EHLMRV load module remainder
- EH512Z # 512 blocks in entire file
- EHCKSM entire file checksum so file words total to FFFFh
- EHSP startup SP
-
- comment;
-
- HEX
-
- : WEXE ( handle --- )
- >R \ Save the file HANDLE
- HERE DPSTART ! \ Save DP for later restoral
- EHMT EHADR EHZ CMOVE \ Move empty header to before 100H
- HERE 20 + EHSP ! \ Startup Stack Pointer to HERE+20H
- HERE 05F + U2/ 8 / XSTART ! \ Save start segment in XSTART
- XDP @ 1F + U2/ 8 / \ Calculate LIST length in segments
- XSTART @ + \ add LIST start segment
- YSTART ! \ Save start segment in YSTART
- YDP @ 1F + U2/ 8 / \ HEAD length in segments
- YSTART @ + \ = total length in segments
- EHADR U2/ 8 / - \ Subtract Header segments
- DUP 20 MOD \ Remainder of 512 byte pages
- 10 * EHLMRV ! \ save BYTE remainder in EHLMRV
- 1F + U2/ 10 / EH512Z ! \ Set # of full pages into EH512Z
-
- 0 YDP @ 1F + 0FFF0 AND \ HEAD length in bytes
- 0 YSEG @ XCKSUM \ Checksum HEADS
- 0 XDP @ 1F + 0FFF0 AND \ LIST length in bytes
- ROT XSEG @ XCKSUM \ Checksum LIST
- EHADR HERE 05F + 0FFF0 AND \ CODE length in bytes
- EHADR - ROT ?CS: XCKSUM \ Checksum CODE
- NOT EHCKSM +! \ Save checksum in EHCKSM
-
- EHADR \ Start address
- HERE 05F + 0FFF0 AND \ end address is total length
- EHADR - \ dup u. \ subtract space below header
- R@ HWRITE DROP \ Write CODE space
-
- 0 \ From segment offset 0
- XDP @ 1F + 0FFF0 AND \ dup u. \ LIST length in bytes
- R@ XSEG @ EXHWRITE DROP \ Write LIST space
-
- 0 \ From segment offseg 0
- YDP @ 1F + 0FFF0 AND \ dup u. \ HEAD length in bytes
- R> YSEG @ EXHWRITE DROP \ Write HEAD space
- YSTART OFF ; \ Reset YSTART
-
- DECIMAL
-
- only forth definitions also hidden also
-
- handle exehcb
- variable ?gotov \ Do we have anything to save?
- defer append-ov \ A defered word to append an overlay to saved EXE.
-
- : *save-exe ( | name --- )
- exehcb !hcb " EXE" ">$
- exehcb $>ext
- exehcb hcreate abort" Could not create file"
- exehcb wexe
- ?gotov @
- if append-ov
- then
- exehcb hclose drop ;
-
- : save-exe ( | name --- )
- DECIMAL \ Save system in DECIMAL number base
- >in @ span @ 1- >
- if cr ." File to save? " query
- then ?gotov @
- if >in @ >r
- *save-exe
- r> >in !
- then *save-exe ;
-
- ' save-exe alias FSAVE ( | name --- ) \ a pseudonym for SAVE-EXE
-
- comment:
-
- WEXE ( fcb ) write .EXE file given FCB of opened file.
- Copies header from EHMT to below 100h, fills out EHSP,
- EHMLRV, EH512Z, sets DTA, computes YSEG (headers) checksum,
- plus checksum from 0E0h to YSTART, puts NOT in EHCKSM,
- writes 0E0h to YSTART, then sets DTA for YSEG, writes
- out FORTH headers. "lobz" is the size of the first write,
- 0E0h to YSTART. Image is written with YSTART containing
- offset where the header segment data begins. YSTART non-
- zero indicates the segment hasn't been moved to its correct
- location for running.
-
- SAVE-EXE like SAVE-SYSTEM, but makes a .EXE file.
-
- comment;
-
- only forth definitions also
-