; 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 $
;
msize equ 62 ;size of available RAM in k
bias equ (msize-20) * 1024
ccp equ 3400h+bias ;base of cpm ccp
bdos equ ccp+806h ;base of bdos
bios equ ccp+1600h ;base of bios
cdisk equ 0004h ;current disk number (0 ... 15)
iobyte equ 0003h ;intel iobyte
buff equ 0080h ;default buffer address
retry equ 3 ;max retries on disk i/o before error
cr equ 13
lf equ 10
READ_FUNC equ 7
WRITE_FUNC equ 6
BOOT_FUNC equ 5
HOME_FUNC equ 4
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
dphtab: dtbl
; Name spt bls dks dir cks off
dpb0: 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
const:
in a,(0)
ret
conin:
in a,(0)
cp 0ffh
jp nz,conin
in a,(1)
ret
conout:
ld a,c
out (2),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
xor a
ld (bootdsk),a
ld e,a
ld a,(dpb0)
ld (bootspt),a
ld c,'I'-'A'
call seldsk
ld a,h
or l
jp z,boot1
ld de,10
add hl,de
ld e,(hl)
inc hl
ld d,(hl) ;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
seldsk:
ld hl,dphtab
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 ;no entry, no disk
ret z ;
ld a,c
out (15),a
ld a,e ;reselection bit
rrca
ret c
; First select after (w)boot
in a,(15) ;querry, if disk exists
or a ;0 = disk is ok
ret z
ld hl,0 ;error return code
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
bootdsk:ds 1
bootspt:ds 1
.8080
endef
end