|
EPAC BIOS.
By Lee Davison. |
|
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
|