; 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