; CP/M BIOS for avrcpm
; Copyright (C) 2010 Sprite_tm
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see .
;
; $Id: bios.asm 71 2010-08-06 19:38:10Z leo $
;
maclib CFGACPM.LIB
cr equ 0dh
lf equ 0ah
aseg
org 100h
.phase bios
.z80
nsects equ ($-ccp)/128 ;warm start sector count
jp boot
wboote:
jp wboot
jp const
jp conin
jp conout
jp list
jp punch
jp reader
jp home
jp seldsk
jp settrk
jp setsec
jp setdma
jp read
jp write
jp listst
jp sectran
jp 0 ;zsdos (?)
jp 0 ;zsdos (?)
jp 0 ;zsdos (?)
jp clock ;zsdos compatible clock set/get
.8080
maclib AVRCPM.LIB
;Drive A B C D E F G H I J K L
;drvtbl:dtbl
;drvtbl:dtbl
;drvtbl: dtbl < , , , , , , , ,dphi,dphj,dphk,dphl>
drvtbl:dtbl < , , , , , , , ,dphi>
; Name spt bls dks dir cks off
; dpb dpb243, 26, 1024, 243, 64, 64, 2
; dpb dp8192s,32, 4096,2046, 512, 512, 2
; dpb dp8192, 32, 4096,2046,1024,1024, 2
; dpb dpbrd, 32, 1024, 56, 32, 0, 2
dpb rd192, 32, 1024, 192, 32, 0, 0
; dpb rd1016, 32, 2048, 508, 192, 0, 2
; dpb rd1024, 32, 2048, 512, 192, 0, 0
; dpb rd0960, 32, 2048, 480, 192, 0, 0
;dpha: dph dpb243
;dphb: dph dpb243
;dphc: dph dpb243
;dphd: dph dpb243
;dpha: dph dp8192s
;dphb: dph dp8192s
;dphc: dph dp8192
;dphd: dph dp8192
;dphi: dph rd1016
dphi: dph rd192
;dphj: dph rd1024
;dphk: dph rd1024
;dphl: dph rd0960
.z80
signon:
db cr,lf
db msize/10+'0'
db msize - (msize/10)*10 + '0' ;modulo doesn't work?
db "k cp/m vers 2.2"
msgnl: db cr,lf,0
msgnodisk:
db "No disk!"
db cr,lf,0
const:
in a,(UARTCSR)
and UARTRXRDY
ret z
or 0ffh
ret
conin:
in a,(UARTCSR)
rra
jp nc,conin
in a,(UARTDR)
ret
conout:
ld a,c
out (UARTDR),a
ret
list:
ret
listst:
ld a,0
ret
punch:
ret
reader:
ld a,01Fh
ret
prmsg:
ld a,(hl)
or a
ret z
push hl
ld c,a
call conout
pop hl
inc hl
jp prmsg
prhex:
ld a,c
push af
rra
rra
rra
rra
call prhexdigit
pop af
; fall thru
prhexdigit:
and 00fh
cp 10
jp c,prd1
add a,7
prd1:
add a,'0'
ld c,a
jp conout
boot:
ld sp,buff
ld hl,signon
call prmsg
ld a,low bcb
out (13),a
ld a, high bcb
out (14),a
xor a
ld (bootdsk),a
ld e,a
ld c,a
call seldsk
jp nz,boot0
ld hl,msgnodisk
call prmsg
halt
boot0:
call getdpb
ld a,(de) ;dpb[0] is sectors_per_track
ld (bootspt),a
ld e,0
ld c,'I'-'A'
call seldsk
jp z,boot1 ;no ram disk
call getdpb ;de = dpb of first ram disk
; Check, if we have reserved tracks.
ld hl,13
add hl,de
ld a,(hl) ;# of reserved tracks
inc hl
or (hl)
jp z,boot1 ;Skip if not.
; Save CPM to ram disk.
ld a,(de) ;sectors per track
ld (bootspt),a
ld a,'I'-'A'
ld (bootdsk),a
call home
ld b,nsects
ld c,0 ;track
ld d,1 ;sektor (0 based, skip ipl)
ld hl,ccp
store1:
push bc
push de
push hl
ld c,d
ld b,0
call setsec
pop bc ;dma
push bc
call setdma
ld c,0
call write
pop hl ;dma
ld de,128
add hl,de
pop de ;d = sec
pop bc ;b = # of secs, c = track
dec b
jp z,boot1
inc d
ld a,(bootspt)
dec a
cp d ;if sector >= spt then change tracks
jp nc,store1
ld d,0
inc c
push bc
push de
push hl
ld b,0
call settrk
pop hl
pop de
pop bc
jp store1
boot1:
xor a
ld (iobyte),a
ld (cdisk),a
jp gocpm
wboot: ;re-load CP/M
ld sp,buff
ld a,1 shl BOOT_FUNC ;init (de)blocking
out (22),a
ld a,(bootdsk)
ld c,a
ld e,0 ;clear reselection flag
call seldsk
call home
ld b,nsects
ld c,0 ;track
ld d,1 ;sektor (0 based)
ld hl,ccp
load1:
push bc
push de
push hl
ld c,d
ld b,0
call setsec
pop bc
push bc
call setdma
call read
cp 0 ;read error?
jp nz,wboot
pop hl
ld de,128
add hl,de
pop de
pop bc
dec b
jp z,gocpm
inc d
ld a,(bootspt)
dec a
cp d ;if sector >= spt then change tracks
jp nc,load1
ld d,0
inc c
push bc
push de
push hl
ld b,0
call settrk
pop hl
pop de
pop bc
jp load1
gocpm:
ld a,0c3h
ld (0),a
ld hl,wboote
ld (1),hl
ld (5),a
ld hl,bdos
ld (6),hl
ld bc,buff
call setdma
ld a,(cdisk)
ld c,a
jp ccp
msgSel: db 13,10,"Sel: ",0
getdpb:
ld de,10
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ;de = dpb
ret
seldsk:
ld a,c
out (15),a
ld a,e ;reselection bit
rrca
jp c,getdph ;skip, if disk already active
ld hl,0
in a,(15) ;querry, if disk exists
or a
ret z
getdph:
ld hl,drvtbl
ld b,0
add hl,bc
add hl,bc
ld a,(hl) ;get table entry for selected disk
inc hl
ld h,(hl)
ld l,a
or h ;return zero, if no entry (no disk)
ret
home:
ld a,1 shl HOME_FUNC
out (22),a
ld bc,0 ; same as seek to track 0
settrk:
ld a,c
out (16),a
ld a,b
out (17),a
ret
setsec:
ld a,c
out (18),a
ret
setdma:
ld a,c
out (20),a
ld a,b
out (21),a
ret
read:
ld a,1 shl READ_FUNC
out (22),a
in a,(22)
and 1
ret
write:
ld a,c
and 3 ;mask write type
or 1 shl WRITE_FUNC
out (22),a
in a,(22)
and 1
ret
sectran:
;translate sector bc using table at de, res into hl
ld h,b
ld l,c
ld a,d
or e
ret z
ex de,hl
add hl,bc
ld l,(hl)
ld h,0
ret
;------------------------------------------------------------------------
; ZSDOS clock drivers may use registers BC and D without restoring them,
; but must preserve the Z80's alternate and index registers.
; Other registers must be used exactly as follows:
;
; Enter: C = 00H to Read the Clock, 01H to Set the Clock
; DE = Address of a 6-byte field to Receive or from which
; to Set time in DateStamper format (BCD digits as:
; YY MM DD HH MM SS). 24-hour operation is assumed.
;
; Exit : A = 01H for a successful operation,
; 0FFH for a failure of any sort (Can't set, etc.)
;
; When Reading the Clock:
; E = Original contents of Entry value of DE plus 5
; HL = Entry value of DE plus 5 (Seconds field)
clock:
dec c
jr z,clk_set
inc c
ret nz
clk_get:
ld hl,5
add hl,de
push hl
ld bc,6*256 + CLOCKPORT-1
ld e,(hl)
clk_gl:
inc c
ind
jr nz,clk_gl
pop hl
jr clk_e
clk_set:
ld a,(hl)
cp 78h
ld a,19h
jr nc,clk_s1
ld a,20h
clk_s1:
out (CLOCKPORT+6),a
ld bc,6*256 + CLOCKPORT+6
clk_sl:
dec c
outi
jr nz,clk_sl
dec hl
clk_e:
ld a,1
ret
;------------------------------------------------------------------------
bcb: dw drvtbl
dw dirbuf
dw enddat
bootdsk:ds 1
bootspt:ds 1
.8080
endef
end