; 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,(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 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