TITLE   'SECTOR DISK MAINTENANCE PROGRAM'
;       DERIVED 8/77 W. EARNEST
;       MODIFIED 9/77 FOR EFFICIENCY+LOGIC
;       MODIFIED 4/07/78 FOR MORE FEATURES
;       MODIFIED 1/15/79 FOR CP/M USAGE
;       MODIFIED 7/14/80 FOR CP/M REV 2.X
;
BDOS    EQU     5
BOOT    EQU     0       ;BDOS FUNCT CODES
CONIN   EQU     1
CONOU   EQU     2
LIST    EQU     5
PMSG    EQU     9
REVNR   EQU     12
GETDPB  EQU     31
;                       BIOS OFFSETS
SDRV    EQU     27
STRK    EQU     30
SSEC    EQU     33
SDMA    EQU     36
READ    EQU     39
WRITE   EQU     42
SECTRN  EQU     48
;
       ORG     100H
BEGIN:  LXI     SP,STACK
       MVI     C,REVNR
       CALL    BDOS    ;CHECK SYSTEM REVISION
       MOV     A,L
       ORA     A
       JNZ     CPMOK   ;CURRENT SYSTEM
       LXI     D,REVMSG
       CALL    MSGO
       JMP     EXIT    ;GIVE UP NOW
;
CPMOK:  LDA     2       ;BIOS PAGE BYTE
       STA     SEDMA+2
       STA     FILBF+2
       STA     WRTBF+2
       STA     SESCT+2
       STA     SETRK+2
       STA     SEDRV+2
       STA     SCTRN+2
       LXI     B,BUFFR
SEDMA:  CALL    SDMA
       JMP     START
;
EXIT:   CALL    CRLF
       JMP     BOOT
;
CO:     PUSH    PSW
       PUSH    H
       PUSH    D
       PUSH    B
       MVI     C,CONOU
       MOV     E,A
       CALL    BDOS
       POP     B
       POP     D
       POP     H
       POP     PSW
       RET
;
CI:     MVI     C,CONIN
       PUSH    H
       PUSH    D
       CALL    BDOS
       POP     D
       POP     H
       ANI     7FH
       CPI     1BH     ;ESC CODE
       JZ      ESCCH   ;ABORT THIS COMMAND
       CPI     61H     ;LOWER  CASE A
       RC
       ANI     5FH     ;CONVT TO UPPER
       RET
;
SO:     JMP     CO      ;VARIABLE JUMP FOR PRINT
;
LO:     PUSH    PSW
       PUSH    H
       PUSH    D
       PUSH    B
       MVI     C,LIST
       MOV     E,A
       CALL    BDOS
       POP     B
       POP     D
       POP     H
       POP     PSW
       RET
;
DEFUN:  LXI     D,PRMUN
       CALL    MSGO
UNAGN:  CALL    IN2NR
       MOV     A,L
KPUNT:  STA     NUNIT
DEFTK:  LXI     D,PRMTK
       CALL    MSGO
TKAGN:  CALL    IN2NR
       MOV     A,L
       CPI     77
       JC      KPTRK
       CALL    INERR
       JMP     TKAGN
;
KPTRK:  STA     NTRAK
DEFSC:  LXI     D,PRMSC
       CALL    MSGO
SCAGN:  CALL    IN2NR
       DCR     L       ;START W/SCTR 1
       MOV     A,L
KPSCT:  STA     NSCTR
MODBR:  JMP     LDBUF   ;CHGS FOR BLOCK MOVE
;
LDBUF:  LDA     BUFLG
       ORA     A
       JNZ     WTBUF
       CALL    SUPRD
       CALL    FILBF
