|  |   | 
| Line 1: | Line 1: | 
|  | == Saving a machine code program into a RAM file ==
 |  | Boy that ralely helps me the heck out. | 
|  |   |  | 
|  | In this chapter, the method to save machine code program that resides in memory into RAM file as a ".CO" file is described. In fact, the object to be saved needs not necessarily machine code program. It can be binary data. The routines described later in this chapter saved the contents of specified portion of memory exactly as they are, just appending some control information.
 |  | 
|  |   |  | 
|  | The control information consists of three words: load address, length, and execution address. The contents of the file is always loaded back to the location where the contents (machine code program) were located when saved. The load address in the file contains the location. Note that this is NOT the address of the file itself.
 |  | 
|  |   |  | 
|  | === Procedure to save machine code program ===
 |  | 
|  |   |  | 
|  | To save machine code program in memory as a ".CO" file, follow the steps below. Address of individual routines used in this chapter will be described later in this document.
 |  | 
|  |   |  | 
|  | 1. Set up file name,
 |  | 
|  |   |  | 
|  | Set up file name in FILNAM. This is the same step used to open an ASCII file
 |  | 
|  | except the extnsion should be "CO" in case of machine code program save. Body
 |  | 
|  | of file anme (i.e. string that precedes the extension) should be 6 characters
 |  | 
|  | long, space filled to the extension.
 |  | 
|  |   |  | 
|  | :<nowiki>[FILNAM] <= 1st character of file name</nowiki>
 |  | 
|  | :.
 |  | 
|  | :.
 |  | 
|  | :.
 |  | 
|  | :<nowiki>[FILNAM+5] <= 6th character of file name</nowiki>
 |  | 
|  | :<nowiki>[FILNAM+6] <= "C"</nowiki>
 |  | 
|  | :<nowiki>[FILNAM+7] <= "O"</nowiki>
 |  | 
|  | :<nowiki>[FILNAM+8] <= " "</nowiki>
 |  | 
|  |   |  | 
|  | 2. Set up parameters
 |  | 
|  |   |  | 
|  | Then set address of machine code program, its length and execution address.
 |  | 
|  |   |  | 
|  | :<nowiki>[BINADR] <= Start address of binary data</nowiki>
 |  | 
|  | :<nowiki>[BINLEN] <= Length of binary data</nowiki>
 |  | 
|  | :<nowiki>[BINEXE] <= Execution start address; 0 if not executable at IPL</nowiki>
 |  | 
|  |   |  | 
|  | 3. Fix up directory structure.
 |  | 
|  |   |  | 
|  | Refer to "Description of ROM routines in PC_8201 for detail of LNKFIL routine.
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		CALL	LNKFIL		; Fix up directory structure
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 4. Search for the file of the same name.
 |  | 
|  |   |  | 
|  | Search directory for the file that has the same name as one in thatwe want to
 |  | 
|  | save the machine code program. If it exists, delete it. Obviously here you can
 |  | 
|  | abort without saving new one, instead of deleting old one.
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		CALL	SRCCOM		; Search directory for FILNAM
 |  | 
|  | 		CNZ	KILCOM		; Kill old one if exist.
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 5. Search directory for empty (free) slot.
 |  | 
|  |   |  | 
|  | To register the file, make sure there's free slot in directory and remember the
 |  | 
|  | location of the slot. If not free slot is available, abort saving.
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		CALL	SCNEMP		; Search for empty slot.
 |  | 
|  | 		; (save address)
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 6. Allocate room in RAM file.
 |  | 
|  |   |  | 
|  | Allocate room in RAM file for machine code program and control information
 |  | 
|  | (location, length, and execution address of machine code program). The length
 |  | 
|  | of the control information is 6 bytes long (i.e.: 3 words). MAKHOL is the
 |  | 
|  | routine to allocate room in [BC] length at [HL]. Here [VARTAB] tells the
 |  | 
|  | location where the room is to be allocated.
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		[HL] <= [VARTAB]
 |  | 
|  | 		[BC] <= [BINLEN] + 6
 |  | 
|  | 		CALL	MAKHOL		; Allocate room
 |  | 
|  | 		JC	OMERR		; Error if out of memory
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 7. Copy control information
 |  | 
|  |   |  | 
|  | Copy control information to the top of the room allocated in above step.
 |  | 
|  |   |  | 
|  | 8. Copy machine code program
 |  | 
|  |   |  | 
|  | Copy machine code program into the rest of the room.
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		[HL] <= [BINADR]
 |  | 
|  | 		[DE] <= (Top address of the room) + 6
 |  | 
|  | 					; Location in RAM file where
 |  | 
|  | 					; the program is saved.
 |  | 
|  | 		[BC] <= [BINLEN]	; Length of the program.
 |  | 
|  | 		CALL	LDIRSB		; Do block transfer.
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 9. Reset BINTAB
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		Special magic???
 |  | 
|  | 		; actually, BINTAB must be preserved across call to MAKHOL
 |  | 
|  | 		; because MAKHOL isn't smart enough to leave it alone
 |  | 
|  | 		; when opening a hole in CO file region.
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 10. Put file name into directory
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		[HL] <= address of directory slot gained by SCNEMP
 |  | 
|  | 		[DE] <= address of room in RAM file. One used in MAKHOL call.
 |  | 
|  | 		[A] <= $AC (CO file directory flags byte)
 |  | 
