;****************************************************** ;* CUSTOM BIOS FOR CP/M 2.2, STOLEN FROM FERGUSEN * ;* BIG BOARD. MODIFIED FOR XEROX 820 USING SAMPLE * ;* BIOS FROM DIGITAL RESEARCH.(ASM85) * ;****************************************************** ; ; Mark Richey 11-March-1986 ; ; *** Modified to support modem control SIOB *** ; ; msize equ 60 ;mem in kbytes monitr equ 0f000h ;monitor residence baud equ 0ch ;channel b baud rate generator ; ; cpm constants ; bias equ (msize-20)*1024 ccp equ 3400h+bias bdos equ ccp+806h cbios equ ccp+1600h cdisk equ 04h iobyte equ 03h ; org cbios ; jmp boot ;jump table for xerox 820 bvectr: jmp wboot ;custom bios subroutines svectr: jmp const ivectr: jmp conin ovectr: jmp conout lvectr: jmp lstout ;list device vector jmp conout ;punch not configured jmp modmin ;reader device vector (tty input) jmp home jmp select jmp seek jmp setsel jmp setptr jmp read jmp write jmp lstst ;list device status jmp trans ; ; boot: xra a sta iobyte ;reset io byte to 0 sta cdisk lxi signon call pmsg ;print signon message jmp gocpm ; ; wboot: lxi sp,stack mvi c,0 call select ;select unit a call home ;seek track 0 lxi h,3400h+bias Š mvi b,0d02h call rdloop ;read even sectors lxi h,3480h+bias mvi b,0c03h call rdloop ;read odd sectors mvi c,1 call seek ;seek track 1 jnz bomb lxi h,4080h+bias mvi b,0a01h call rdloop ;read odd sectors lxi h,4100h+bias mvi b,0902h call rdloop ;read even sectors on 1 gocpm: mvi a,0c3h ;store jump vectors sta (00h) lxi h,cbios+3 ;jump to warm boot @ 0 shld (01H) sta (05H) lxi h,bdos ;jump to bdos at 5h shld (06H) sta (38H) lxi h,monitr ;jump to monitor at 38h shld (39H) mvi b,0080h call setptr ;disk buffer = 80h mvi c,0 jmp ccp ; ; rdloop: shld (pointr) ;store adr from hl mov a,c sta (sector) ;store sector from c push h push b call read pop b pop h jnz bomb inr h ;add 256 to load adress inr c inr c ;add 2 sectors dcr b jnz rdloop ret ; ; bomb: lxi h,dead call pmsg loop: jmp loop ; dead: db cr,lf dm 'cannot boot cp/m $' ; ; const: jmp monitr+6 ;monitor console status return ; Šconin: jmp monitr+9 ;monmitor console input return ; conout: mov a,c jmp monitr+12 ;monitor console output return ; lstout: mov a,c jmp monitr+15 ;monitor ptr (sio) return ; lstst: jmp monitr+18 ;monitor list status return ; modmin: jmp monitr+21 ;monitor siob input return ; ; ; ;*** DISK I/O SUBROUTINES **** ; ; ;Sector translation for 1 in 6 interleave. ; ; sectab: db 1,7,13,19 db 25,5,11,17 db 23,3,9,15 db 21,2,8,14 db 20,26,6,12 db 18,24,4,10 db 16,22 ; ; ; Disk Parameter Block for 8" Floppy ; dpblk: dw 26 ;sectors per trk db 3 ;block shift constant db 7 ;block mask db 0 ;extent mask dw 242 ;max block dw 63 ;max dir db 11000000b ;msb allocation db 00000000b ;lsb allocation dw 16 ;check size dw 2 ;reserved trks ; ; ; Disk param headers for 4 disks ; ; dphtab: dw sectab,000h ;unit 0,a dw 000h,000h dw dirbuf,dpblk dw chk0,all0 dw sectab,0000h ;unit 1,b dw 0000h,0000h dw dirbuf,dpblk dw chk1,all1 dw sectab,000h ;unit 2,c dw 000h,000h dw dirbuf,dpblk dw chk2,all2 dw sectab,000h ;unit 3,d dw 0000h,0000h dw dirbuf,dpblk dw chk3,all3 ; ; ; setsec: mov a,c sta (sector) ;store sector number from b ret ; ; trans: xchg d,h ;add translation table address dad b ;passed in d to sector in b mov l,(h) mvi h,0 ;find physical sector ret ;and return in h ; ; setptr: mov l,c ;low order address mov l,m ;hi order address shld (pointr) ;save the address select: lxi h,0 ;error return code mov a,c cpi 4 rnc ;retr with hl=0 if c>3 sta (unit) ;store c as new drive # mov l,a dad h dad h dad h dad h ;mult unit by 4 lxi d,dphtab dad d ;add start push h mov c,a ;load drive number mvi b,0 ;load seek speed call monitr+27 pop h rz ;exit if successful pop h mvi c,l call report jnz sel2 ;jump if abort lda (unit) ;else try again mov c,a jmp select sel2: mvi h,0 ;disable bdos calls ret ; ; ; home: call monitr+30 ;home routine in monitor rz ;back if all ok mvi c,2 call report jz home ;try again if no one home ret ; ; ; seek: mov a,c ;get track number sta (track) call monitr+33 ;seek routine in monitor rz ;leave if ok mvi c,2 call report ;tell console about it rnz ;return permanent error lda (track) ;unless retry indicated mov c,a jmp seek ; ; read: lhld (pointr) lda (sector) mov c,a call monitr+36 ;read routine in monitor rz ;back if oki doki mov c,3 ;tell bdos about it call report ;console wants to know too jz read ;try again? ret ; ; write: lhld (pointr) lda (sector) mov c,a call monitr+39 ;write routine in monitor rz ;see read, same line mov c,4 ;bdos again! call report ;console same jz write ;try again? ret ; ; report: sta (flags) ;1771 i/o status mov a,c sta (class) ;command error class lxi h,dskmsg call pmsg ;start message printout dcx h lda (class) mov b,a rep1: call skip ;skip to next $ dcr b jnz rep1 call pmsg ;print new string lxi h,errmsg call pmsg ;print 'error' after type lda (flags) ral ;test for drive not ready jmp rep8 ;and jump if thats it cpi 3 ;is it select/seek? jnc rep2 lxi h,skerrs ;point to proper messages rep2: mvi b,5 mov d,a ;reset bit 0 ani 00000001b mov a,d rep4: ; ; ; ; start again here insert from rep4 ; ; ; lf equ 0ah cr equ 0dh dskmsg: db cr,lf dm 'bios $' dm 'select $' dm 'seek $' dm 'read $' dm 'write $' errmsg: dm 'error $' skerrs: dm '$' dm '$' dm 'cannot seek$' dm 'bad crc$' dm 'cannot restore$' rdymsg: dm 'drive not rdy-$' rwerrs: dm 'write protected$ dm 'write fault$' dm 'record not found$' dm 'bad crc$' dm 'data overrun$' tsmsg: dm 'trk/sect = $' signon: db cr,lf dm '60k CP/M version 2.2' db cr,lf dm 'custom version for xerox 820' db cr,lf dm 'on line bullitin board---M.R. Apr. 86' db cr,lf db cr,lf dm 'channel B baud = 1200' crlf: db cr,lf db '$' ; ; unit: ds 1 track: ds 1 sector: ds 1 pointr: ds 1 flags: ds 1 class: ds 1 ds 32 stack: ds 1 ;local stack for wboot ; ; ;***** Disk I/O buffers for bdos ***** ; ; dirbuf: ds 128 ;scratch directory ; all0: ds 32 ;unit a allocation chk0: ds 16 ;unit 0 check all1: ds 32 chk1: ds 16 all2: ds 32 chk2: ds 16 all3: ds 32 chk3: ds 16 ; ; db 1,baud db 00000111b ;1200 baud ; end