home *** CD-ROM | disk | FTP | other *** search
- ;=====================================================================
- ; MP/M-80 II Resident Extended Input/Output System, Version 1.0
- ;=====================================================================
- ;
- ; Copyright (C) 1981 ,by MICROCOSM.All rights reserved.No part may be
- ; reproduced,transmitted,transcribed ,stored in retrieval system, or
- ; translated into any language or computer language, in any form or
- ; by any means,electronic,mechanical,magnetic,optical,chemical,manual
- ; or otherwise, without the prior written permission of MICROCOSM,
- ; 3055 Waco St.,Simi Valley,California 93063.
- ;
- ; Disclaimer
- ; ==========
- ;
- ; MICROCOSM makes no representation or warranties with respect to the
- ; contents herof and specifically disclaims any implied warranties of
- ; merchantability or fitness for any particular purpose. Further ,
- ; MICROCOSM reserves the right to revise and to make changes from
- ; time to time in the content hereof without obligation of MICROCOSM
- ; to notify any person of such revision or changes.
- ;
- ;
- ;
- ;
- ; THIS MODULE CONTAINS ALL THE INPUT/OUTPUT ROUTINES FOR THE MP/M-80 II SYSTEM
- ;
- ;
- ; CONSOLE PORT #0 I/O PARAMETER EQUATES
- ;
- CCTRL EQU 010H ; CONSOLE STATUS PORT
- CCTRL EQU 010H ; CONSOLE COMMAND PORT
- CDATA EQU 011H ; CONSOLE DATA PORT
- CRRDY EQU 001H ; CONSOLE RECEIVER READY BIT
- CTRDY EQU 002H ; CONSOLE TRANSMITTER READY BIT
- CNULL EQU 000H ; CONSOLE NULL COUNT
- ;
- ; CONSOLE PORT #1 I/O PARAMETER EQUATES
- ;
- MCTRL EQU 01AH ; MODEM CONTROL/STATUS PORT
- MDATA EQU 01BH ; MODEM DATA PORT
- MRRDY EQU 001H ; MODEM RECEIVER READY BIT
- MTRDY EQU 002H ; MODEM TRANSMITTER READY BIT
- CARDET EQU 004H ; DATA CARRIER DETECT MASK
-
- ROMBOOT EQU 0F13DH ; ROM BOOT ENTRY ADDRESS
-
- ;
- ; VECTOR INTERRUPT/REAL TIME CLOCK I/O PARAMETER EQUATES
- ;
- VICNTRL EQU 0FEH ; 88-VI(RTC) CONTROL PORT
- FLAGSET EQU 133
- DSPTCH EQU 142
- ;
- ; VECTOR INTERRUPT/REAL TIME CLOCK VECTOR LEVEL EQUATES
- ;
- VEC1 EQU 0DDH ; VECTOR LEVEL 1 (RST 1), ADDRESS 0008 HEX
- ;
- ; DISK I/O PARAMETER EQUATES
- ;
- CNTRL EQU 0C0H ; ICOM 3712 DISK CONTROL COMMAND PORT
- DATAO EQU 0C1H ; ICOM 3712 DISK DATA OUT PORT
- DATAI EQU 0C0H ; ICOM 3712 DISK DATA IN PORT
- ;
- ; LIST DEVICE I/O PARAMETER EQUATES
- ;
- LSTAT EQU 002H ; LIST STATUS PORT
- LCOM EQU 002H ; LIST COMMAND PORT
- LDATA EQU 003H ; LIST DATA PORT
- LRBIT EQU 080H ; LISTER READY BIT
- LNULL EQU 000H ; LIST NULL COUNT
- LINCNT EQU 66 ; LINES PER PRINTER PAGE
- ;
- ; ASCII CHARACTER EQUATES
- ;
- RUBOUT EQU 7FH
- SPACE EQU 20H
- ;
- TDISKS EQU 2 ; NUMBER OF AVAILABLE DISKS
- ;
- NMBDEV EQU 6 ; NUMBER OF DEVICES IN POLL TABLE
- ;
- NMBCNS EQU 2 ; NUMBER OF CONSOLES
- ;
- POLL EQU 131 ; XDOS POLL FUNCTION
- ;
- PLLPT EQU 0 ; POLL PRINTER
- PLDSK EQU 1 ; POLL DISK
- PLCO0 EQU 2 ; POLL CONSOLE OUT #0
- PLCO1 EQU 3 ; POLL CONSOLE OUT #1 (MODEM)
- PLCI0 EQU 4 ; POLL CONSOLE IN #0
- PLCI1 EQU 5 ; POLL CONSOLE IN #1 (MODEM)
- ;
- RTCNT EQU 10 ; RETRY COUNT
- ;
- IOBYTE EQU 3 ; ADDRESS OF I/O BYTE
- ;
- OFFSET EQU 2 ; NUMBER OF TRACKS USED BY MP/M-80 II
-
- ORG 00000H ; START OF REL-0 XIOS FOR MP/M-80 II
- ;
- ; +++ I/O JUMP VECTOR +++
- ;
- ;
- JMP COMMONBASE ; COMMON BASE, TERMINATE PROCESS
- WBOOTE: JMP WBOOT ; WARM BOOT, TERMINATE PROCESS
- JMP CONST ; CONSOLE STATUS
- JMP CONIN ; CONSOLE CHARACTER IN
- JMP CONOUT ; CONSOLE CHARACTER OUT
- JMP LIST ; LIST CHARACTER OUT
- JMP PUNCH ; PUNCH NOT IMPLEMENTED
- JMP READER ; READER NOT IMPLEMENTED
- JMP HOME ; MOVE HEAD TO HOME
- JMP SELDSK ; SELECT DISK
- JMP SETTRK ; SET TRACK NUMBER
- JMP SETSEC ; SET SECTOR NUMBER
- JMP SETDMA ; SET DMA ADDRESS
- JMP READ ; READ DISK
- JMP WRITE ; WRITE DISK
- JMP POLLPT ; LIST STATUS
- JMP SECTRAN ; SECTOR TRANSLATE
- ;
- ; EXTENDED I/O SYSTEM JUMP VECTOR
- ;
- JMP SELMEMORY ; SELECT MEMORY
- JMP POLLDEVICE ; POLL DEVICE
- JMP STARTCLOCK ; START CLOCK
- JMP STOPCLOCK ; STOP CLOCK
- JMP EXITREGION ; EXIT REGION
- JMP MAXCONSOLE ; MAXIMUM CONSOLE NUMBER
- JMP SYSTEMINIT ; SYSTEM INITIALIZATION
- DB 0,0,0 ; IDLE PROCEDURE, NOT USED
-
- ;
- COMMONBASE: ; TERMINATE PROCESS
- ;
- JMP COLDSTART
- SWTUSER:JMP $-$
- SWTSYS: JMP $-$
- PDISP: JMP $-$
- XDOS: JMP $-$
- SYSDAT: DW $-$
- ;
- COLDSTART:
- WARMSTART:
- ;
- MVI C,0 ; SYETM RESET, TERMINATE PROCESS
- JMP XDOS
- ;
- ; MP/M-80 II CONSOLE HANDLERS
- ;
- CONST: ; CONSOLE STATUS
- CALL PTBLJMP ; COMPUTE AND JUMP TO HANDLER
- DW PT0ST ; CONSOLE #0 STATUS ROUTINE
- DW PT1ST ; CONSOLE #1 (MODEM) STATUS RT
-
- READER: ; READER NOT IMPLEMENTED
- MVI D,0 ; DEFAULT TO CONIN #0
-
- CONIN: ; CONSOLE INPUT
- CALL PTBLJMP ; COMPUTE AND JUMP TO HANDLER
- DW PT0IN ; CONSOLE #0 INPUT
- DW PT1IN ; CONSOLE #1 (MODEM) INPUT
-
- PUNCH: ; PUNCH NOT IMPLEMENTED
- MVI D,0 ; DEFAULT TO CONOUT #0
-
- CONOUT: ; CONSOLE OUTPUT
- CALL PTBLJMP ; COMPUTE AND JUMP TO HANDLER
- DW PT0OUT ; CONSOLE #0 OUTPUT
- DW PT1OUT ; CONSOLE #1 (MODEM) OUTPUT
-
- ;
- PTBLJMP: ; COMPUTE AND JUMP TO HANDLER
- ; D = CONSOLE #
- ; DO NOT DESTROY <D>
- MOV A,D
- CPI NMBCNS
- JC TBLJMP
- POP PSW ; THROW AWAY TABLE ADDRESS
- RTNEMPTY:
- XRA A
- RET
- TBLJMP: ; COMPUTE AND JUMP TO HANDLER
- ; A = TABLE INDEX
- ADD A ; DOUBLE TABLE INDEX FOR ADR OFFST
- POP H ; RETURN ADR POINTS TO JUMP TBL
- MOV E,A
- MVI D,0
- DAD D ; ADD TABLE INDEX * 2 TO TBL BASE
- MOV E,M ; GET HANDLER ADDRESS
- INX H
- MOV D,M
- XCHG
- PCHL ; JUMP TO COMPUTED CNS HANDLER
- ;
- ; CHECK CONSOLE INPUT STATUS
- ;
- ; POLL CONSOLE #0 INPUT
-
- POLCI0:
- PT0ST: ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN CCTRL ; READ CONSOLE STATUS
- ANI CRRDY ; LOOK AT RECEIVER READY BIT
- MVI A,0 ; SET A=0 FOR RETURN
- RZ ; NOT READY, WHEN 0
- MVI A,0FFH ; IF READY A=FF
- RET ; RETURN FROM POLCI0
- ;
- ; READ A CHARACTER FROM CONSOLE.
- ;
- ; CONSOLE #0 INPUT
- ;
- PT0IN: ; RETURN CHARACTER IN REG A
- MVI C,POLL
- MVI E,PLCI0
- CALL XDOS ; POLL CONSOLE #0 INPUT
- IN CDATA ; READ A CHARACTER
- ANI 7FH ; MAKE MOST SIG. BIT = 0
- CPI RUBOUT ; IS IT A RUBOUT?
- RNZ ; RETURN IF NOT
- MVI A,0FFH ; SET NO PRINT FLAG
- STA CONOTF
- MVI A,7FH ; RESTORE RUBOUT
- RET ; RETURN FROM PT0IN
- ;
- ; WRITE A CHARACTER TO THE CONSOLE DEVICE
- ;
- ; CONSOLE #0 OUTPUT
- ;
- PT0OUT: ; REG C = CHARACTER TO OUTPUT
- PUSH B
- CALL PT0WAIT ; POLL CONSOLE #0 OUTPUT
- POP B
- MOV A,C ; GET CHARACTER
- OUT CDATA ; PRINT IT
- RET ; RETURN FROM PT0OUT
- ;
- ; WAIT FOR CONSOLE #0 OUTPUT READY
- ;
- PT0WAIT:
- MVI C,POLL
- MVI E,PLCO0
- JMP XDOS ; POLL CONSOLE #0 OUTPUT
- ; RET
-
- ;
- ; POLL CONSOLE #0 OUTPUT
- ;
- POLCO0:
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN CCTRL ; READ CONSOLE STATUS
- ANI CTRDY ; IF NOT READY,
- MVI A,0 ; RETURN WITH ZERO'S
- RZ ; NOT READY, WHEN 0
- MVI A,0FFH
- RET ; RETURN FROM POLCO0
- ;
- ; WRITE A CHARACTER ON LISTING DEVICE
- ;
- LIST: ; LIST OUTPUT
- PUSH B
- PUSH D
- MVI C, POLL
- MVI E, PLLPT
- CALL XDOS
- POP D
- POP B
- MOV A,C ; GET DATA BYTE
- OUT LDATA ; PRINT IT
- RET ; RETURN FROM LIST
- ;
- ; RETURN LIST STATUS
- ;
- LISTST: XRA A ; FLAG LISTER NOT READY
- RET
-
- ;
- ; POLL PRINTER OUTPUT
- ;
- POLLPT:
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN LSTAT ; READ LISTER STATUS.
- ANI LRBIT ; LOOK AT READY BIT.
- MVI A,0 ; RETURN WITH ZERO'S IF NOT READY
- RNZ
- MVI A,0FFH
- RET
- ;
- ; POLL CONSOLE #1 (MODEM) INPUT
- ;
- POLCI1:
- PT1ST:
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN MCTRL ; GET MODEM STATUS
- ANI CARDET ; DATA CARRIER DETECT ON?
- JNZ RESTART ; EXIT, IF NO CARRIER
- IN MCTRL ; GET MODEM STATUS
- ANI MRRDY ; MASK MODEM RECEIVER READY
- MVI A,0 ; RETURN WITH ZERO'S
- RZ ; RETURN IF ZERO FLAG SET
- MVI A,0FFH ; IF READY,A=FFH
- RET ; RETURN FROM POLCI1
- ;
- ; CONSOLE #1 (MODEM) INPUT
- ;
- PT1IN:
- ; RETURN CHARACTER IN REG A
- IN MCTRL ; GET MODEM STATUS
- ANI CARDET ; DATA CARRIER DETECT ON?
- JNZ RESTART ; EXIT, IF NO CARRIER
- MVI C,POLL
- MVI E,PLCI1
- CALL XDOS ; POLL CONSOLE #1 INPUT
- IN MDATA ; GET MODEM DATA BYTE
- ANI 07FH ; STRIP OFF MSB FOR ASCII
- RET ; RETURN FROM CONIN
- ;
- ; CONSOLE #1 (MODEM) OUTPUT
- ;
- PT1OUT:
- ; REG C = CHARACTER TO OUTPUT
- IN MCTRL ; GET MODEM STATUS
- ANI CARDET ; DATA CARRIER DETECT ON?
- JNZ RESTART ; EXIT, IF NO CARRIER
- PUSH B
- CALL PT1WAIT
- POP B
- MOV A,C ; GET CHARACTER
- OUT MDATA ; OUT TO MODEM
- RET ; RETURN FROM CONOUT
-
- ; WAIT FOR CONSOLE #1 (MODEM) OUTPUT READY
-
- PT1WAIT:
- MVI C,POLL
- MVI E,PLCO1
- JMP XDOS ; POLL CONSOLE #1 OUTPUT
- ; RET
-
- ; POLL CONSOLE #1 (MODEM) OUTPUT
-
- POLCO1:
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN MCTRL ; GET MODEM STATUS
- ANI CARDET ; DATA CARRIER DETECT ON?
- JNZ RESTART ; EXIT, IF NO CARRIER
- IN MCTRL ; GET MODEM STATUS
- ANI MTRDY ; MASK MODEM TRANSMITTER READY
- MVI A,0 ; RETURN WITH ZERO'S
- RZ
- MVI A,0FFH ; IF READY,A=FFH
- RET ; RETURN FROM POLCO1
- ;
- ; WAIT FOR DATA CARRIER DETECT, THEN RESTART AT "BOOT"
- ;
- LIGHTS EQU 0FFH ; IMSAI FRONT PANEL DATA LIGHTS
- SWITCH EQU 0FFH ; IMSAI FRONT PANEL DATA SWITCHES
- ;
- RESTART:MVI B,10 ; SET MAJOR DELAY LOOP
- XRA A ; RESET FRON PANEL LIGHTS
- OUT LIGHTS
- DELAY: LXI H,0FFFFH; SET MINOR DELAY LOOP
- DELAY1: DCX H
- MOV A,H
- ORA L
- JNZ DELAY1 ; LOOP MINOR DELAY
- CMA ; SET FRONT PANEL LIGHTS
- OUT LIGHTS
- DCR B
- JNZ DELAY ; LOOP MAJOR DELAY
- MVI A,003H ; RESET MODEM 2SI/O PORT
- OUT MCTRL
- MVI A,011H ; SET 8 DATA BITS,2 STOP, NO PARITY
- OUT MCTRL
- CARWAIT:IN MCTRL ; GET MODEM STATUS, AND WAIT FOR CARRIER
- ANI CARDET ; DATA CARRIER DETECT ON?
- JNZ RESTART ; LOOP HERE 'TILL IT IS
- JMP ROMBOOT ; ROM BOOT WHEN READY
- ;
- ; MP/M-80 II EXTENDED I/O SYSTEM
- ;
- POLLDEVICE:
- ; REG C = DEVICE # TO BE POLLED
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- MOV A,C
- CPI NMBDEV
- JC DEVOK
- MVI A,NMBDEV; IF DEV # >= NMBDEV,
- ; SET TO NMBDEV
- DEVOK:
- CALL TBLJMP ; JUMP TO DEV POLL CODE
-
- DW POLLPT ; POLL PRINTER OUTPUT
- DW POLDSK ; POLL DISK READY
- DW POLCO0 ; POLL CONSOLE #0 OUTPUT
- DW POLCO1 ; POLL CONSOLE #1 (MODEM) OUTPUT
- DW POLCI0 ; POLL CONSOLE #0 INPUT
- DW POLCI1 ; POLL CONSOLE #1 (MODEM) INPUT
- DW RTNEMPTY; BAD DEVICE HANDLER
-
-
- ; SELECT / PROTECT MEMORY
-
- SELMEMORY:
- ; REG BC = ADR OF MEM DESCRIPTOR
- ; BC -> BASE 1 BYTE,
- ; SIZE 1 BYTE,
- ; ATTRIB 1 BYTE,
- ; BANK 1 BYTE.
-
- ; THIS HARDWARE DOES NOT HAVE MEMORY PROTECTION OR BANK SWITCHING
-
- RET
-
-
- ; START CLOCK
-
- STARTCLOCK:
- ; WILL CAUSE FLAG #1 TO BE SET
- ; AT EACH SYSTEM TIME UNIT TICK
- MVI A,0FFH
- STA TICKN
- RET
-
- ; STOP CLOCK
-
- STOPCLOCK:
- ; WILL STOP FLAG #1 SETTING AT
- ; SYSTEM TIME UNIT TICK
- XRA A
- STA TICKN
- RET
-
- ; EXIT REGION
-
- EXITREGION:
- ; EI IF NOT PREEMPTED
- LDA PREEMP
- ORA A
- RNZ
- EI
- RET
-
- ; MAXIMUM CONSOLE NUMBER
-
- MAXCONSOLE:
- MVI A,NMBCNS
- RET
-
- ; SYSTEM INITIALIZATION
-
- SYSTEMINIT:
- ;
- MVI A,003H ; CONSOLE AND MODEM RESET
- OUT CCTRL
- OUT MCTRL
- MVI A,011H ; NO INTERRUPTS,8 DATA BITS,NO PARITY,1 STOP BIT
- OUT CCTRL
- OUT MCTRL
- ;
- ; CLEAR XIOS VARIABLE AREA
- ;
- MVI C,ENDZ-STARTZ ; GET LENGTH OF ZERO AREA
- LXI H,STARTZ ; POINT TO THE START OF ZERO AREA
- CLEAR: XRA A ; MAKE ZERO
- MOV M,A ; JAM INTO MEMORY
- INX H ; BUMP POINTER
- DCR C ; DE-BUMP LENGTH
- JNZ CLEAR ; LOOP UNTIL ALL CLEARED
- ;
- ; SETUP RESTART JUMP VECTORS
- ;
- MVI A,0C3H
- STA 1*8
- LXI H,INT1HND
- SHLD 1*8+1 ; JMP INT1HND AT RESTART 1
- MVI A,0C9H ; RETURNS FOR ALL REMAINING INTERRUPT VECTORS
- STA 2*8
- STA 3*8
- STA 4*8
- STA 5*8
- STA 6*8
- MVI A,0F0H ; ENABLE VI AND RTC, RESET INTERRUPT, CLEAR COUNTERS
- OUT VICNTRL
- RET
-
- ; MP/M-80 II INTERRUPT HANDLERS
-
- INT1HND:
- ; INTERRUPT 1 HANDLER ENTRY POINT
- ;
- ; LOCATION 0008H CONTAINS A JMP
- ; TO INT1HND.
- PUSH PSW
- MVI A,VEC1 ; SET VECTOR LEVEL 1 (RST 1), ADDRESS 0008 HEX
- OUT VICNTRL
- LDA SLICE
- DCR A ; ONLY SERVICE EVERY 2ND SLICE
- STA SLICE
- JZ T40MS ; JUMP IF 40MS ELAPSED
- POP PSW
- EI
- RET
-
- T40MS:
- MVI A,4
- STA SLICE ; RESET SLICE COUNTER
- POP PSW
- SHLD SVDHL
- POP H
- SHLD SVDRET
- PUSH PSW
- LXI H,0
- DAD SP
- SHLD SVDSP ; SAVE USERS STK PTR
- LXI SP,INTSTK+48 ; LCL STK FOR INTR HNDL
- PUSH D
- PUSH B
-
- MVI A,0FFH
- STA PREEMP ; SET PREEMPTED FLAG
-
- LDA TICKN
- ORA A ; TEST TICKN, INDICATES
- ; DELAYED PROCESS(ES)
- JZ NOTICKN
- MVI C,FLAGSET
- MVI E,1
- CALL XDOS ; SET FLAG #1 EACH TICK
- NOTICKN:
- LXI H,CNT25
- DCR M ; DEC 25 TICK CNTR
- JNZ NOT1SEC
- MVI M,25
- MVI C,FLAGSET
- MVI E,2
- CALL XDOS ; SET FLAG #2 @ 1 SEC
- NOT1SEC:
- XRA A
- STA PREEMP ; CLEAR PREEMPTED FLAG
- POP B
- POP D
- LHLD SVDSP
- SPHL ; RESTORE STK PTR
- POP PSW
- LHLD SVDRET
- PUSH H
- LHLD SVDHL
-
- ; THE FOLLOWING DISPATCH CALL WILL FORCE ROUND ROBIN
- ; SCHEDULING OF PROCESSES EXECUTING AT THE SAME PRIORITY
- ; EVERY 40 MILLI-SECONDS.
- ;
- ; NOTE: INTERRUPTS ARE NOT ENABLED UNTIL THE DISPATCHER
- ; RESUMES THE NEXT PROCESS. THIS PREVENTS INTERRUPT
- ; OVER-RUN OF THE STACKS WHEN STUCK OR HIGH FREQUENCY
- ; INTERRUPTS ARE ENCOUNTERED.
-
- JMP PDISP ; MP/M DISPATCH
- ;
- ; FIXED DATA TABLES FOR TWO-DRIVE STANDARD IBM-COMPATIBLE 8" DISKS
- ;
- MACLIB DISKDEF ; DISK DEFINITION MACRO LIBRARY
-
- DISKS 2 ; TWO DISK SYSTEM
-
- DISKDEF 0,1,26,6,1024,243,64,64,OFFSET,(0)
- DISKDEF 1,0
- ;
- BOOT:
- WBOOT:
- MVI C,0
- JMP XDOS
-
- ;
- ; ROUTINE TO SELECT GIVEN BY REGISTER C
- ;
- SELDSK: MOV A,C ; GET NEW UNIT #
- LXI H,0 ; RETURN 0000 IN H&L REGS., IF ERROR
- CPI TDISKS ; BIGGER THAN # OF DISKS AVAILABLE?
- RNC ; OOPS.....
- STA UNITNO ; VALID UNIT #, SAVE IT
- MOV L,C ; L REG =DISK #
- DAD H ; *2
- DAD H ; *4
- DAD H ; *8
- DAD H ; *16
- LXI D,DPBASE; D&E REGS =DISK PARAMETER BASE
- DAD D ; H&L REGS =BIAS OFFSET INTO TABLE
- XRA A ; SET A = 0
- RET ; RETURN FROM SELDSK
- ;
- ; MOVE DISK TO TRACK ZERO
- ;
- HOME: MVI A,RTCNT ; GET RETRY COUNT
- HRETRY: STA SERCNT ; STORE IN SEEK ERROR COUNTER
- XRA A ; SET TRKNO TO ZERO
- STA TRKNO
- CALL XMTUS ; XMIT UNIT/SECTOR #
- MVI A,00DH ; SET SEEK TRACK ZERO COMMAND
- CALL XMITW ; XMIT AND WAIT
- RZ ; RETURN FROM HOME, IF O.K.
- CALL CLRER ; CLEAR DISK ERROR
- PUSH H ; SAVE CURRENT DMAADR
- LXI H,SECNT ; GET SEEK ERR COUNT ADDRESS
- INR M ; ONE MORE ERROR
- POP H ; RECOVER CURRENT DMAADR
- LDA SERCNT ; GET SEEK ERROR COUNT
- DCR A ; DECREMENT COUNT
- JNZ HRETRY ; TRY TO HOME AGAIN
- JMP EREXIT ; OOPS...PERMANENT DISK I/O ERROR
- ;
- ; SET TRACK NUMBER TO WHATEVER IS IN REGISTER C
- ; ALSO PERFORM MOVE TO THE CORRECT TRACK (SEEK)
- ;
- SETTRK: MOV A,C ; GET TRACK # INTO A REG
- CPI 0 ; TRACK ZERO REQUESTED?
- JZ HOME ; DO SEEK TRACK ZERO, IF SO
- STA TRKNO ; SAVE TRACK #
- MVI A,RTCNT ; GET RETRY COUNT
- SRETRY: STA SERCNT ; STORE IN SEEK ERROR COUNTER
- CALL XMTUS ; XMIT UNIT/SECTOR #
- CALL XMTTK ; XMIT TRACK #
- MVI A,009H ; SET SEEK TRACK COMMAND
- CALL XMITW ; XMIT AND WAIT
- RZ ; RETURN FROM SETTRK, IF O.K.
- CALL CLRER ; CLEAR DISK ERROR
- PUSH H ; SAVE CURRENT DMAADR
- LXI H,SECNT ; GET ADDRESS OF SEEK ERROR COUNTER
- INR M ; ONE MORE SEEK ERROR
- POP H ; RECOVER CURRENT DMAADR
- LDA SERCNT ; GET ERROR COUNT
- DCR A ; DECREMENT COUNT
- JNZ SRETRY ; RETRY SEEK
- JMP EREXIT ; ARGH.....
-
- ;
- ; TRANSLATE THE SECTOR GIVEN BY BC USING THE TRANSLATE TABLE GIVEN BY DE
- ;
- SECTRAN:MVI B,0 ; DOUBLE PRECISION SECTOR NUMBER
- XCHG ; TRANSLATE TABLE ADDRESS TO H&L REGS
- DAD B ; TRANSLATE SECTOR ADDRESS
- MOV A,M ; TRANSLATE SECTOR # TO A REG
- MOV L,A ; RETURN SECTOR # IN L REG
- RET ; RETURN FROM SECTRAN
- ;
- ; SET DISK SECTOR GIVEN BY REGISTER C
- ;
- SETSEC: MOV A,C ; GET SECTOR NUMBER
- STA SECNO ; PUT AT SECT # ADDRESS
- RET ; RETURN FROM SETSEC
- ;
- ; SET DISK DMA ADDRESS GIVEN BY REGISTER PAIR B AND C
- ;
- SETDMA: MOV H,B ; MOVE B&C TO H&L
- MOV L,C
- SHLD DMAADR ; PUT AT DMA ADR ADDRESS
- RET ; RETURN FROM SETDMA
- ;
- ; READ THE SECTOR AT SECT, FROM THE PRESENT TRACK
- ; USE STARTING ADDRESS AT DMAADR
- ;
- READ: MVI A,RTCNT ; GET RETRY COUNT
- RRETRY: STA ERCNT ; STORE IN ERROR CTR
- CALL XMTUS ; XMIT UNIT/SECTOR #
- MVI A,003H ; SET READ SECTOR COMMAND
- CALL XMITW ; XMIT AND WAIT
- JZ READOK ; IF READ O.K.,GET DATA FROM BUFFER
- CALL CLRER ; CLEAR DISK ERROR
- PUSH H ; SAVE CURRENT DMAADR
- LXI H,RECNT ; GET READ ERROR COUNT ADDRESS
- INR M ; ONE MORE ERROR
- POP H ; RECOVER CURRENT DMAADR
- LDA ERCNT ; GET ERROR COUNT
- DCR A ; DECREMENT COUNT
- JNZ RRETRY ; TRY TO READ AGAIN
- EREXIT: IN DATAI ; GET DISK STATUS
- STA IOERR ; SAVE ERROR STATUS
- MVI A,1 ; INFORM CP/M OF ERROR
- ORA A ; SET FLAGS
- RET
-
- READOK: LHLD DMAADR ; GET STARTING ADDRESS
- MVI D,128 ; SET BYTE COUNT
- MVI A,040H ; SET READ BUFFER COMMAND
- CALL XMT4X ; XMIT 04XH COMMAND
- INX H ; BUMP POINTER
- DCR D ; DE-BUMP BYTE COUNT
- READL: MVI A,041H ; GET DATA BYTE FROM BUFFER
- CALL XMT4X ; XMIT 04XH COMMAND
- INX H ; BUMP POINTER
- DCR D ; DE-BUMP BYTE COUNT
- JNZ READL ; LOOP UNTIL ALL BYTES IN
- RET ; RETURN FROM READ
- ;
- ; WRITE THE SECTOR AT SECT, ON THE PRESENT TRACK
- ; USE STARTING ADDRESS AT DMAADR
- ;
- WRITE: MVI A,RTCNT ; GET RETRY COUNT
- WRETRY: STA ERCNT ; STORE IN ERROR COUNTER
- LHLD DMAADR ; GET STARTING ADR
- MVI D,128 ; SET BYTE COUNT
- WRITEL: MOV A,M ; GET BYTE FROM DMAADR
- OUT DATAO ; SEND TO CONTROLLER
- MVI A,031H ; XMIT SHIFT WRITE BUFFER
- CALL XMIT
- INX H ; BUMP POINTER
- DCR D ; DE-BUMP BYTE COUNT
- JNZ WRITEL ; LOOP UNTIL ALL BYTES OUT
- CALL XMTUS ; XMIT UNIT/SECTOR #
- MVI A,005H ; SET WRITE COMMAND
- CALL XMITW ; XMIT AND WAIT
- RZ ; RETURN FROM WRITE, IF O.K.
- CALL CLRER ; CLEAR DISK ERROR
- PUSH H ; SAVE CURRENT DMAADR
- LXI H,WECNT ; GET ADR OF WRITE ERR CTR
- INR M ; ONE MORE WRITE ERROR
- POP H ; RECOVER CURRENT DMAADR
- LDA ERCNT ; GET ERROR COUNT
- DCR A ; DECREMENT COUNT
- JNZ WRETRY ; TRY TO WRITE AGAIN
- JMP EREXIT ; ARGH.....
- ;
- ; TRANSMIT UNIT AND SECTOR NUMBER
- ;
- XMTUS: LDA UNITNO ; GET UNIT NUMBER FOR DISK
- ANI 003H ; PRESERVE UNIT # ONLY
- RRC ; POSITION TO BITS 6&7 FOR 3712 CONTROLLER
- RRC
- MOV B,A ; SAVE IN B REG
- LDA SECNO ; GET SECTOR NUMBER
- ORA B ; MERGE UNIT NUMBER
- OUT DATAO ; SEND DATA OUT
- MVI A,021H ; XMIT UNIT/SECTOR NUMBER
- JMP XMIT
- ;
- ; TRANSMIT TRACK NUMBER
- ;
- XMTTK: LDA TRKNO ; GET TRACK NUMBER
- OUT DATAO ; SEND DATA OUT
- MVI A,011H ; XMIT TRACK NUMBER
- XMIT: PUSH PSW ; SAVE COMMAND
- DRCHK: IN DATAI ; GET DISK STATUS
- ANI 020H ; MASK FOR DRIVE NOT READY
- JNZ DRCHK ; LOOP UNTILL DISK READY
- POP PSW ; RECOVER COMMAND
- OUT CNTRL ; SEND CONTROL
- XRA A ; RESET CPU0 BIT
- OUT CNTRL ; SEND CONTROL
- RET
- ;
- ; TRANSMIT "BUSY" TYPE COMMAND, AND WAIT FOR "NOT BUSY"
- ;
- XMITW: CALL XMIT ; XMIT COMMAND
- BUSY: IN DATAI ; GET STATUS
- RAR ; SET BUSY FLAG
- JC BUSY ; LOOP IF BUSY
- IN DATAI ; GET DISK STATUS
- ANI 028H ; DISK NOT READY OR CRC ERROR?
- RET ; RETURN FROM XMITW WITH ERROR STATUS
- ;
- ; TRANSMIT "4X" (READ BUFFER OR SHIFT READ BUFFER) TYPE COMMAND
- ;
- XMT4X: OUT CNTRL ; SEND CONTROL
- IN DATAI ; GET DATA BYTE
- MOV M,A ; STUFF DATA BYTE INTO MEMORY
- XRA A ; RESET CPU0 BIT
- OUT CNTRL ; SEND CONTROL
- RET ; RETURN FROM XMT4X
-
- CLRER: MVI A,00BH ; CLEAR ERROR FLAGS
- CALL XMIT
- RET
-
- ;
- ; POLL DISK READY STATUS
- ;
- POLDSK:
- ; RETURN 0FFH IF READY,
- ; 000H IF NOT
- IN DATAI ; GET DISK STATUS
- ANI 020H ; MASK FOR DISK NOT READY
- MVI A,0 ; SET A REG. TO ZERO FOR POSSIBLE NOT READY
- RNZ
- MVI A,0FFH ; DISK IS READY
- RET
- ;
- ; SCRATCH RAM AREA REQUIRED FOR XIOS VARIABLES
- ;
- ; NOTE: AS THERE ARE ONLY SEVEN SECTORS
- ; AVAILABLE FOR XIOS ON THE SECOND SYSTEM TRACK (1),
- ; THE LAST ADDRESS BEFORE THIS POINT SHOULD BE NO
- ; GREATER THAN THE XIOS STARTING ADDRESS + 0380 (HEX).
- ;
- ;
- TRKNO: DS 1 ; CURRENT TRACK NUMBER
- SECNO: DS 1 ; CURRENT SECTOR NUMBER
- DMAADR: DS 2 ; DISK TRANSFER ADDRESS.
- ;
- ; THE NEXT SEVERAL BYTES, BETWEEN STARTZ AND
- ; ENDZ, ARE SET TO ZERO AT COLD BOOT TIME.
- ;
- STARTZ: ; START OF ZEROED AREA.
- UNITNO: DS 1 ; DISK NUMBER (TO MP/M)
- ;
- ; THESE LOCATIONS KEEP TRACK OF THE NUMBER OF ERRORS THAT OCCUR DURING
- ; READ, WRITE, OR SEEK OPERATIONS. THEY ARE INITIALIZED ONLY WHEN A
- ; COLD START IS PERFORMED BY THE BOOT STRAP.
- ;
- IOERR: DS 1 ; DISK I/O ERROR TYPE
- RECNT: DS 1 ; READ ERROR COUNTER
- WECNT: DS 1 ; WRITE ERROR COUNTER
- SECNT: DS 1 ; SEEK ERROR COUNTER
- ;
- ; SPECIAL FLAGS
- ;
- CONOTF: DS 1 ; NO PRINT FLAG (WHEN FF HEX)
- ;
- ENDZ: ; END OF ZEROED AREA
- ;
- NODSKS: DS 1 ; NUMBER OF DISKS
- ERCNT: DS 1 ; ERROR COUNTER FOR DISK I/O RETRIES
- SERCNT: DS 1 ; ERROR COUNTER FOR DISK SEEK RETRIES
- TEMP: DS 1 ; TEMPORARY DISK UNIT NUMBER
- ;
- SLICE: DB 4 ; 4 SLICES = 40MS = 1 TICK
- CNT25: DB 25 ; 25 TICK CNTR = 1 SEC
- INTSTK: DS 48 ; LOCAL INTRPT STK
- SVDHL: DW 0 ; SAVED REGS HL DURING INTERRUPT
- SVDSP: DW 0 ; SAVED SP DURING INTERRUPT
- SVDRET: DW 0 ; SAVED RETURN DURING INTERRUPT
- TICKN: DB 0 ; TICKING BOOLEAN,TRUE = DELAYED
- PREEMP: DB 0 ; PREEMPTED BOOLEAN
- ;
- ENDEF
- ;
- DB 0 ; FORCE OUT LAST BYTE IN HEX FIELD FOR RMAC
- ;
- END