; CP/M 2.2 boot-loader for Z80-Simulator
;
; Copyrigth (C) 1988 by Udo Munk
;
ORG 0 ; mem base of cp/m
;
MSIZE EQU 64 ; mem size in kbytes
;
BIAS EQU (MSIZE-20)*1024 ; offset from 20k system
CCP EQU 3400H+BIAS ; base of the ccp
BIOS EQU CCP+1600H ; base of the bios
BIOSL EQU 0300H ; length of the bios
BOOT EQU BIOS
SIZE EQU BIOS+BIOSL-CCP ; size of cp/m system
SECTS EQU SIZE/128 ; # of sectors to load
;
; I/O ports
;
DRIVE EQU 10 ; fdc-port: # of drive
TRACK EQU 11 ; fdc-port: # of track
SECTOR EQU 12 ; fdc-port: # of sector
FDCOP EQU 13 ; fdc-port: command
FDCST EQU 14 ; fdc-port: status
DMAL EQU 15 ; dma-port: dma address low
DMAH EQU 16 ; dma-port: dma address high
;
; begin the load operation
;
COLD: LD BC,2 ; b=track 0, c=sector 2
LD D,SECTS ; d=# sectors to load
LD HL,CCP ; base transfer address
LD A,0 ; select drive A
OUT (DRIVE),A
;
; load the next sector
;
LSECT: LD A,B ; set track
OUT (TRACK),A
LD A,C ; set sector
OUT (SECTOR),A
LD A,L ; set dma address low
OUT (DMAL),A
LD A,H ; set dma adress high
OUT (DMAH),A
XOR A ; read sector
OUT (FDCOP),A
IN A,(FDCST) ; get status of fdc
CP 0 ; read successful ?
JP Z,CONT ; yes, continue
HALT ; no, halt cpu
CONT:
; go to next sector if load is incomplete
DEC D ; sects=sects-1
JP Z,BOOT ; head for the bios
;
; more sectors to load
;
; we aren't using a stack, so use <sp> as scratch register
; to hold the load address increment
;
LD SP,128 ; 128 bytes per sector
ADD HL,SP ; <hl> = <hl> + 128
;
INC C ; sector = sector + 1
LD A,C
CP 27 ; last sector of track ?
JP C,LSECT ; no, go read another
;
; end of track, increment to next track
;
LD C,1 ; sector = 1
INC B ; track = track + 1
JP LSECT ; for another group
END ; of boot loader