PRINT:  CALL    PRBUF
;
START:  LXI     SP,STACK
       CALL    PRMPT
       CALL    CI
       SUI     'A'     ;TABLE START VALUE
       JC      INVLID  ;BELOW LEGAL RANGE
       CPI     'Z'-'A'+1 ;END OF TABLE
       JNC     INVLID  ;ABOVE LEGAL RANGE
       ADD     A       ;DOUBLE
       MOV     E,A
       MVI     D,0
       LXI     H,DOTBL
       DAD     D       ;CALCULATE VECTOR
       MOV     A,M
       INX     H
       MOV     H,M
       MOV     L,A
       CALL    CRLF
       PCHL            ;GO TO ROUTINE
;
ESCCH:  POP     H
       LXI     D,CANMSG
       JMP     EMSG
;
INVLID: CALL    CRLF
       LXI     D,INVAL
EMSG:   CALL    MSGO
       JMP     START
;
DOTBL:  DW      TOMEM   ;A DISK TO MEMORY
       DW      BLKMV   ;B BLOCK MOVE
       DW      CHGBF   ;C CHANGE CONTENTS
       DW      DMODE   ;D DECIMAL MODE
       DW      EXTTBL  ;E EXTRNAL XLATE
       DW      PHSTBL  ;F PHYSICAL SECTORS
       DW      GENTBL  ;G LOGICAL SECTORS
       DW      HMODE   ;H HEXADECIMAL MODE
       DW      START   ;I
       DW      START   ;J
       DW      EXIT    ;K EXIT TO CP/M
       DW      LSET    ;L LINE PRINTER OUT
       DW      MOVE    ;M MOVE SECTOR
       DW      START   ;N
       DW      START   ;O
       DW      PRINT   ;P PRINT BUFFER
       DW      START   ;Q
       DW      START   ;R
       DW      DEFSC   ;S SET SECTOR
       DW      DEFTK   ;T SET TRACK
       DW      DEFUN   ;U SET UNIT
       DW      VSET    ;V VIDEO OUTPUT
       DW      WTBUF   ;W WRITE BUFF TO DISK
       DW      XLATE   ;X XLATE BLOCK (INTERLACE)
       DW      START   ;Y
       DW      FRMEM   ;Z MEMORY TO DISK
;
PHSTBL: LXI     H,PHMAP
       MVI     A,'F'
       JMP     TBLST
;
GENTBL: LXI     H,GENMAP
       MVI     A,'G'
;
TBLST:  SHLD    HLDIT
       SHLD    HLDOT
       STA     PRMST
       JMP     START
;
XLATE:  CALL    CI
       LXI     H,PHMAP
       CPI     'F'
       JZ      XLSET
       LXI     H,GENMAP
       CPI     'G'
       JZ      XLSET
       LXI     H,EXMAP
       CPI     'E'
       JZ      XLSET
       JMP     INVLID
;
EXTTBL: LXI     H,EXTBL ;TABLE FOR EXTRN SKEW
       SHLD    CHGBAS
       LXI     H,EXMAP
       SHLD    HLDIT
       SHLD    HLDOT
       MVI     A,'E'
       STA     PRMST
       MVI     B,0
       PUSH    B
       JMP     CHGLP
;
CHGBF:  LXI     H,BUFFR-1
       SHLD    CHGBAS
       CALL    IN2NR
       MOV     B,L
       PUSH    B
CHGLP:  CALL    IN2NR
       POP     B
       LDA     LSTCH
       CPI     0DH     ;CR?
       JZ      CHEND   ;YES
       MOV     C,L
       MOV     A,B
       CPI     129
       JNC     RGERR
       LHLD    CHGBAS
       ADD     L
       MOV     L,A
       JNC     NCARY
       INR     H
NCARY:  MOV     M,C
       INR     B
       PUSH    B
       LDA     LSTCH
       CPI     '.'
       JNZ     CHGLP
       POP     B
CHEND:  CALL    CRLF
       JMP     START
;
RGERR:  LXI     D,RNMSG
       JMP     EMSG
;
WTBUF:  CALL    SUPWT
       CALL    WRTBF
       XRA     A
       STA     BUFLG
       JMP     START
;
MOVE:   CALL    CRLF
       LXI     D,ADMSG
       CALL    MSGO
       MVI     A,1
       STA     BUFLG   ;MARK TO BE WRITTEN
       CALL    CRLF
       JMP     DEFUN
;
XLSET:  SHLD    HLDOT
BLKMV:  LXI     D,FRMMG
       LXI     H,RDSTU
STUCOM: SHLD    MODBR+1
       CALL    MSGO
       CALL    CRLF
       JMP     DEFUN
;
RDSTU:  LHLD    NSCTR
       SHLD    RSCTR
       LHLD    NTRAK
       SHLD    RTRAK
       LXI     D,TOMSG
       LXI     H,WTSTU
       JMP     STUCOM
;
WTSTU:  LXI     D,SIZMG
       CALL    MSGO
       CALL    INNRS
       SHLD    SCTCT
       LXI     H,LDBUF
       SHLD    MODBR+1
MORBL:  CALL    SUPBK
       CALL    FILBF
       CALL    SUPWT
       CALL    WRTBF
       LXI     H,NSCTR
       CALL    INCAD
       LXI     H,RSCTR
       CALL    INCAD
       LHLD    SCTCT
       DCX     H
       SHLD    SCTCT
       MOV     A,L
       ORA     H
       JNZ     MORBL
       JMP     START
;
INCAD:  INR     M
       LDA     SPERT
       CMP     M
       JZ      TKEND
       RNC
TKEND:  MVI     M,0
       INX     H
       INX     H
       INR     M
       RET
;
PRMPT   LXI     D,PRMST ;PROMPT STRING
       JMP     MSGO
;
INERR:  LXI     D,ERRMG
MSGO:   MVI     C,PMSG
       JMP     BDOS
;
LMSG:   CALL    PCRLF
LMSGL:  LDAX    D
       CPI     '$'
       RZ
       CALL    SO
       INX     D
       JMP     LMSGL
;
IN2NR:  CALL    INNRS
       MOV     A,H
       ORA     A
       RZ
       LXI     D,LMSG1
       CALL    MSGO
       JMP     IN2NR
;
INNRS:  LXI     H,0
NRSLP:  PUSH    H
       CALL    CI
       STA     LSTCH
       CPI     0DH
       POP     H
       JZ      LINFD
       CPI     ','
       RZ
       CPI     '.'
       RZ
       CALL    HEXBI
       JNC     NRSLP
       LXI     D,LMSG2
       CALL    MSGO
       JMP     INNRS
;
LINFD:  MVI     A,0AH
       JMP     CO
;
HEXBI:  CPI     '0'
       RC
       CPI     '9'+1
       JC      CVNUM
       CPI     'A'
       RC
       CPI     'G'
ALJMP:  JC      CVALP
NRBAD:  STC
       RET
;
CVALP:  ADI     9
CVNUM:  ANI     0FH
       PUSH    H
       POP     D
       DAD     H
       RC
       DAD     H
       RC
HDCHG:  DAD     H
       RC
       DAD     H
       RC
       ADD     L
       MOV     L,A
       RET
;
DMODE:  MVI     A,'D'
       STA     PRMST+1
       MVI     A,19H   ;DAD D
       LXI     H,NRBAD
MDCOM:  STA     HDCHG
       SHLD    ALJMP+1
       JMP     START
;
HMODE:  MVI     A,'H'
       STA     PRMST+1
       MVI     A,29H   ;DAD    H
       LXI     H,CVALP
       JMP     MDCOM
;
CRLF:   MVI     A,0DH
       CALL    CO
       MVI     A,0AH
       JMP     CO
;
FILBF:  JMP     READ
;
WRTBF:  JMP     WRITE
;
SUPBK:  LDA     RUNIT
       MOV     C,A
       CALL    SEDRV
       LDA     RTRAK
       ANI     7FH
       MOV     C,A
       CALL    SETRK
       LHLD    RSCTR
       XCHG
       LXI     H,HLDIT
       JMP     GTSEC
