Z80 CPU boot.asm template

I am researching how to build a Z80 retro computer. For this I read about the Z80 and its instruction set. There are a couple of fixed addresses the Z80 CPU uses that you better get right. So I made a template file that can be the starting point of writing your own Z80 boot/bios ROM.

First of all there is !RESET (! means not or active low). The reset vector of the Z80 is address $0000 (hex). So here goes code that initializes your system.

But wait there is more…

Then there are the RST instructions. The first one RST00 jumps to address $0000. Sort of a soft reset. Your code might want to check if the current boot is from a hard reset or a soft reset.
Other RST instructions jump to addresses: $08, $10, $18, $20, $28, $30 and $38 (all on the first memory page, so the high byte of the address is $00). So all these locations should at least contain something to get your system going again. You could also think of these as shortcuts to often used bios functions.

But wait there is more…

In Interrupt Mode 1 and interrupt on the !INT pin of the Z80 will trigger an RST38 (hex). So if you want to allow IM1 you need to take that into account. Interrupt Mode 0 (the old 8080 mode) allows the interrupting device to put an instruction on the databus which the Z80 will execute. To make it easy, devices usually put RST instructions on the data bus. Personally I think this mode is less useful. Interrupt mode 2 provides a very flexible dispatch mechanism. When the !INT pin is put low by the interrupting device, a low address can be put on the data bus. This, together with the I register for the high address bits forms an address that contains a jump table with 16 bit addresses. Each address should be the start of an Interrupt Service Routine (ISR) for that specific interrupt/device. Up to 128 interrupts can be managed in this fashion.

So its important, if you use IM2 to determine a location for the ISR jump table (the value of the I register).

But wait there is more…

Finally there is the Non-Maskable Interrupt. When the !NMI pin is put low the Z80 jumps to address $66. The code that runs there should end with the RETN instruction.

All in all a nice list of fixed addresses you should take into account when writing a Z80 ROM.

 

 

; bios.asm
; Declares fixed addresses and startup routines

;
; Page 0 memory layout
;

; !RESET and RST00
ORG $0000
SEEK $0000
di ; from warm boot (rst00), interrupts may be enabled
jp ResetInit

; RTS08
ORG $0008
SEEK $0008
; di ; if you need interrupts disabled, do that here
jp BiosFn1

; RST10
ORG $0010
SEEK $0010
; di ; if you need interrupts disabled, do that here
jp BiosFn2

; RST18
ORG $0018
SEEK $0018
; di ; if you need interrupts disabled, do that here
jp BiosFn3

; RST20
ORG $0020
SEEK $0018
; di ; if you need interrupts disabled, do that here
jp BiosFn4

; RST28
ORG $0028
SEEK $0028
; di ; if you need interrupts disabled, do that here
jp BiosFn5

; RST30
ORG $0030
SEEK $0030
; di ; if you need interrupts disabled, do that here
jp BiosFn6

; RST38 and IM1
ORG $0038
SEEK $0038
; di ; if you need interrupts disabled, do that here
jp BiosFn7

; !NMI
ORG $0066
SEEK $0066
; The ISR for NMI goes here. Keep it short and sweet.
retn

;
; ISR Table (IM2) of 16-bit jump addresses (I=1) 256 bytes max
;

; ISR Table is located at page 1 ($0100).
ISR_TABLE: EQU 1
; Page 1
ORG $0100
SEEK $0100
; The lo address byte (A0-A7: A0=0) is put on the databus by the interrupting device.
; The hi address byte (A8-A15) is supplied by the I register that is initialized to (page) 1.
;DEFW ISR0 ; Address of ISR
;DEFW ISR1 ; Address of ISR
;DEFW ISR2 ; Address of ISR
;DEFW ISR3 ; Address of ISR
;DEFW ISR4 ; Address of ISR
;DEFW ISR5 ; Address of ISR
;DEFW ISR6 ; Address of ISR
;DEFW ISR7 ; Address of ISR
;DEFW ISR8 ; Address of ISR
;DEFW ISR9 ; Address of ISR
;DEFW ISR10 ; Address of ISR
;DEFW ISR11 ; Address of ISR
;DEFW ISR12 ; Address of ISR
;DEFW ISR13 ; Address of ISR
;DEFW ISR14 ; Address of ISR
;DEFW ISR15 ; Address of ISR
;DEFW ISR16 ; Address of ISR
;DEFW ISR17 ; Address of ISR
;DEFW ISR18 ; Address of ISR
;DEFW ISR19 ; Address of ISR
;DEFW ISR20 ; Address of ISR
;DEFW ISR21 ; Address of ISR
;DEFW ISR22 ; Address of ISR
;DEFW ISR23 ; Address of ISR
;DEFW ISR24 ; Address of ISR
;DEFW ISR25 ; Address of ISR
;DEFW ISR26 ; Address of ISR
;DEFW ISR27 ; Address of ISR
;DEFW ISR28 ; Address of ISR
;DEFW ISR29 ; Address of ISR
;DEFW ISR30 ; Address of ISR
;DEFW ISR31 ; Address of ISR
;
; DEFW ISR127 ; Address of ISR
; !!! Last ISR !!!
;
; Start of bios
;

; Page 2
ORG $0200
SEEK $0200

; Interrupts are disabled.
ResetInit:
ld a, i ; cold boot/hard reset would init I to $00
cp a, $00 ; is I zero?
jr nz, resetWarm ; nope – warm boot

; TODO
; MemoryTest to determine RAM_TOP

; Initialize Interrupt mode
ld a, ISR_TABLE ; load I with page 1 address
ld i, a ; for the ISR jump table at $0100
im 2 ; for IM2
; ResetInit jumps here if it detects a warm reset
resetWarm:
; Initialize SP

ei ; turn on interrupts

BiosFn1:
; bios function #1

BiosFn2:
; bios function #2

BiosFn3:
; bios function #3

BiosFn4:
; bios function #4

BiosFn5:
; bios function #5

BiosFn6:
; bios function #6

BiosFn7:
; bios function #7
; also used for IM1

 

Advertisements
Published in: on December 7, 2015 at 4:36 pm  Leave a Comment  

The URI to TrackBack this entry is: https://jacobielectronix.wordpress.com/2015/12/07/z80-cpu-boot-asm-template/trackback/

RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: