; cp/m basic input/output operating system (bios) ; ; 2.2 version of 10-27-80 ; .. copyright 1980 .. ; ; this module contains all the input/output ; routines for the cp/m system, excluding ; the disk routines. ; FFFF = true equ 0ffffh ;define value of true. 0000 = false equ not true ;define value of false. ; 0040 = msize equ 64 ;memory size in kbytes. 0002 = ndisks equ 2 ;number of disk drives 0016 = vers equ 22 ;cp/m version number 0012 = bvers equ 18 ;bios version number FFFE = onedsk equ not((((ndisks-1)+3)and 4)shr 2) if onedsk disk4 equ false disk3 equ false endif if not onedsk 0000 = disk4 equ (ndisks and 0000$0100b) shr 2 0000 = disk3 equ ndisks and 0000$0001b endif 0000 = dubsid equ false ;true for double sided drives. 0000 = intrp equ false ;set true for intrrupts allowed. FFFF = COLCNT EQU TRUE ;SET TRUE FOR NETRONICS TERMINAL 0050 = cpl equ 80 ;characters/line 0050 = llimit equ cpl ;characters/line ; 00C5 = cstat equ 0C5H ;console status port 00C5 = ccom equ 0C5H ;console command port 00C4 = cdata equ 0C4H ;console data port 00C9 = lstat equ 0C9H ;list status port. 00C9 = lcom equ 0C9H ;list command port. 00C8 = ldata equ 0C8H ;list data port. ; ; 0002 = ckbr equ 0000$0010b ;status bit on port 0. 0004 = cptr equ 0000$0100b ;printer ready bit. 0004 = lrbit equ cptr ;lister ready bit. ; 0003 = iobyte equ 3 ;address of i/o byte. 0004 = cdisk equ 4 ;current selected disk B000 = cbase equ (msize-20)*1024 ;bias for larger than 20k. E400 = cpmb equ cbase+3400h ;start of cp/m 2.2 EC06 = bdos equ cpmb+806h ;start of bdos 2.2 FA00 = bios equ cpmb+1600h ;base of bios 2.2 FA00 org bios 002C = nsects equ ($-cpmb)/128 ;number of sectors in it. 004D = trks equ 77 ;# of tracks/disk 001A = spt equ 26 ;sectors/track 0002 = off equ 2 ;# of reserved system trks ; ; i/o jump vector ; this is where cp/m calls whenever it needs ; to do any input/output operation. ; user programs may use these entry points ; also, but note that the location of this ; vector changes with the memory size. ; FA00 C3CBFA jmp boot ;from cold start loader. FA03 C335FB wboote: jmp wboot ;from warm boot. FA06 C380FB jmp const ;check console kb status. FA09 C389FB jmp conin ;read console char. FA0C C395FB jmp conot ;write console char. FA0F C3ECFB jmp list ;write listing char. FA12 C3F9FB jmp punch ;write punch char. FA15 C3F7FB jmp reader ;read reader char. FA18 C33AFC jmp home ;move disk to zero. FA1B C3FAFB jmp seldsk ;select disk drive. FA1E C33CFC jmp settrk ;seek to track in reg a. FA21 C392FC jmp setsec ;set sector number. FA24 C397FC jmp setdma ;set disk starting address. FA27 C3A3FC jmp read ;read selected sector. FA2A C303FD jmp write ;write selected sector. FA2D C3E5FB jmp ltbsy ;return list status. FA30 C39DFC jmp sectran ;sector translate. ; ; data byte for number of disk drives ; FA33 02 nodsks: db ndisks ; ; ; fixed data tables for tw0-drive standard ; ibm-compatible 8" disks ; ; disk parameter header for disk 00 FA34 54FA0000 dpbase: dw trans,0000h FA38 00000000 dw 0000h,0000h FA3C 9FFD6EFA dw dirbf,dpblk FA40 3EFE1FFE dw chk00,all00 ; disk parameter header for disk 01 FA44 54FA0000 dw trans,0000h FA48 00000000 dw 0000h,0000h FA4C 9FFD6EFA dw dirbf,dpblk FA50 6DFE4EFE dw chk01,all01 if disk3 or disk4 ; disk parameter header for disk 02 dw trans,0000h dw 0000h,0000h dw dirbf,dpblk dw chk02,all02 endif if disk4 ; disk parameter header for disk 03 dw trans,0000h dw 0000h,0000h dw dirbf,dpblk dw chk03,all03 endif ; ; ; sector translate vector ; FA54 01070D13 trans: db 1,7,13,19 ;sectors 1,2,3,4 FA58 19050B11 db 25,5,11,17 ;sectors 5,6,7,8 FA5C 1703090F db 23,3,9,15 ;sectors 9,10,11,12 FA60 1502080E db 21,2,8,14 ;sectors 13,14,15,16 FA64 141A060C db 20,26,6,12 ;sectors 17,18,19,20 FA68 1218040A db 18,24,4,10 ;sectors 21,22,23,24 FA6C 1016 db 16,22 ;sectors 25,26 ; dpblk: ;disk parameter block, common to all disks FA6E 1A00 dw spt ;sectors per track if not dubsid FA70 03 db 3 ;block shift factor FA71 07 db 7 ;block mask FA72 00 db 0 ;null mask FA73 F200 dw 242 ;disk size-1 FA75 3F00 dw 63 ;directory max FA77 C0 db 192 ;alloc 0 FA78 00 db 0 ;alloc 1 FA79 1000 dw 16 ;check size endif if dubsid db 4 ;block shift factor db 15 ;block mask db 0 ;null mask dw 246 ;disk size-1 dw 127 ;directory max db 192 ;alloc 0 db 0 ;alloc 1 dw 32 ;check size endif FA7B 0200 dw off ;track offset ; ; end of fixed tables ; ; ; signon message ; smsg: FA7D 0C0A0D db 12,10,13 FA80 4578706C6F db 'Explorer-85 ' FA8C 3634 db msize/10+'0',msize mod 10 +'0' FA8E 6B2043502F db 'k CP/M v',vers/10+'0','.',vers mod 10+'0' FA99 5B3264 db '[',ndisks+'0','d' if dubsid db 's' endif FA9C 2E31385D db '.',bvers/10+'0',bvers mod 10+'0',']' FAA0 0A0D db 10,13 FAA2 436F707972 db 'Copyright (c) 1980' FAB4 0A0D db 10,13 FAB6 4E6574726F db 'Netronics Research' FAC8 0A0D db 10,13 FACA 00 db 0 ; ; boot ; this section is executed whenever reset and run ; after the coldstart loader reads in ; the cp/m system. ; 00C5 = STAT51 EQU 0C5H 00C5 = cntl51 equ 0C5H 00C4 = rxd51 equ 0C4H 00CD = MODE51 EQU 0CDH 0027 = cmd51 equ 27H boot: FACB 3E88 MVI A,88H FACD D3CF OUT 0CFH FACF 3E00 MVI A,00H FAD1 D3CC OUT 0CCH FAD3 3E06 MVI A,06H FAD5 D3CD OUT 0CDH FAD7 3E01 MVI A,01H FAD9 D3CE OUT 0CEH FADB 3ECD mvi a,mode51 FADD D3C5 out cntl51 FADF D3C9 OUT CNTL51+4 FAE1 3E27 mvi a,cmd51 FAE3 D3C5 out cntl51 FAE5 D3C9 OUT CNTL51+4 FAE7 DBC4 in rxd51 FAE9 DBC8 IN RXD51+4 FAEB 318000 lxi sp,80h ;set stack pointer. if intrp ;if interrupts allowed, ei ;enable them here. endif FAEE AF xra a ;clear scratch area. FAEF 320400 sta cdisk FAF2 320300 sta iobyte ;do it! FAF5 0E05 mvi c,endz-startz ;get length of zero area. FAF7 2194FD lxi h,startz ;get scratch address. FAFA 77 bootl: mov m,a ;put zero in memory. FAFB 23 inx h ;increment pointer. FAFC 0D dcr c ;decrement counter. FAFD C2FAFA jnz bootl ;loop till done. FB00 3650 mvi m,llimit ;set line limit FB02 23 inx h ;point to latch byte FB03 3600 mvi m,0 ;set latch code = 0. FB05 217DFA lxi h,smsg ;print signon message. FB08 CD60FD call pmsg gocpm: ; ; set jumps into cp/m in lower memory. ; FB0B 3EC3 mvi a,0c3h ;put jmp to wboot FB0D 320000 sta 0 ;adr at zero. FB10 2103FA lxi h,wboote FB13 220100 shld 1 FB16 320500 sta 5 FB19 2106EC lxi h,bdos ;put jump to bdos FB1C 220600 shld 6 ;at adr 5,6,7. FB1F 218000 lxi h,80h ;set default dma adr. FB22 2292FD shld dmaadd FB25 3A0400 lda cdisk ;get disk number to FB28 4F mov c,a ;pass to ccp in c. FB29 C300E4 jmp cpmb ;jump to ccp. ; FB2C 216BFD rderr: lxi h,btmsg ;get address of "boot error". FB2F CD60FD call pmsg ;print it. FB32 CD89FB call conin ;read a char from console. ; ; warm-boot: read all of cp/m back in ; except bios, then jump to ccp. ; FB35 318000 wboot: lxi sp,80h ;set stack pointer. if intrp ;if interrupts allowed, ei ;allow them here. endif FB38 3A94FD lda diskno ;save disk no. FB3B 329EFD sta temp FB3E 0E00 mvi c,0 ;select disk zero. FB40 CDFAFB call seldsk FB43 CD3AFC call home ;move to track zero. FB46 C22CFB jnz rderr ;if error, print message. FB49 162C mvi d,nsects ;get # sectors for cp/m read. FB4B 010200 lxi b,2 ;track (b) = 0, sector (c) = 2. FB4E 2100E4 lxi h,cpmb ;get starting address. if intrp ;if intrrupts allowed, di ;disable them here. endif FB51 C5 rdblk: push b ;save b&c. FB52 48 mov c,b ;go to track in b. FB53 CD3CFC call settrk FB56 C1 pop b ;restore b&c. FB57 C22CFB jnz rderr ;if error, print message. FB5A 2292FD rblk1: shld dmaadd ;set starting address. FB5D CD92FC call setsec ;read starting at sector in c. FB60 CDA3FC call read FB63 C22CFB jnz rderr ;if error, print message. FB66 15 dcr d ;decrement sector count. FB67 CA77FB jz aldon ;all done when d=0. FB6A 0C inr c ;increment sector number. FB6B 79 mov a,c ;if sector no. FB6C FE1B cpi spt+1 ;if not sectors/track + 1 FB6E DA5AFB jc rblk1 ;keep reading on this track. FB71 0E01 mvi c,1 ;otherwise, reset sector = 1. FB73 04 inr b ;increment track no. FB74 C351FB jmp rdblk ;and read next track. FB77 3A9EFD aldon: lda temp ;restore disk no. if intrp ;if interrupts allowed, ei ;allow them again here. endif FB7A 3294FD sta diskno FB7D C30BFB jmp gocpm ;go back to cp/m. ; ; ; check console input status. ; const: FB80 DBC5 in cstat ;get status FB82 E602 ani ckbr ;look at flag bit stat$ret: FB84 3E00 mvi a,0 ;set a=0, for return FB86 C8 rz FB87 2F cma ;if ready (pressed) a=ff FB88 C9 ret ; ; read a character from console. ; conin: FB89 CD80FB call const ;get console status FB8C B7 ora a FB8D CA89FB jz conin ;not ready yet FB90 DBC4 in cdata ;get data byte mask: FB92 E67F ani 7fh ;make most sig. bit = 0. FB94 C9 ret ; ; write a character to the console device. ; conot: IF COLCNT FB95 E5 push h FB96 CDDAFB call conota ;output the char FB99 2199FD lxi h,lcount ;get char. counter FB9C 79 mov a,c ;get char. FB9D FE0C CPI 12 ;IS IT FORM FEED FB9F C2B7FB JNZ ISITCR ;JP TO ISITCR FBA2 C5 PUSH B FBA3 E5 PUSH H FBA4 0602 MVI B,2 FBA6 210000 LXI H,0 WAIT1: FBA9 2D DCR L FBAA C2A9FB JNZ WAIT1 FBAD 25 DCR H FBAE C2A9FB JNZ WAIT1 FBB1 05 DCR B FBB2 C2A9FB JNZ WAIT1 FBB5 E1 POP H FBB6 C1 POP B ISITCR: FBB7 FE0D cpi 13 ;is it 'cr' FBB9 CAD6FB jz slimit FBBC FE0A cpi 10 ;is it 'lf' FBBE CAC7FB jz lfeed FBC1 FE08 cpi 8 ;is it 'bs' FBC3 C2C8FB jnz getcnt FBC6 34 inr m lfeed: FBC7 34 inr m getcnt: FBC8 35 dcr m FBC9 C2D8FB jnz conxit FBCC 0E0D mvi c,13 ;echo a 'cr' FBCE CDDAFB call conota FBD1 0E0A mvi c,10 ;and a 'lf' FBD3 CDDAFB call conota slimit: FBD6 3650 mvi m,llimit ;reset counter conxit: FBD8 E1 pop h FBD9 C9 ret ENDIF conota: FBDA DBC5 in cstat ;read console status FBDC E604 ani cptr FBDE CADAFB jz conota ;loop until ready FBE1 79 mov a,c ;get character FBE2 D3C4 out cdata ;print it FBE4 C9 ret ; ; write a character on listing device ; ltbsy: FBE5 DBC9 in lstat ;read lister status FBE7 E604 ani lrbit ;look at ready bit FBE9 C384FB jmp stat$ret list: FBEC CDE5FB bsytst: call ltbsy ;check for busy FBEF B7 ora a ;set flags FBF0 CAECFB jz bsytst ;still busy ;lst:=lpt: FBF3 79 mov a,c ;get the char. FBF4 D3C8 out ldata ;print it. FBF6 C9 ret ;return from list. ; ; read paper tape ; reader: FBF7 3E1A mvi a,1ah ;cp/m eof returned for them. ; ; punch paper tape. ; punch: FBF9 C9 ret ;don't service them, just return. ; ; ; ; lisk i/o for the western digital 1771 ; controller chip ; ; version of 3-29-80 ; ; ; ; ; hlab set 8 ;8 for hd ld at beg of seek. stprat set 2 ;rate 1=6ms, 2=10ms, 3=20ms. ; 00E8 = disk equ 0e8h ;disk base address. 00E8 = dcom equ disk ;disk command port. 00E8 = dstat equ disk ;disk status port. 00E9 = track equ disk+1 ;disk track port. 00EA = sectp equ disk+2 ;disk sector port. 00EB = ddata equ disk+3 ;disk data port. 00EC = wait equ disk+4 ;disk wait port. 00EC = dcont equ disk+4 ;disk control port. 000A = rtcnt equ 10 ;retry count. ; ; ; select dsk number according to register c. ; FBFA 210000 seldsk: lxi h,0000h ;error return code FBFD 3A33FA lda nodsks ;get no. of dsks if not onedsk FC00 3D dcr a endif FC01 B9 cmp c FC02 D8 rc ;err ret if diskno > nodsks new$old: FC03 79 mov a,c ;get new dsk no. FC04 2194FD lxi h,diskno ;get adr of old dsk no. FC07 BE cmp m ;new = old? FC08 CA2AFC jz getdph ;yes, return = dph if onedsk push a ;save disk number. lxi h,mntmsg ;get adr of mount mess. call pmsg ;print "mount". pop a ;get dsk number. sta diskno ;update old with new. adi 'a' ;add ascii for 'a'. mov c,a ;put into c. call conot ;print it. call conin ;read a character endif if not onedsk selmor: FC0B 5E mov e,m ;put old dsk no. in d&e. FC0C 1600 mvi d,0 FC0E 2197FD lxi h,trtab ;get addr. of track table. FC11 E5 push h FC12 19 dad d ;add dsk no. to address. FC13 DBE9 in track ;read 1771 track reg. FC15 77 mov m,a ;put into table. FC16 59 mov e,c ;new disk no. in d$e. FC17 E1 pop h ;get addr. of track table FC18 19 dad d ;add dsk no. to addr. FC19 7E mov a,m ;get new track no. FC1A D3E9 out track ;put into 1771 track reg. FC1C 79 mov a,c ;update old dsk no. FC1D 3294FD sta diskno FC20 2136FC LXI H,SELECT$TABLE FC23 0600 MVI B,0 FC25 09 DAD B FC26 7E MOV A,M FC27 329AFD sta latch ;save new latch code. endif getdph: FC2A 2A94FD lhld diskno FC2D 29 dad h ;*2 FC2E 29 dad h ;*4 FC2F 29 dad h ;*8 FC30 29 dad h ;*16 FC31 1134FA lxi d,dpbase FC34 19 dad d ; = dpbase(diskno*16) FC35 C9 ret ;return from seldsk. SELECT$TABLE: FC36 00 DB 0 FC37 06 DB 6 FC38 0A DB 10 FC39 12 DB 18 ; ; move dsk to track zero. ; FC3A 0E00 home: mvi c,0 ;seek to track zero. ; ; set track no. to whatever is in register c. ; also perform move to correct track (seek). ; settrk: if not dubsid ;if not double-sided dsk FC3C E5 push h ;save h&l. FC3D 2A9AFD lhld latch ;get new & old latch. FC40 7D mov a,l ;get new latch. FC41 D3EC out dcont ;select drv. now. FC43 329BFD sta clatch ;remember current latch. FC46 BC cmp h ;is it same as old? FC47 3EFF mvi a,0ffh ;if not, set flag = ff FC49 C24DFC jnz sflag FC4C 2F cma ;if new = old, flag = 0. FC4D 3296FD sflag: sta hlsf ;set head-load/select flag. FC50 E1 pop h ;restore h&l. endif FC51 79 mov a,c ;get new track no. if dubsid ;if double-sided dsk rrc ;shift right once push psw ;save revised trk # push h lhld latch ;get new & old latch mov a,l ;put new latch in a jc side2 ;if trk # odd, side #2 ani 1eh ;clear latch bit for side 1 jmp setlat ;go ahead and set latch side2: ori 1 ;set latch bit for side 2 setlat: out dcont ;output to the latch sta clatch ;set current latch code xra h ;compare old with new ani 1eh ;ignore side bit mvi a,0ffh ;if old not = new, jnz setfl ; set flag = ff cma ;if old = new, flag = 0 setfl: sta hlsf ;set flag zero if same pop h pop psw ani 7fh ;clear msb mov c,a ;set c = trk # endif FC52 3290FD sta trk ;update old with new. ; ; move head to the track in register a. ; FC55 C5 seek: push b ;save b&c. FC56 47 mov b,a ;save destination track. FC57 3E0A mvi a,rtcnt ;get retry count. FC59 329DFD sretry: sta sercnt ;store in error counter. FC5C DBE9 in track ;read present track no. FC5E 4F mov c,a ;save in c. FC5F 79 mov a,c ;delay. FC60 B8 cmp b ;same as new track no.? FC61 78 mov a,b ;restore a from b. FC62 C267FC jnz nothr ;jump if not there. FC65 C1 there: pop b ;restore b&c. FC66 C9 ret ;return from seek. nothr: ; ; this routine is to allow time for the drive ; tunnel erase to terminate before moving the ; head. the delay is approx. 700 micro-sec. @ ; 4 mhz cpu time, and double this for 2 mhz cpu's. ; FC67 F5 push psw ;save accum and flags FC68 3ED0 mvi a,0d0h ;delay count = 208 FC6A 3D busy1: dcr a ;decrease count. FC6B C26AFC jnz busy1 ;loop till done FC6E F1 pop psw ;restore accum and flags. FC6F D3EB out ddata ;track to data register. FC71 DBE8 busy: in dstat ;read dsk status. FC73 0F rrc ;look a bit 0. FC74 DA71FC jc busy ;wait till not busy. FC77 3E1E mvi a,14h+stprat+hlab ;get step rate, do FC79 D3E8 out dcom ;seek with verify. FC7B DBEC in wait ;wait for intrq. FC7D DBE8 in dstat ;read status. FC7F E691 ani 91h ;look at bits. FC81 CA65FC jz there ;ok, if zero. FC84 3A9DFD lda sercnt ;get err cnt. FC87 3D dcr a ;decrement cnt. FC88 C259FC jnz sretry ;retry seek. FC8B C1 pop b ;restore b&c FC8C 2188FD lxi h,skmsg ;print "seek". FC8F C3CBFC jmp ermsg ;do common messages. ; ; set dsk sector no. ; FC92 79 setsec: mov a,c ;get sector no. FC93 3291FD sta sect ;put at sect # addr. FC96 C9 ret ;return from setsec. ; ; set dsk dma address. ; FC97 60 setdma: mov h,b ;move b&c to h&l. FC98 69 mov l,c FC99 2292FD shld dmaadd ;put dma addr address. FC9C C9 ret ;return from setdma. ; ; translate the sector given by using the ; translate table given by ; sectran: FC9D EB xchg ; = trans FC9E 09 dad b ; = trans(sector) FC9F 6E mov l,m ; = trans(sector) FCA0 2600 mvi h,0 ; = trans(sector) FCA2 C9 ret ;with value in ; ; read the sector at sect, from the present track. ; use starting address at dmaadd. ; FCA3 3E0A read: mvi a,rtcnt ;get retry count. FCA5 CD2EFD rretry: call rw$retry ;store in error ctr. FCA8 C688 adi 88h ;add code for read sect. FCAA D3E8 reade: out dcom ;send command to 1771. FCAC DBEC rloop: in wait ;wait for drq or intrq. FCAE B7 ora a ;set flags FCAF F2B9FC jp rddone ;done if intrq. FCB2 DBEB in ddata ;get byte from dsk. FCB4 77 mov m,a ;put byte into memory. FCB5 23 inx h ;increment memory pointer. FCB6 C3ACFC jmp rloop ;keep reading. FCB9 DBE8 rddone: in dstat ;read dsk status. if intrp ;if interrupts allowed, ei ;allow again here. endif FCBB E69D ani 9dh ;look at error bits. FCBD C8 rz ;return if none. FCBE CDD7FC call erchk ;check for seek error. FCC1 3A9CFD lda ercnt ;get error count FCC4 3D dcr a ;decrement count. FCC5 C2A5FC jnz rretry ;try to read again. FCC8 2177FD lxi h,rdmsg ;print "read ". FCCB CD60FD ermsg: call pmsg ;print origin message. ermsg1: FCCE 2170FD lxi h,errmsg ;print "error." FCD1 CD60FD call pmsg FCD4 3E01 mvi a,1 ;set for perm err msg FCD6 C9 ret ; ; erchk - check for record not found error. ; erchk: FCD7 E610 ani 10h ;if record not found, FCD9 C8 rz ;return, no errors ; check for seek to correct track, ; and change if necessary. FCDA 3EC4 chksk: mvi a,0c4h ;send command to 1771 FCDC D3E8 out dcom ;to read address. FCDE DBEC in wait ;wait for drq or intrq. FCE0 DBEB in ddata ;read the track address. FCE2 47 mov b,a ;save in reg b. FCE3 DBEC chks2: in wait ;wait for intrq. FCE5 B7 ora a ;set flags. FCE6 F2EEFC jp chks3 ;done with read adr op. FCE9 DBEB in ddata ;read another byte. FCEB C3E3FC jmp chks2 ;do it again. FCEE DBE8 chks3: in dstat ;read dsk status. FCF0 B7 ora a ;set flags. FCF1 CAFAFC jz chks4 ;read adr ok if 0. FCF4 CD3AFC call home ;otherwise, home first. FCF7 C3FDFC jmp chks5 FCFA 78 chks4: mov a,b ;update track reg. FCFB D3E9 out track FCFD 3A90FD chks5: lda trk ;get required track no. FD00 C355FC jmp seek ;move head to it. ; ; write the sector at sect, on the present track. ; use starting address at dmaadd. ; FD03 3E0A write: mvi a,rtcnt ;get retry count. FD05 CD2EFD wretry: call rw$retry ;store in error counter. FD08 C6A8 adi 0a8h ;add code for write. FD0A D3E8 write2: out dcom FD0C DBEC wloop: in wait ;wait for ready. FD0E B7 ora a ;set flags. FD0F F219FD jp wdone ;hop when done. FD12 7E mov a,m ;get byte from mem. FD13 D3EB out ddata ;write onto dsk. FD15 23 inx h ;increment mem ptr. FD16 C30CFD jmp wloop ;keep writing. FD19 DBE8 wdone: in dstat ;read dsk status. if intrp ;if interrupts allowed, ei ;enable again here. endif FD1B E6FD ani 0fdh ;look at these bits. FD1D C8 rz ;return if no err. FD1E CDD7FC call erchk ;check/correct seek err. FD21 3A9CFD lda ercnt ;get error count. FD24 3D dcr a ;decrement count. FD25 C205FD jnz wretry ;try to write again. FD28 217FFD lxi h,wtmsg ;print "write ". FD2B C3CBFC jmp ermsg ; ; read / write retry subroutine ; rw$retry: FD2E 329CFD sta ercnt ;store in error counter FD31 2A92FD lhld dmaadd ;get starting addr. FD34 3ED0 mvi a,0d0h ;cause interrupt. FD36 D3E8 out dcom FD38 E3 xthl ;some delay FD39 E3 xthl if intrp ;if interrupts allowed, di ;disable them here. endif FD3A 3A91FD lda sect ;get sector no. FD3D D3EA out sectp ;set sector into 1771. ; ; hdld - get head-load bit if required. ; FD3F 3A96FD hdld: lda hlsf ;get head-load flag. FD42 B7 ora a ;is a = 0? FD43 CA57FD jz hdld1 ;hop if so. FD46 2F cma ;set a = 0. FD47 3296FD sta hlsf ;set flag = 0 if not. ; ; if changing to a new drive, perform a seek to ; the same track to allow the head to unload. ; FD4A DBE9 in track ;get present track FD4C D3EB out ddata ;and tell 1771 about it. FD4E 3E1E mvi a,14h+stprat+hlab ;get the step rate. FD50 D3E8 out dcom ;send it to floppy controller. FD52 DBEC in wait ;wait for intrq. FD54 3E04 hdldy: mvi a,4 ;set bit to load head. FD56 C9 ret ;return from hdld. FD57 DBE8 hdld1: in dstat ;read 1771 status. FD59 E620 ani 20h ;look at hl bit. FD5B CA54FD jz hdldy ;load if not loaded. FD5E AF xra a ;otherwise, a = 0. FD5F C9 ret ;return from hdld. ; ; print the message at h&l until a zero. ; FD60 7E pmsg: mov a,m ;get a char. FD61 B7 ora a ;if it's zero, FD62 C8 rz ;return FD63 4F mov c,a ;otherwise, FD64 CD95FB call conot ;print it. FD67 23 inx h ;increment h&l, FD68 C360FD jmp pmsg ;and get another. ; ; cbios messages ; FD6B 426F6F7420btmsg: db 'Boot ' FD70 4572726F72errmsg: db 'Error.',0 FD77 0D0A526561rdmsg: db 0dh,0ah,'Read ',0 FD7F 0D0A577269wtmsg: db 0dh,0ah,'Write ',0 FD88 0D0A536565skmsg: db 0dh,0ah,'Seek ',0 if onedsk mntmsg: db 0dh,0ah,'Mount ',0 endif ; bios scratch area. ; org $ FD90 trk: ds 1 ;current track no. FD91 sect: ds 1 ;current sector no. FD92 dmaadd: ds 2 ;disk transfer address ; ; the next several bytes, between startz and ; endz, are set to zero at cold boot time. ; FD94 org $ startz: ;start of zeroed area. FD94 diskno: ds 2 ;disk no. (to cp/m). ; special flags. FD96 hlsf: ds 1 ;head-load select flag. ; ; trtab - disk track table - present position of ; heads for up to ndisks drvs ; FD97 trtab: ds ndisks endz: ;end of zeroed area. ; FD99 org $ FD99 lcount: ds 1 ;character counter FD9A latch: ds 1 ;new code for latch FD9B clatch: ds 1 ;current code in latch. FD9C ercnt: ds 1 ;error count for retries FD9D sercnt: ds 1 ;seek retry counter FD9E temp: ds 1 ;temporary storage ; ; scratch ram area for bdos use ; FD9F = begdat equ $ ;beginning of data area FD9F dirbf: ds 128 ;scratch directory area if not dubsid FE1F all00: ds 31 ;allocation vector 0 FE3E chk00: ds 16 ;check vector 0 FE4E all01: ds 31 ;allocation vector 1 FE6D chk01: ds 16 ;check vector 1 endif if disk3 or disk4 and not dubsid all02: ds 31 ;allocation vector 2 chk02: ds 16 ;check vector 2 endif if disk4 and not dubsid all03: ds 31 ;allocation vector 3 chk03: ds 16 ;check vector 3 endif if dubsid all00: ds 32 ;allocation vector 0 chk00: ds 32 ;check vector 0 all01: ds 32 ;allocation vector 1 chk01: ds 32 ;check vector 1 endif if disk3 or disk4 and dubsid all02: ds 32 ;allocation vector 2 chk02: ds 32 ;check vector 2 endif if disk4 and dubsid all03: ds 32 ;allocation vector 3 chk03: ds 32 ;check vector 3 endif ; FE7D = enddat equ $ ;end of data area 00DE = datsiz equ $-begdat ;size of data area FE7D end