;******************************************************** ;* * ;* CP/M Bios for Software Publisher's ATR8000 * ;* copyright (c) 1984 by SWP Inc. * ;* * ;* last revision: 27-April-84 * ;* * ;******************************************************** ; ASEG ; ; BASE EQU 0D400H ;assemble equate for 'base' ; IF BASE LT 3400H .PRINTX /*** MAKING LOWER THAN 20K CBIOS ***/ ENDIF ; CCP EQU 0000H+BASE ;start of console command processor BDOS EQU 0800H+BASE ;start of resident disk os module CBIOS EQU 1600H+BASE ;start of custom bios IOBYTE EQU 0003H ;intel configuration byte IOCB EQU 0040H ;9 byte disk i/o control block IDBUFF EQU 0049H ;6 byte buffer for read-id TPA EQU 0100H ;start of transient program area MONITOR EQU 0F000H ;entrys into system monitor DISKDVR EQU MONITOR+15 OVRLAY EQU 0F700H ;ovrlay area for printer/comm drivers SCRATCH EQU 0F880H ;ram area for bios/cpm buffers SYSRAM EQU 0FF00H ;start of monitor ram page CTCVEC EQU SYSRAM+16 ;interrupt vectors for ctc here ; ; ; ... declare global variables ... ; GLOBAL RATEA,RATEB,RATEC,RATED GLOBAL IIOBYT GLOBAL IBAUD GLOBAL TXMASK GLOBAL SECTAB GLOBAL DD8IN,SD8IN,DD5IN,SD5IN GLOBAL NTRKSA,NTRKSB,NTRKSC,NTRKSD GLOBAL SIXTAB,FIVTAB GLOBAL ONEDSK GLOBAL XONXOF GLOBAL PRINTER ; ; ; .. i/o port equates .. ; CENTRON EQU 20H ;printer output/inputs LATCH EQU 30H ;drive control latch WD179X EQU 40H ;wd type disk controller ; SERIN EQU 50H ;rs232 serial input ; ATROUT EQU 50H ;atari serial output SEROUT EQU 51H ;rs232 serial output BANKSW EQU 52H ;rom bankswitch bit STROBE EQU 53H ;printer strobe INDXSET EQU 54H ;index control flop set DTR EQU 55H ;dtr output control INDXCLR EQU 56H ;index control flop clear CDMUX EQU 57H ;atari cmd/data mux control ; ATARI EQU 70H ;atari input bits port CTC0 EQU 80H ;zilog counter/timer CTC1 EQU 81H CTC2 EQU 82H CTC3 EQU 83H ; ; ; ; ... data structure for disk i/o control block ... ; DSKOP EQU 0 ;disk operation code DSKDRV EQU 1 ;drive# DSKTRK EQU 2 ;track# DSKSEC EQU 3 ;sector# DSKPTR EQU 4 ;read/write pointer DSKAUX EQU 6 ;auxilliary param bytes DSKSTS EQU 8 ;operation completion status ; ; ; ... disk driver operation code definitions ... ; TSTRDY EQU 0 ;select drive and test ready GETSEC EQU 1 ;read sector PUTSEC EQU 2 ;write sector GETID EQU 3 ;read id mark ; ; ; ; ; ; ... one sector loader for cp/m cold boot ... ; ; ORG TPA .PHASE 0080H ; ONESECT: LD SP,ONESECT ;put stack just below here LD IX,COLDCB ;point to iocb for cold boot LD B,14 ONESC2: PUSH BC CALL DISKDVR ;read 512 byte sector from track zero POP BC LD A,(COLDCB+DSKSTS) OR A JR NZ,BERROR ;exit boot loop if disk error LD A,(COLDCB+DSKSEC) INC A CP 11 ;check for sector# > 10 JR C,ONESC3 LD A,1 LD (COLDCB+DSKTRK),A ONESC3: LD (COLDCB+DSKSEC),A LD HL,COLDCB+DSKPTR+1 INC (HL) INC (HL) DJNZ ONESC2 ;read tk0/sec2..9 and tk1/sec1..6 LD HL,OVRLAY LD (COLDCB+DSKPTR),HL CALL DISKDVR ;read tk1/sec7 into overlay buffer LD A,(COLDCB+DSKSTS) OR A JR Z,ONESC4 ;execute cp/m coldstart if ok BERROR: LD A,'!' CALL MONITOR+12 LD HL,0 BERR2: DEC HL LD A,H OR L JR NZ,BERR2 JP MONITOR+3 ;then jump back to monitor ; ; arrive here if system loads successfully ; ONESC4: LD HL,DPHTAB LD (HL),0 LD DE,DPHTAB+1 LD BC,FREEMEM-DPHTAB-1 LDIR ;zero-out scratch memory for bios LD DE,NTRKSA LD HL,DPHTAB+NTRACKS ONESC5: LD A,(DE) AND 01111111B LD (HL),A ;store default value for 'ntracks' INC HL LD A,(DE) AND 10000000B LD (HL),A ;set value for bit 7 of 'flags' LD BC,DPHLEN-1 ADD HL,BC INC DE LD A,E CP LOW (NTRKSA+4) JR NZ,ONESC5 JP CBIOS ; ; ; COLDCB: DEFB GETSEC ;disk i/o control block for loader DEFB 0 DEFB 0 DEFB 2 DEFW CCP DEFW 512 DEFB 0 ; ; .DEPHASE ; ; ; ; ORG TPA+128 .PHASE CBIOS ; ; ... cbios jump table ... ; JP BOOT ;standard jump table to JP WBOOT ;the subroutines of cbios JP OVRLAY+0 IVEC: JP OVRLAY+3 OVEC: JP OVRLAY+6 LVEC: JP LIST JP OVRLAY+18 ;comm output is punch JP OVRLAY+15 ;comm input is reader JP HOME JP SELENTRY ;do 'seldisk' with ix save JP SETTRACK JP SETSECT JP SETDMA JP RDENTRY ;do 'readdb' with ix save JP WRTENTRY ;do 'writedb' with ix save JP DUMMY JP SECTRAN ; ; TXMASK: DEFB 00000010B ;'xor' mask for serial printer DEFB 00000010B ;'and' mask RXDATA: DEFB 0 ;temp for rs232 receive routine COMCTL: DEFB 0 ;copy of rs232 init control byte RXDAV: DEFB 0 ;rs232 data available flag ; ; ; ... entry points for complex disk routines ... ; SELENTRY: LD HL,SELDISK JR SSTK ; RDENTRY: LD HL,READDB JR SSTK ; WRTENTRY: LD HL,WRITEDB SSTK: LD (SPSAVE),SP LD SP,BIOSTK PUSH IX CALL GOTOHL POP IX LD SP,(SPSAVE) RET ; ; GOTOHL: JP (HL) ; ; ; ; ... cold boot entry point ... ; BOOT: LD HL,(MONITOR+24+1) LD (REINIT+1),HL ;set address for console re-init LD HL,REINIT ;patch new address in monitor vector LD (MONITOR+24+1),HL LD HL,BOOTAB CALL MOVE ;store constants from boot init table LD BC,10100011B OR (13 SHL 8) IBAUD EQU $-2 ;initial baudrate for rs232 port CALL OVRLAY+12 ;go program rs232 port LD HL,DIRBUF CALL PMSG ;display signon message in temp buffer LD HL,DUMMY LD (CBIOS+1),HL ;close the door on the way out LD HL,CCP PUSH HL ;put ccp entry address onto stach JR GOCPM ; ; ; BOOTAB: DEFB 2 DEFW IOBYTE IIOBYT: DEFB 10000001B ;initial iobyte DEFB 0 ;initial user#/drive# DEFB 4 DEFW 0FF28H RATEA: DEFB 16+2 ;initial settling times + step rates RATEB: DEFB 16+2 RATEC: DEFB 16+2 RATED: DEFB 16+2 BIOSTK EQU $ SPSAVE: DEFW 0 ;stack pointer save and table end mark ; ; ; ; ... warm boot entry point ... ; WBOOT: LD SP,0080H ;put stack in a fallow spot CALL FLUSH ;finish any deferred disk i/o XOR A LD (HSTDSK),A LD (HSTTRK),A LD A,2 LD (HSTSEC),A LD HL,CCP ;point to start of ccp and bdos LD (HSTPTR),HL LD HL,512 LD (DPHTAB+SECLEN),HL LD IX,DPHTAB RES 6,(IX+FLAGS) LD B,11 WBOOT2: PUSH BC LD A,GETSEC CALL DISKOP ;read 512 byte sector from sys tracks POP BC JP NZ,MONITOR+3 ;jump to monitor if sector is dead LD A,(HSTSEC) INC A CP 11 JR C,WBOOT3 LD A,1 LD (HSTTRK),A WBOOT3: LD (HSTSEC),A LD HL,HSTPTR+1 INC (HL) INC (HL) DJNZ WBOOT2 LD HL,CCP+3 PUSH HL ;push entry address for ccp GOCPM: LD HL,WBOOTAB CALL MOVE ;plug-in constants for warm boot LD HL,BDOS+8 LD A,(HL) CP H ;check for evidence of valid bdos load LD A,0 CALL NZ,REPORT ;force bios error code zero if no bdos JP NZ,MONITOR+3 ;then jump to ATRMON LD HL,IOBYTE+1 LD C,(HL) RET ;enter cp/m console comand processor ; ; ; WBOOTAB: DEFB 3 DEFW 0000H JP CBIOS+3 ;warmstart vector DEFB 3 DEFW 0005H JP BDOS+6 ;bdos vector DEFB 2 DEFW POINTR DEFW TPA-128 ;set initial dma pointer DEFB 0 ; ; ; ; MOVE: LD B,0 LD C,(HL) ;bc=bytecount from table @hl INC HL LD E,(HL) INC HL LD D,(HL) ;de=dest pointer from table @hl INC HL LDIR ;move data @hl to place @de LD A,(HL) OR A JR NZ,MOVE ;loop again if next byte @hl <> 0 DUMMY: XOR A RET ; ; ; INCLUDE DEBLOCK.MAC ;assemble deblocking disk drivers ; ; ; ... printer i/o routines ... ; PRINTER EQU $ ; LIST: LD A,(IOBYTE) RLA JP NC,MONITOR+12 ;goto console out if lst:=tty: or crt: RLA JR NC,PARALLEL ;goto parallel out if lst:=lpt: ; ; serial output with both hardwired and xonxoff handshake ; SERIAL: LD HL,(TXMASK) SERL2: IN A,(SERIN) XOR L ;set polarities of bits from rs232 AND H ;mask to bits of interest JR NZ,SERL2 ;loop till ready to transmit CALL OVRLAY+18 ;output character to rs232 port XONXOF: RET ;put nop here to enable xonxoff CALL OVRLAY+9 ;test for rs232 data available RET Z ;exit if nothing there CALL OVRLAY+15 RES 7,A CP 'S'-64 ;else get char and test if ctl-s RET NZ ;exit if no xoff received JP OVRLAY+15 ;else hang till another character ; ; ; ; parallel output via entry points in monitor ; PARALLEL: PUSH BC PARAL2: CALL MONITOR+21 ;call rom parallel output ready JR NZ,PARAL2 POP BC JP MONITOR+18 ;call rom printer output ; ; ; ; .DEPHASE ; ORG TPA+128+(6*256) .PHASE OVRLAY ;assemble rs232 port drivers here ; ; ; ... jump vectors for character i/o module ... ; JP CONST ;console status via iobyte JP CONIN ;console input via iobyte JP CONOUT ;console output via iobyte JP COMSTAT ;rs232 port status JP COMINIT ;rs232 port initialize JP COMINP ;rs232 character input JP COMOUT ;rs232 character output ; ; ; COMSTAT: LD A,(RXDAV) OR A RET Z ;return a=0 if no data available LD A,(RXDATA) LD C,A ;save character in c CALL PCHECK ;go derrive parity for character XOR C ;compare before and after pictures OR 00000001B RET ;msb=1 if parity err, lsb=1 forces <> 0 ; ; ; ; PCHECK: LD HL,COMCTL ;prepare to derrive parity bit for tx BIT 1,(HL) RET Z ;exit with a unchanged if parity off AND 01111111B ;else clear bit 7 and determine parity JP PO,PCHK2 SET 7,A ;make bit right for odd parity PCHK2: BIT 0,(HL) RET NZ ;exit if odd parity is selected XOR 10000000B ;else filp bit for even parity RET ; ; ; ; COMINP: LD A,(RXDAV) OR A JR Z,COMINP ;loop till 'rxdata' is non-zero XOR A LD (RXDAV),A ;then set byte to zero for next time LD A,(RXDATA) LD HL,COMCTL BIT 1,(HL) ;test parity enable bit in control word RET Z ;exit with bit 7 intact if disabled RES 7,A ;else clear parity bit before return RET ; ; ; ; ; ; ... interrupt for serial input start bit ... ; SBIT: PUSH AF LD A,10100111B DMODE EQU $-1 ;ctc cntrl word for data bit interrupt OUT (CTC2),A ;start baudrate interrupt LD A,13 DBAUD EQU $-1 ;count modulus for data baudrate OUT (CTC2),A ;program baudrate divide ratio LD A,LOW DBIT ;set vector for data bit interrupts LD (CTCVEC+4),A LD A,01111111B SBIT2: LD (RXTEMP),A POP AF EI RETI ; ; ; ; ... interrupt for serial input data bits ... ; DBIT: PUSH AF IN A,(SERIN) ;read rs232 input data port RLA LD A,NULL RXTEMP EQU $-1 RRA ;convert data stream into parallel JR C,SBIT2 ;jump if not last bit in word LD (RXDATA),A ;store received data LD A,LOW XBIT ;set vector for stop bit interrupt LD (CTCVEC+4),A POP AF EI RETI ; ; ; ; ; ... interrupt for serial input stop bit ... ; XBIT: PUSH AF LD A,10101111B SMODE EQU $-1 ;ctc mode for start bit interrupt OUT (CTC2),A ;enable interrupt from start bit again LD A,13/2 SBAUD EQU $-1 ;modulus for 1/2 baud time OUT (CTC2),A LD A,LOW SBIT ;set vector back to start bit routine LD (CTCVEC+4),A XBIT1: LD A,XBIT2-XBIT1-2 ;set to 'jr' if rx low at init time LD (RXDAV),A POP AF EI RETI ;takes 80 clock cycles ; ; XBIT2: LD A,3EH LD (XBIT1),A ;suff load acc immediate opcode POP AF EI RETI ;next rx character will be for real ; ; ; ; COMOUT: LD A,C CALL PCHECK ;derrive parity for character in c LD C,A LD HL,CTCVEC+2 CMOUT2: LD A,(HL) INC A ;loop till tx ctc turns itself off JR NZ,CMOUT2 ;(interrupt vector lsb set=ffh) DI LD E,(HL) ;save current ctc1 interrupt vector LD (HL),LOW STARBIT INC HL LD D,(HL) LD (HL),HIGH STARBIT DEC HL LD B,8 LD A,(DMODE) OUT (CTC1),A ;program ctc1 to interrupt at bit rate LD A,(DBAUD) OUT (CTC1),A ;set baudrate for transmit EI JR $ ;spin here till interrupts get us out ; ; ; ; ; ... damn fast transmit interrupts ... ; ; hl ... points to lsb of interrupt vector table for ctc1 ; de ... holds copy of previous ctc1 interrupt vector ; b ... used for djnz to count bits ; c ... used to pass character to irq ; ; STARBIT: XOR A OUT (SEROUT),A ;send start bit LD (HL),LOW DATBIT ;fix baudrate interrupt vector EI RETI ;return to idle loop ; ; ; DATBIT: LD A,C OUT (SEROUT),A ;send next data bit RR C ;then another lsb DJNZ DATB2 ;decrement and skip if not last bit LD (HL),LOW STOPBIT ;then fix vector for stop interrupt DATB2: EI RETI ;return to idle loop ; ; ; STOPBIT: LD A,255 OUT (SEROUT),A ;send stop bit now LD (HL),LOW EXITBIT EI RETI ;next interrupt is the finish ; ; ; EXITBIT: LD A,00000111B OUT (CTC1),A ;stop tx baudrate interrupt LD A,26 OUT (CTC1),A ;set console port to 9600 LD (HL),E ;set irq vector to indicate idle INC HL LD (HL),D ;restore old ctc1 interrupt vector EI POP HL ;discard irq return address and return RETI ; to second address on stack ; ; ; ; ; REINIT: CALL 0000H ;address filled in at cboot JR ZOOP ; ; COMINIT: LD A,B ;baudrate modulus is passed in b LD (DBAUD),A ;store number as data bit time const SRL A LD (SBAUD),A ;store 1/2 of that for start bit delay LD A,C LD (COMCTL),A ;save control word for parity stuff AND 00100000B ;use bit 5 of c as ctc prescale bit OR 10000111B LD (DMODE),A ;store data bit control byte OR 00001000B LD (SMODE),A ;store start bit control byte ZOOP: DI IN A,(SERIN) RLA JR C,ZOOP2 ;jump if serial input is high (mark) LD A,18H ;'jr' unconditional opcode byte JR ZOOP3 ; forces first rx to be discarded ; ZOOP2: LD A,3EH ;load acc immediate opcode ZOOP3: LD (XBIT1),A LD A,(SMODE) OUT (CTC2),A LD A,(SBAUD) OUT (CTC2),A ;re-init modem port rx interrupts LD HL,SBIT LD (CTCVEC+4),HL XOR A LD (RXDATA),A EI RET ; ; ; ; ... character i/o routines for console ... ; ; ; CONST: LD A,(IOBYTE) BIT 1,A JR NZ,CONST2 CALL MONITOR+6 ;call console status if con:=tty:/crt: RET Z LD A,255 RET ; CONST2: CALL OVRLAY+9 ;call rs232 status if con:=bat:/uc1: RET Z LD A,255 RET ; ; ; ; CONIN: LD A,(IOBYTE) BIT 1,A JR NZ,CONIN2 CALL MONITOR+9 RES 7,A RET ; CONIN2: CALL OVRLAY+15 ;call rs232 input if con:=bat:/uc1: RES 7,A RET ; ; ; CONOUT: LD A,(IOBYTE) BIT 1,A JR NZ,CNOUT2 RRA PUSH BC CALL NC,LIST ;echo to printer if con:=tty: POP BC JP MONITOR+12 ;goto console out for con:=tty:/crt: ; CNOUT2: RRA JP NC,LVEC ;goto printer output if con:=bat: JP OVRLAY+18 ;else goto rs232 out for con:=uc1: ; ; ; ; .DEPHASE ; ORG TPA+128+(6*256)+(3*128) DEFB '*****************************',CR,LF DEFB '** CP/M version 2.2 **',CR,LF DEFB '** for ATR8000 27-April-84 **',CR,LF DEFB '*****************************',CR,LF DEFB CR,LF,NULL ; ; ; PAGE ;******************************************************** ;* * ;* disk i/o buffers for bdos file handler * ;* * ;******************************************************** ; ; ; .PHASE SCRATCH DIRBUF: DEFS 128 ;scratch directory buffer BIGBUF: DEFS 1024 ; ; DPHTAB EQU $ DEFS 16 ;disk 0 disk parameter header DEFS 15 ;disk 0 disk parameter block DEFS 6 ;disk 0 deblock parameters DPHLEN EQU $-DPHTAB ;length of unit's parameter block DEFS 16 ;disk 1 disk parameter header DEFS 15 ;disk 1 disk parameter block DEFS 6 ;disk 1 deblock parameters DEFS 16 ;disk 2 disk parameter header DEFS 15 ;disk 2 disk parameter block DEFS 6 ;disk 2 deblock parameters DEFS 16 ;disk 3 disk parameter header DEFS 15 ;disk 3 disk parameter block DEFS 6 ;disk 3 deblock parameters ; ; ; ; NEW EQU $ SECTOR: DEFS 1 ;bios sector number TRACK: DEFS 1 ;bios track number DRIVE: DEFS 1 ;bios disk number POINTR: DEFS 2 ;bios dma pointer ; ; HOST EQU $ HSTSEC: DEFS 1 ;host sector number HSTTRK: DEFS 1 ;host track number HSTDSK: DEFS 1 ;host disk number HSTPTR: DEFS 2 ; HSTDPH: DEFS 2 ;host disk parameter pointer ; NEXT EQU $ NXTSEC: DEFS 1 ;next sector number NXTTRK: DEFS 1 ;next track number ; RCOUNT: DEFS 1 ;unalloc rec cnt SECTMP: DEFS 1 ;host equiv of sector# RDACT: DEFS 1 ;read buffer active flag WRTACT: DEFS 1 ;write buffer active flag DIR: DEFS 1 ;1 if read operation ; OLDDSK: DEFS 1 ;current drive# for single disk mode ; DPHPTR: DEFS 2 ;selected drive's dph pointer ; ; ; FREEMEM EQU $ ;free memory for alv/csv allocation ; .DEPHASE ; ; ; END