;
SUPRD:  LXI     H,HLDIT
SUUTK:  PUSH    H
       LDA     NUNIT
       MOV     C,A
       CALL    SEDRV
       LDA     NTRAK
       ANI     7FH
       MOV     C,A
       CALL    SETRK
       LHLD    NSCTR
       XCHG
       POP     H
       JMP     GTSEC
;
SUPWT:  LXI     H,HLDOT
       JMP     SUUTK
;
SEDRV:  CALL    SDRV
       MOV     A,H
       ORA     L
       JZ      UNIERR
       MOV     E,M
       INX     H
       MOV     D,M
       XCHG
       SHLD    XLTADR
       LXI     H,9
       DAD     D
       MOV     E,M
       INX     H
       MOV     D,M
       XCHG
       MOV     A,M
       STA     SPERT
       RET
;
SETRK:  JMP     STRK
UNIERR: LXI     D,UNERMG
       JMP     EMSG
;
TOMEM:  LXI     D,MVMSG
       CALL    MSGO
       CALL    INNRS
       LXI     D,BUFFR
MVCOM:  MVI     B,128
MMVLP:  LDAX    D
       MOV     M,A
       INX     D
       INX     H
       DCR     B
       JNZ     MMVLP
       JMP     START
;
FRMEM:  LXI     D,MVMSG
       CALL    MSGO
       CALL    INNRS
       LXI     D,BUFFR
       XCHG
       JMP     MVCOM
;
PRBUF:  LDA     NUNIT
       ORI     '0'
       STA     IDMSG+5
       LDA     NTRAK
       LXI     H,IDMSG+13
       CALL    PBYT
       LDA     NSCTR
       INR     A
       LXI     H,IDMSG+23
       CALL    PBYT
       LXI     D,IDMSG
       CALL    LMSG
       LXI     D,BUFFR
       PUSH    D
       CALL    PCRLF
       MVI     A,1
PRBGN:  STA     PRPTR
       POP     D
PRILP:  PUSH    D
       LDA     PRPTR
       CALL    PRADR
       POP     D
       PUSH    D
       CALL    PRSPC
       CALL    PR4BT
       CALL    PRSPC
       CALL    PR4BT
       CALL    PRSPC
       CALL    PR4BT
       CALL    PRSPC
       CALL    PR4BT
       CALL    PRSPC
       POP     D
       CALL    PRLIT
       PUSH    D
       CALL    PCRLF
       POP     D
       LDA     PRPTR
       ADI     10H
       STA     PRPTR
       CPI     81H
       JNZ     PRILP
       RET
;
PR4BT:  CALL    PRHWD
       CALL    PRHWD
       RET
;
PRHWD:  LDAX    D
       INX     D
       MOV     H,A
       LDAX    D
       INX     D
       MOV     L,A
       PUSH    D
       CALL    HEXCH
       POP     D
       RET
;
PBYT:   PUSH    PSW
       RAR
       RAR
       RAR
       RAR
       CALL    CNIB
       POP     PSW
CNIB:   ANI     0FH
       CPI     10
       JC      NNIB
       ADI     7
NNIB:   ADI     '0'
       MOV     M,A
       INX     H
       RET
;
PRSPC:  MVI     A,' '
       JMP     SO
;
PRLIT:  MVI     A,'*'
       CALL    SO
       MVI     B,10H
LITLP:  LDAX    D
       INX     D
       CPI     ' '
       JC      INVIS
       CPI     80H
       JNC     INVIS
LITBR:  CALL    SO
       DCR     B
       JNZ     LITLP
       MVI     A,'*'
       JMP     SO
;
INVIS:  MVI     A,'.'
       JMP     LITBR
;
PRADR:  MOV     L,A
       MVI     H,0
