Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,342 @@
; Figure 9-5
;
; This shows slightly more user-friendly error processor
; for disk errors than that shown in the enhanced BIOS
; in Figure 8-10.
; This version outputs a recommended course of action
; depending on the nature of the error detected.
; Code that remains unchanged from Figure 8-10 has been
; abbreviated.
;
; Dummy Equates and data declarations needed to get
; an error free assembly of this example.
;
Floppy$Read$Code EQU 01H ;Read Command for controller
Floppy$Write$Code EQU 02H ;Write Command for controller
;
Disk$Hung$Flag: DB 0 ;Set NZ when Watchdog timer times
; out.
Disk$Timer EQU 600 ;10 seconds delay (16.66ms tick)
;
Disk$Status$Block EQU 43H ;Address in memory where controller
; returns status
;Values from controller command table
Floppy$Command: DB 0
Floppy$Head: DB 0
Floppy$Track: DB 0
Floppy$Sector: DB 0
Deblocking$Required: DB 0 ;Flag set by SELDSK according
; to selected disk type
Disk$Error$Flag: DB 0 ;Error flag returned to BDOS
;
In$Buffer$Disk: DB 0 ;Logical disk Id. relating to current
; disk sector in deblocking buffer
;
; Equates for Messages
;
BELL EQU 07H ;Sound terminal Bell
CR EQU 0DH ;Carriage Return
LF EQU 0AH ;Line Feed
;
BDOS EQU 5 ;BDOS Entry Point (for system reset)
;
;
;
;
No$Deblock$Retry:
;----------------------------------------------------
; Omitted code to setup disk controller command table
; and initiate the disk operation
;----------------------------------------------------
JMP Wait$For$Disk$Complete
;
;
Write$Physical: ;Write contents of Disk Buffer to
; correct sector.
MVI A,Floppy$Write$Code ;Get Write Function code
JMP Common$Physical ;Go to common code
Read$Physical: ;Read previously selected Sector
; into Disk Buffer.
MVI A,Floppy$Read$Code ;Get Read Function code
Common$Physical:
STA Floppy$Command ;Set command table
;
Deblock$Retry: ;Re-entry point to re-try after error
;---------------------------------------------------
; Omitted code sets up disk controller command block
; and initiates the disk operation
;---------------------------------------------------
;
Wait$For$Disk$Complete: ;Wait until Disk Status Block indicates
; operation has completed, then check
; if any errors occurred.
;On entry HL -> Disk Control byte
XRA A ;Ensure hung flag clear
STA Disk$Hung$Flag
LXI H,Disk$Timed$Out ;Setup Watchdog timer
LXI B,Disk$Timer ;Time delay
CALL Set$Watchdog
Disk$Wait$Loop:
MOV A,M ;Get control byte
ORA A
JZ Disk$Complete ;Operation done
LDA Disk$Hung$Flag ;Also check if timed out
ORA A
JNZ Disk$Error ;Will be set to 40H
JMP Disk$Wait$Loop
Disk$Timed$Out: ;Control arrives here from Watchdog
; routine itself - so this is effectively
; part of the interrupt service routine.
MVI A,40H ;Set Disk Hung error code
STA Disk$Hung$Flag ; into error flag to pull
; control out of loop
RET ;Return to Watchdog routine
Disk$Complete:
LXI B,0 ;Reset Watchdog timer
;HL is irrelevant here
CALL Set$Watchdog
LDA Disk$Status$Block ;Complete - now check status
CPI 80H ;Check if any errors occurred
JC Disk$Error ;Yes
;
Disk$Error$Ignore:
XRA A ;No
STA Disk$Error$Flag ;Clear error flag
RET
;
; Disk Error Message handling
;
;
Disk$Error$Messages: ;This table is scanned, comparing the
; Disk Error Status with those in the
; table. Given a match, or even when
; then end of the table is reached, the
; address following the status value
; points to the correct advisory message text.
; Following this is the address of an
; error description message.
DB 40H
DW Disk$Advice1,Disk$Msg$40
DB 41H
DW Disk$Advice2,Disk$Msg$41
DB 42H
DW Disk$Advice3,Disk$Msg$42
DB 21H
DW Disk$Advice4,Disk$Msg$21
DB 22H
DW Disk$Advice5,Disk$Msg$22
DB 23H
DW Disk$Advice5,Disk$Msg$23
DB 24H
DW Disk$Advice6,Disk$Msg$24
DB 25H
DW Disk$Advice6,Disk$Msg$25
DB 11H
DW Disk$Advice7,Disk$Msg$11
DB 12H
DW Disk$Advice7,Disk$Msg$12
DB 13H
DW Disk$Advice7,Disk$Msg$13
DB 14H
DW Disk$Advice7,Disk$Msg$14
DB 15H
DW Disk$Advice7,Disk$Msg$15
DB 16H
DW Disk$Advice7,Disk$Msg$16
DB 0 ;<== Terminator
DW Disk$Advice7,Disk$Msg$Unknown ;Unmatched code
;
DEM$Entry$Size EQU 5 ;Entry size in Error Message Table
;
;
; Message Texts
;
Disk$Msg$40: DB 'Hung',0 ;Timeout message
Disk$Msg$41: DB 'Not Ready',0
Disk$Msg$42: DB 'Write Protected',0
Disk$Msg$21: DB 'Data',0
Disk$Msg$22: DB 'Format',0
Disk$Msg$23: DB 'Missing Data Mark',0
Disk$Msg$24: DB 'Bus Timeout',0
Disk$Msg$25: DB 'Controller Timeout',0
Disk$Msg$11: DB 'Drive Address',0
Disk$Msg$12: DB 'Head Address',0
Disk$Msg$13: DB 'Track Address',0
Disk$Msg$14: DB 'Sector Address',0
Disk$Msg$15: DB 'Bus Address',0
Disk$Msg$16: DB 'Illegal Command',0
Disk$Msg$Unknown: DB 'Unknown',0
;
Disk$EM$1: ;Main disk error message - part 1
DB BELL,CR,LF
DB 'Disk ',0
;
;Error Text output next
;
Disk$EM$2: ;Main disk error message - part 2
DB ' Error ('
Disk$EM$Status: DB 0,0 ;Status code in Hex
DB ')',CR,LF,' Drive '
Disk$EM$Drive: DB 0 ;Disk Drive code, A,B...
DB ', Head '
Disk$EM$Head: DB 0 ;Head number
DB ', Track '
Disk$EM$Track: DB 0,0 ;Track number
DB ', Sector '
Disk$EM$Sector: DB 0,0 ;Sector number
DB ', Operation - '
DB 0 ;Terminator
;
Disk$EM$Read: DB 'Read.',0 ;Operation names
Disk$EM$Write: DB 'Write.',0
;
Disk$Advice0: DB CR,LF,' ',0
Disk$Advice1: DB 'Check disk loaded, Retry',0
Disk$Advice2: DB 'Possible hardware problem',0
Disk$Advice3: DB 'Write enable if correct disk, Retry',0
Disk$Advice4: DB 'Retry several times',0
Disk$Advice5: DB 'Reformat disk or use another disk',0
Disk$Advice6: DB 'Hardware error, Retry',0
Disk$Advice7: DB 'Hardware or Software error, Retry',0
;
Disk$Advice9: DB ', or call for help if error persists',CR,LF
;
Disk$Action$Confirm:
DB 0 ;Set to character entered by user
DB CR,LF,0
;
; Disk Error Processor
;
; This routine builds and outputs an error message.
; The user is then given the opportunity to :
;
; R - Retry the operation that caused the error.
; I - Ignore the error and attempt to continue.
; A - Abort the program and return to CP/M.
;
Disk$Error:
PUSH PSW ;Preserve error code from controller
LXI H,Disk$EM$Status ;Convert code for message
CALL CAH ;Converts A to hex
LDA In$Buffer$Disk ;Convert disk id. for message
ADI 'A' ;Make into letter
STA Disk$EM$Drive
LDA Floppy$Head ;Convert head number
ADI '0'
STA Disk$EM$Head
LDA Floppy$Track ;Convert track number
LXI H,Disk$EM$Track
CALL CAH
LDA Floppy$Sector ;Convert sector number
LXI H,Disk$EM$Sector
CALL CAH
LXI H,Disk$EM$1 ;Output first part of message
CALL Output$Error$Message
POP PSW ;Recover error status code
MOV B,A ;For comparisons
LXI H,Disk$Error$Messages - DEM$Entry$Size
;HL -> Table - one entry
LXI D,DEM$Entry$Size ;For loop below
Disk$Error$Next$Code:
DAD D ;Move to next (or first) entry
MOV A,M ;Get code number from table
ORA A ;Check if end of table
JZ Disk$Error$Matched ;Yes - pretend a match occurred
CMP B ;Compare to actual code
JZ Disk$Error$Matched ;Yes - exit from loop
JMP Disk$Error$Next$Code ;Check next code
;
Disk$Error$Matched:
INX H ;HL -> Advisory text address
MOV E,M
INX H
MOV D,M ;DE -> Advisory test
PUSH D ;Save for later
INX H ;HL -> Message text address
MOV E,M ;Get Address into DE
INX H
MOV D,M
XCHG ;HL -> Text
CALL Output$Error$Message ;Display explanatory text
LXI H,Disk$EM$2 ;Display second part of message
CALL Output$Error$Message
LXI H,Disk$EM$Read ;Choose operation text
; (assume a read)
LDA Floppy$Command ;Get controller command
CPI Floppy$Read$Code
JZ Disk$Error$Read ;Yes
LXI H,Disk$EM$Write ;No - change address in HL
Disk$Error$Read:
CALL Output$Error$Message ;Display operation type
LXI H,Disk$Advice0 ;Display leading blanks
CALL Output$Error$Message
POP H ;Recover Advisory text pointer
CALL Output$Error$Message
LXI H,Disk$Advice9 ;Display trailing component
CALL Output$Error$Message
;
Disk$Error$Request$Action: ;Ask the user what to do next
CALL Request$User$Choice ;Display prompt and get single
; character response (folded to
; upper case)
CPI 'R' ;Retry?
JZ Disk$Error$Retry
CPI 'A' ;Abort
JZ System$Reset
CPI 'I' ;Ignore
JZ Disk$Error$Ignore
JMP Disk$Error$Request$Action
;
Disk$Error$Retry: ;The decision on where to return to
; depends on whether the operation
; failed on a deblocked or
; non-deblocked drive
LDA Deblocking$Required
ORA A
JNZ Deblock$Retry
JMP No$Deblock$Retry
;
System$Reset: ;This is a radical approach, but
; it does cause CP/M to restart
MVI C,0 ;System Reset
CALL BDOS
;
; Omitted subroutines (listed in full in Figure 8-10)
;
Set$Watchdog: ;Set Watchdog timer (to number of "ticks" in BC, and
; to transfer control to (HL) if timer hits zero).
CAH: ;Convert A to two ASCII hex characters, storing
; the output in (HL) and (HL+1)
Output$Error$Message: ;Display the 00-byte terminated error message
; pointed to by HL. Output is directed only to
; those console devices not being used for list
; output as well.
Request$User$Choice: ;Display prompt "Enter R, A, I..." and return
; single keyboard character (upper case) in A
RET ;Dummy