; 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
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
.8080
maclib AVRCPM.LIB
;Drive A B C D E F G H I J K L
;drvtbl: dtbl
drvtbl: dtbl
; 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 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
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,(0)
ret
conin:
in a,(0)
cp 0ffh
jp nz,conin
in a,(1)
ret
conout:
ld a,c
out (1),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
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
bcb: dw drvtbl
dw dirbuf
dw enddat
bootdsk:ds 1
bootspt:ds 1
.8080
endef
end