HEXCH:  MVI     D,4
HEXLP:  XRA     A
       DAD     H
       RAL
       DAD     H
       RAL
       DAD     H
       RAL
       DAD     H
       RAL
       CPI     10
       JC      NTALP
       ADI     7
NTALP:  ADI     '0'
       CALL    SO
       DCR     D
       JNZ     HEXLP
       RET
;
PCRLF:  MVI     A,0AH
       CALL    SO
       MVI     A,0DH
       JMP     SO
;
LSET:   LXI     H,LO
       MVI     A,'L'
PSET:   SHLD    SO+1
       STA     PRMST+2
       JMP     START
;
VSET:   LXI     H,CO
       MVI     A,'V'
       JMP     PSET
;
GTSEC:  LDA     SPERT
       CMP     E       ;NR WANTED
       JZ      SECERR
       JC      SECERR
       MOV     A,M
       INX     H
       MOV     H,M
       MOV     L,A
       PCHL
;
SECERR: LXI     D,SECERM
       JMP     EMSG
;
PHMAP:  MOV     C,E
       INR     C
SESCT:  JMP     SSEC
;
EXMAP:  LXI     H,EXTBL
       SHLD    XLTADR
;
GENMAP: MOV     C,E
       MOV     B,D
       LHLD    XLTADR
       XCHG
SCTRN:  CALL    SECTRN
       MOV     C,L
       JMP     SESCT
;
EXTBL:  DB      1,2,3,4,5
       DB      6,7,8,9,10
       DB      11,12,13,14,15
       DB      16,17,18,19,20
       DB      21,22,23,24,25
       DB      26,27,28,29,30
       DB      31,32,33,34,35
       DB      36,37,38,39,40
       DB      41,42,43,44,45
       DB      46,47,48,49,50
       DB      51,52,53,54,55
       DB      56,57,58,59,60
       DB      61,62,63,64
;
REVMSG: DB      'Not valid CP/M revision!!$'
INVAL:  DB      'Invalid Command:$'
RNMSG:  DB      'Range exceeded:$'
PRMTK:  DB      'Enter Track:$'
PRMSC:  DB      'Enter Sector:$'
PRMUN:  DB      'Enter Unit:$'
FRMMG:  DB      'Enter Sending address:$'
TOMSG:  DB      'Enter Receiving address:$'
SIZMG:  DB      'Enter Number of Sectors to move:$'
ADMSG:  DB      'Enter new address:$'
MVMSG:  DB      'Enter Memory address:$'
IDMSG:  DB      'Unit X,Track XX,Sector XX$'
ERRMG:  DB      'RETYPE:$'
LMSG1:  DB      '2 Hex Digit limit. Retype:$'
LMSG2:  DB      '4 Hex Digit limit. Retype:$'
UNERMG: DB      'Invalid Unit number',0DH,0AH,'$'
SECERM: DB      'Invalid Sector number',0DH,0AH,'$'
CANMSG: DB      'Cancelled',0dh,0ah,'$'
PRMST:  DB      'GHV==>$'
;
;       DONT MOVE THE NEXT 6 ITEMS
NSCTR:  DW      0       ;XTRA BYTE FOR TBL CALC PAD
NTRAK:  DB      0
NUNIT:  DB      0
RSCTR:  DW      0
RTRAK:  DB      0
RUNIT:  DB      0
SCTCT:  DW      0
BUFLG:  DB      0
HLDIT:  DW      GENMAP  ;CP/M IS DEFAULT
HLDOT:  DW      GENMAP  ;CP/M FOR OUT ALSO
CHGBAS: DW      0       ;BASE ADDR FOR BYTE CHANGES
XLTADR: DW      EXTBL   ;POINT AT SOMETHING
SPERT:  DB      26      ;SECTORS PER TRACK
LSTCH:  DS      1
PRPTR:  DS      1
       DS      24
STACK:  DS      2
BUFFR:  DS      128
;
       END