|  | 		CALL	SETNAM
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | 11. Fix up the directory structure
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 		CALL LNKFIL		; gratuitous since appending to final region...
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | === Sample program ===
 |  | 
|  |   |  | 
|  | <pre>
 |  | 
|  | 	; Save machine code program in memory into RAM file.
 |  | 
|  |   |  | 
|  | 		LXI	H,0		; Remember current SP for ERRJMP
 |  | 
|  | 		DAD	SP
 |  | 
|  | 		SHLD	MYSTACK
 |  | 
|  | 		LXI	H,ERROR
 |  | 
|  | 		SHLD	ERRJMP		; Active error trap
 |  | 
|  |   |  | 
|  | 		LXI	H,MYFILE
 |  | 
|  | 		LXI	D,FILNAM
 |  | 
|  | 		LXI	B,6
 |  | 
|  | 		CALL	LDIRSB		; Copy filename to FILNAM
 |  | 
|  | 		LXI	M,FILNAM+6	; Extension
 |  | 
|  | 		MVI	M,'C'
 |  | 
|  | 		INX	H
 |  | 
|  | 		MVI	M,'O'
 |  | 
|  | 		INX	H
 |  | 
|  | 		MVI	M,' '
 |  | 
|  |   |  | 
|  | 		LXI	H,MYBIPA	; Format, copy in hdr
 |  | 
|  | 		LXI	D,BINADR
 |  | 
|  | 		LXI	B,6
 |  | 
|  | 		CALL	LDIRSB
 |  | 
|  |   |  | 
|  | 		CALL	LNKFIL		; Fixup directory entry start addresses
 |  | 
|  |   |  | 
|  | 		CALL	SRCCOM		; Search directory for a file
 |  | 
|  | 		CNZ	KILCOM		; Delete if exists
 |  | 
|  |   |  | 
|  | 		CALL	SCNEMP		; Find an empty directory slot
 |  | 
|  | 		PUSH	H		; Save theaddress
 |  | 
|  |   |  | 
|  | 		LHLD	BINTAB		; Save current BINTAB since MAKHOL damages it
 |  | 
|  | 		PUSH	H
 |  | 
|  |   |  | 
|  | 		LXI	B,6
 |  | 
|  | 		LHLD	BINLEN
 |  | 
|  | 		PUSH	H		; Save BINLEN (without header) for future use
 |  | 
|  |   |  | 
|  | 		DAD	B		; Add 6 bytes for header to HL
 |  | 
|  |   |  | 
|  | 		MOV	E,H
 |  | 
|  | 		MOV	D,L		; Copy HL to DE but swap bytes??? Looks like bug...
 |  | 
|  |   |  | 
|  | 		LHLD	VARTAB		; Where file is created/
 |  | 
|  | 		SHLD	TEMP		; Length saved for future use
 |  | 
|  | 		CNC	MAKHOL		; Make room for header and program
 |  | 
|  | 		JC	OMERR		; Cleanup if outof memory
 |  | 
|  |   |  | 
|  | 		XCHG
 |  | 
|  | 		LXI	H,BINADR
 |  | 
|  | 		LXI	B,6
 |  | 
|  | 		CALL	LDIRSB		; Copy header bytes into file
 |  | 
|  |   |  | 
|  | 		LHLD	BINADR		; Point to source data
 |  | 
|  | 		POP	B		; Recover source length
 |  | 
|  | 		CALL	LDIRSB		; Copy in the program
 |  | 
|  |   |  | 
|  | 		POP	H		; Restore BINTAB
 |  | 
|  | 		SHLD	BINTAB
 |  | 
|  |   |  | 
|  | 		POP	H		; Recover dir slot pointer
 |  | 
|  | 		MVI	A,$A0		; Set type to CO
 |  | 
|  | 		XCHG
 |  | 
|  | 		LHLD	TEMP		; HL <= start address of file
 |  | 
|  | 		XCHG
 |  | 
|  | 		CALL	SETNAM		; Fill in dir entry
 |  | 
|  |   |  | 
|  | 		CALL	LNKFIL		; Fix up directory file start pointers
 |  | 
|  |   |  | 
|  | RETURN:		LXI	H,0		; Remove error trap
 |  | 
|  | 		SHLD	ERRTRP
 |  | 
|  | 		RET
 |  | 
|  |   |  | 
|  | ERROR:		LHLD	MYSTACK
 |  | 
|  | 		SPHL			; drop BASIC junk from stack
 |  | 
|  | 		; put error handling code here
 |  | 
|  | 		JMP	RETURN
 |  | 
|  |   |  | 
|  | OMERR:		; Put OM error handler here
 |  | 
|  | 		JMP	RETURN
 |  | 
|  |   |  | 
|  | MYFILE:		.DB	"SAMPLE"
 |  | 
|  |   |  | 
|  | MYBIPA:		.DW	$A000		; Start address
 |  | 
|  | 		.DW	$0800		; Length
 |  | 
|  | 		.DW	$A000		; Entry address
 |  | 
|  |   |  | 
|  | MYSTACK:	.DB	2
 |  | 
|  |   |  | 
|  | TEMP:		.DB	2
 |  | 
|  |   |  | 
|  | 		.END
 |  | 
|  | 		
 |  | 
|  | </pre>
 |  | 
|  |   |  | 
|  | [[Category:Model T Developer Reference]]
 |  |