Up one EPAC BIOS. By Lee Davison. Up to top

Introduction.

The EPAC I received came without an EPROM or any other software. To be able to use it I worte a BIOS that supports EhBASIC, can download code as s-records and run or trace it and also supports a lot of EASy68K's TRAP #15 I/O calls so EASy68K can be used to write, assemble and test code for the EPAC.

Source

The source as presented will not run on an unmodified EPAC. It requires that IC7, the address decoder, be changed for one that supports a more expandable memory map. This is so that just one version of the BIOS will run to some degree on all memory sizes.

Instructions
  ***************************************************************************************
  *											*
  *	BIOS for EPAC 68008 2006/1/27. V0.70						*
  *											*
  *											*
  *	More 68000 and other projects can be found on my website at ..			*
  *											*
  *	 http://www.themotionstore.com/leeedavison/index.html				*
  *											*
  *	.. or ..									*
  *											*
  *	 http://members.lycos.co.uk/leeedavison/index.html				*
  *											*
  *	mail : leeedavison@lycos.co.uk							*
  *											*
  ***************************************************************************************

 Startup

	When started the BIOS will announce itself and then present a prompt for user
 input. Commands are case insensetive and may be entered in either case, as are the
 characters A to F when used in hexadecimal values. The following commands are available.

	help or ?
		Displays the brief help message.

	ver
		Display the BIOS version string.

	dn <hex>
		Display or set the value of data register n, where n is a single digit
		0 to 7 and <hex> is an optional, unsigned hexadecimal longword. So if
		you type d0 [Enter] the BIOS will respond with ..

		 = $xxxxxxxx

		.. where xxxxxxxx is the hexadecimal contents of d0. If however you type
		d0 deadbeef [Enter] then d0 will be set to the hexadevimal value DEADBEEF.

	an <hex>
		Display or set the value of address register n, where n is a single digit
		0 to 7 and <hex> is an optional, unsigned, hexadecimal longword.

	us <hex>
		Display or set the value of the user stack pointer. <hex> is an
		optional, unsigned, hexadecimal longword.

	pc <hex>
		Display or set the value of the user program counter. <hex> is an
		optional, unsigned, hexadecimal longword.

	regs
		Display the saved user registers. All the 680x0 registers are displayed
		in a layout similar to that used in the simulator window in Sim68K. 'A7'
		and the user stack pointer 'US' are the same register, changing one will
		change the other. When the monitor is first started the register contents
		will look like this ..

	                                                              T S  INT   XNZVC
	 D0 = 00000000 D4 = 00000000 A0 = 00000000 A4 = 00000000 SR = 0000000000000000
	 D1 = 00000000 D5 = 00000000 A1 = 00000000 A5 = 00000000 US = 00000000
	 D2 = 00000000 D6 = 00000000 A2 = 00000000 A6 = 00000000 SS = 000007FC
	 D3 = 00000000 D7 = 00000000 A3 = 00000000 A7 = 00000000 PC = 00000000


		These register values will be loaded into the corresponding registers when
		code is run or traced. After each instruction while tracing and at the end
		of a run program the saved values will be updated to reflect the current
		register values.

	run <hex>
		Executes code, in user mode, from the current user pc value or the hex
		value entered. Programs loaded with the load command (see later) can be
		started with run if the start address was set correctly in the assembly.
		<hex> is an optional, unsigned, hexadecimal longword.

	trace <hex>
		Single step code, in user mode, from the current user pc value or the hex
		value entered. Programs loaded with the load command (see later) can be
		started with trace if the start address was set correctly in the assembly.
		<hex> is an optional, unsigned, hexadecimal longword.

		The first time trace is executed after a load, or when trace <hex> is
		entered will just display the registers and the instruction at the user
		program counter. The prompt will change from '>>' to 'T>' and can
		now be stepped, instruction by instruction, by pressing enter. Registers can
		be examined or set though setting the program counter will exit the trace
		mode and the prompt will change back to '>>' requiring trace to be
		entered again to continue tracing.

	restart
		Restart the monitor. This executes the code in exactly the way that a power
		on reset would. The vector addresses are reset and the system base address
		and stack pointers reset to their original values. The time is reset to
		$00000000 and all the saved registers are cleared. Also the I/O devices are
		initialized.

	load
		Load an S-Record file into the host memory. After entering load the user
		will  be prompted to 'Send S-Record now'. As each record is received and
		loaded a '.' character is output to give some idea of progress. Most S-
		Record record types are recognised and used. Type 0 records are decoded
		and displayed as ASCII strings, types 7, 8 and 9 are used to load the
		start address of the code and also act as end of file markers.

		If all goes well then after the end record has been loaded the message
		'S-Record(s) loaded' will be displayed however during loading other mesages
		may appear.

		'S-Record error'
			There was an error in the record, either a non hex character in the
			stream or the checksum was incorrect. In this case nothing is saved
			to memory and the loader disregards the entire record.

		'S-Record too long'
			The record was too long to fit in the buffer and so was dropped. As
			records are not supposed to exceede 78 characters and the buffer is
			long enough for eighty character pairs this should never happen.

		'Unrecognised S-Record type'
			The record was received correctly but is of a type not used by the
			loader and so has been disregarded. Only record types 4, 5 and 6
			will cause this.

	time <hex>
		Display or set the system time in centiseconds since midnight. If no time or
		a time of more than 83D5FF is entered then the current system time count will
		be displayed. If a time is entered and is between 000000 and 83D5FF inclusive
		then the system time will be set to this value.

	basic <hex<,hex>>
		EhBASIC has been included as part of the BIOS and may be started by entering
		basic (see EhBASIC documentation for details on use). This version has the
		extra command EXIT that will quit EhBASIC and return to the BIOS monitor.

		If one hex value follows the basic command then this will set the default
		end of memory for EhBASIC and is an absolute address, this can still be
		overriden by inputting an end address in response to the "Memory size?"
		prompt. If a second hex value follows the first one this will set the start
		of memory for EhBASIC. By setting both start and end addresses you can have
		more than one BASIC workspace in memory at any time.

		E.g.

			>>basic			.. use all available memory
			>>basic 4000		.. use all available memory up to $4000
			>>basic 8000,4000	.. use memory from $4000 up to $8000
			>>basic 10000,8000	.. use memory from $8000 up to $10000

		Each area is independant and should remain unaffected by programs and
		variables in other workspace areas.

		Note that the end address is the next address after the last address that
		EhBASIC will use and should always be an even address.

	warm <hex>
		Re-enter EhBASIC without initializing the BASIC workspace. This means that
		any program in memory or variables should be unchanged. Note that you must
		have started EhBASIC by using the basic command, with a corresponding start
		address if used, before using warm to do the initial BASIC workspace setup.

 		If a hex value follows the warm command this will set the start address of
		the BASIC workspace. By setting this address you could chose which BASIC
		workspace in memory you will use.

		E.g.

			>>warm			.. use the default workspace
			>>warm 4000		.. use the workspace from $4000
			>>warm 8000		.. use the workspace from $8000

 System functions

 	Sim68K uses TRAP #15 calls to access system resources and, where possible, this
 BIOS emulates those calls. Obviously in any system that lacks the physical hardware
 for functions these functions are not available though they should still return
 practical values where possible. For example the file system calls, tasks 50 to 57
 mostly return an error indiaction as no storage devices are (currently) available.

	There are some extra task numbers not used in Sim68K that are used by the BIOS
 to assist in running and debugging user code, these are required by the BIOS monitor
 as some actions can only be performed in the supervisor state.

	The following are all the supported, or partly supported, Sim68K TRAP #15 tasks
 available in the BIOS as well as the BIOS' own TRAP #15 tasks.

	Text/Time/Terminate

	Task No.	Function
	--------	--------
	 0		Output the string at (a1), d1.w bytes long, with a carriage return
			and line feed. 
	 1		Output the string at (a1), d1.w bytes long, without a carriage return
			and line feed.
	 2		Read a [CR] terminated string from the input device to a buffer at
			(a1), the length is retuned in d1.w with a maximum langth of eighty
			characters.
	 3		Output d1.l as a leading zero supressed, signed, decimal number.
	 4		Read a signed decimal number from the input device into d1.l
	 5		Wait for a character from the input device and read it into d1.b
	 6		Write the character in d1.b to the output device.
	 7		Poll the input device, set d1.b = 1 if there ia a character pending
			else set d1.b = 0
	 8		Return time in hundredths of a second since midnight in d1.l
	 9		Terminate the program and return to the BIOS monitor.

	12		Set the input device echo, enter with d1.b = 0 to turn off the input
			device echo or with d1.b <> 0 to turn it on (default). 
			Echo is restored on 'Reset' or when a new file is loaded.

	13		Output the NULL terminated string at (a1) with a carriage return and
			line feed.
	14		Output the NULL terminated string at (a1) without a carriage return
			and line feed.
	15		Output the unsigned number in d1.l in the number base contained in d2.b.
			Values of d2.b outside the range 2 to 36 inclusive are ignored.

	17		A combination of task numbers 14 & 3. Output the NULL terminated string
			at (a1) without a carriage return and line feed then output d1.l as a
			leading zero supressed, signed, decimal number.
	18		A combination of task numbers 14 & 4. Output the NULL terminated string
			at (a1) without a carriage return and line feed then read a signed
			decimal number from the input device into d1.l
	19		Return a key scan code. On entry with d1.l = $00000000 the character
			code of the last character input is returned in d1.b
	20		Output d1.l as a leading zero supressed, signed, decimal number in a
			minimum of d2.b digits.

	Environment

	Task No.	Function
	--------	--------
	31		Return the cycle counter in d1.l. unless a cycle counter is fitted this
			function will always return d1.l = 00000000
	32		Get hardware values in d1.l. this function will ignore any set calls
			and always return d1.l = 00000000 for any get calls

	File I/O

	Task No.	Function
	--------	--------
	50		Close all files. This always returns without error and d0.w = $0000
	51		Open existing file. (a1) points to the null terminated file name. This
			always returns a null File-ID in d1.l and the error d0.w = $0002
	52		Open new file. As above this always returns a null File-ID in d1.l and
			the error d0.w = $0002
	53		Read d2.l bytes from the file identified by the FID in d1.l to (a1).
			This always returns the number of bytes actually read in d2.l as zero
			and the error d0.w = $0002
	54		Write d2.l bytes to the file identified by the FID in d1.l from (a1).
			This always the error d0.w = $0002
	55		Set the position where the next read/write will take place. This always
			the error d0.w = $0002
	56		Close the file identified by the FID in d1.l This always the error d0.w
			= $0002 
	57		Delete existing file. (a1) points to the null terminated file name.
			This always returns without error and d0.w = $0000

	Program control

	Task No.	Function
	--------	--------
	60		Output the registers. The registers are output in four lines in a
			similar layout to that used by Sim68K
	61		Disassemble the instruction at (a1). The opcode at (a1) is disassembled
			and output and a1 is returned pointing to the next opcode. If, on entry,
			a1 is odd then 'Address error' will be output and a1 will remain the
			same.
	62		Task 60 then task 61
	63		Execute user code from (a1). a1 is saved as the user program counter,
			the trace and supervisor bits are cleared in the saved status word. The
			saved register values are restored and the code is run from the current
			saved program counter. This code may return to the BIOS monitor using
			task 9 (see above).
	64		Execute user code. The trace and supervisor bits are cleared in the
			saved status word, the saved register values are restored and the code
			is run from the current saved program counter.
	65		Continue user code. the saved status word is left unchanged, the saved
			register values are restored and the code is run from the current saved
			program counter.
	66		Trace user code from (a1). The same as task 63 except the trace bit is
			set causing a return to the BIOS monitor after only one instruction has
			been executed.
	67		Trace user code. As task 64 except only one instruction is executed.
	68		Set supervisor mode. Sets the S bit in the status register.

	Sound I/O

	Task No.	Function
	--------	--------
	70		Play a .wav file. No sound is played, returns without error and with
			d0.w = FFFF
	72		Play sound from sound memory. No sound is played, returns without error
			and with d0.w = FFFF

	Graphics I/O

	Task No.	Function
	--------	--------
	83		Return the pixel colour at X,Y in d1.l. Always returns d1.l = 00000000

 Monitor messages

	There are a few times when BIOS messages will appear, these are usually the result
 of some error or other like not initialising values or registers. In a real 68000
 system the memory and registers may not be initialised to some predetermined value as
 they are in the simulator.

	Bus error

			Real 680x0 systems don't have the whole address range filled with
		memory so if you try to use some area that doesn't decode to memory or some
		I/O device this is usually the result.

	Address error

			An attempt was made to access a word or longword operand or an
		instruction at an odd address and this is the result. This will also
		happen if a stack operation is attempted with the stack pointer at an
		odd value as all stack actions are word or longword in size, even byte
		actions.

	Illegal instruction at $xxxxxxxx

			An attempt was made to execute an opcode that is not a valid
		instruction. The $xxxxxxxx is the address of the offending opcode.

	Divide by zero error

			A signed divide, DIVS, or unsigned divide, DIVU instruction will
		cause this if a division operation is attempted with a divisor of zero.

	CHK exception error

			The register tested in the CHK instruction was outide the range of
		0 to <ea>.

	TRAPV exception error

			A TRAPV instruction was executed with the overflow bit set.

	Privilage violation error

			All the code 'run' under the BIOS monitor, as well as the monitor
		itself, is always run in user mode. This means some instructions are
		unavailable such as STOP and RESET.

	Uninitialized interrupt error

			An interrupt has been generated but the address for the corresponding
		interrupt vector has not been set yet. This could also occur because an
		attempt has been made to use a vector from a device that has not had it's
		vector register initialised.

	Spurious interrupt error

			A bus error was encountered while trying to respond to an interrupt.
		This is most likely caused by setting a vector to an address that doesn't
		exist.

	Line A exception error

			An attempt was made to execute an opcode that starts with the
		patterm $Axxx

	Line F exception error

			An attempt was made to execute an opcode that starts with the
		patterm $Fxxx. Codes beginning with this pattern are implemented in the
		MC68020 and beyond as coprocessor instructions. This vector allows the
		unimplemented instructions to be emulated in software.

	Reserved exception error

			An interrupt has been generated but has ended up using on of the
		reserved vectors and that vector has not been set yet. There is nothing
		to stop the use of the reserved vectors but your code may break on other
		processors in the 680x0 family.

	Aborted

			The abort button was pressed and the code has been aborted and
		control returned to the monitor. If you press abort while in the monitor
		the saved user registers will be overwritten by the current register
		values.

 Things to remember when running Sim68K code

	You're running on a real 68008 that only has so much real memory some of which is
 needed by the BIOS. Your code should be set so that it starts clear of the BIOS memory
 and that it sets it's stack pointer on entry. The easiest way is with startup code like
 this ..
	ORG	$1000			* clear of BIOS area and stack

startup
	LEA	startup(pc),sp		* the stack grows down from startup	
Your code will be running in user mode so some instructions will not be available. Some programs use STOP to halt the program at the end but this is one of the privilaged instructions not available, instead use TRAP #15 task 9 to return to the monitor like this ..
exit_code
	MOVEQ	#9,d0			* terminate the program			
	TRAP	#15			* do I/O function


Last page update: 5th March, 2006. e-mail me e-mail