home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol018
/
xlook.asm
< prev
Wrap
Assembly Source File
|
1984-04-29
|
13KB
|
762 lines
.PAGE 80,63
;DISK EXAMINE/MODIFY UTILITY.
; This utility allows the user to examine absolute
;addresses on a disk. Additionally he may alter, character by
;charater, the contents of any given sector. Entire sectors
;may be moved from the bufer onto the disk.
; All I/O is done through the BIOS for CPM. There are
;no calls made to the BDOS.
;
;D.A. BARKER, January 1980.
;
.PABS
.SALL
.OPSYN .BLKB,DS
.OPSYN .BYTE,DB
.OPSYN .WORD,DW
;
.IDENT LOOK
.PROGID EXAM,1,2
;
;
; *****************
; * MISC. EQUATES *
; *****************
;
TEST = 0
CR = 0DH
LF = 0AH
DMADD = 80H
QUIT = 0 ;USE CPM ENTRY
ESC = 1BH
MAXDRV = 2
NSECS = 26
MAXGP = 243
;
; *************************
; * I/0 ENTRY DEFINITIONS *
; *************************
;
COUT = 12 ;THE FOLLOWING ARE BIOS JUMP TABLE
KEYIN = 9 ; ENTRY POINTS FOR THE VARIOUS
.SETDMA = 36 ; ROUTINES
.SELDSK = 27
.SETTRK = 30
.SETSEC = 33
.READ = 39
.WRITE = 42
;
; **********************
; * STRING DEFINITIONS *
; **********************
;
.DEFINE ST1 =[ -- LOOK -- VERSION 1.3 -- D. A. BARKER OCT. 21, 1980 ]
.DEFINE ST2 =[ Drive:]
.DEFINE ST3 =[ Track:]
.DEFINE ST4 =[ Sector:]
.DEFINE ST4.5 =[ Group:]
.DEFINE ST5 =[ Display is from:]
.DEFINE ST6 =[ Auto-read is:]
;
; *********************
; * MACRO DEFINITIONS *
; *********************
;
; CURSOR ADDRESSING
; This routine should produce the sequence of characters
;necessary to position the cursor. The third parameter should
;not require alteration.
;
.DEFINE XY [ROW,COL,Z(0)] =
[
DB ROW,COL
.IFE Z, DB 0
]
;
; INVERTING A STRING VALUE
; This routine sets the MSB of each character of the
;argument string. This is used for inverse video when the
;IObyte has been altered to accept inverse video rather than
;xy-addressing
;
; I/O FUNCTIONS
; Setup and do a BIOS function (FUNC).
;
.DEFINE GODO [FUNC] =
[
PUSH H
PUSH D
LXI D,FUNC
CALL IOCALL
POP D
POP H
]
;
.DEFINE TYPE = [CALL TYPEX]
;
.DEFINE PRINT = [CALL PRNTMSG]
;
.DEFINE XYPR = [CALL POSPR]
;
; GETKEY will set the zero flag if an Escape is typed.
;
.DEFINE GETKEY = [CALL GK]
;
; THE MAIN PROGRAM BEGINS
;
.LOC 0100H ;MAKE IT A CPM TRANSIENT
;
EXAM:
INIT: LXI B,DMADD ;THIS WILL NEVER CHANGE
GODO .SETDMA
LXI H,100H
SHLD DSKTBL
LXI D,DSKTBL+2
LXI H,DSKTBL
LXI B,10
LDIR ;INITIALIZE VARIOUS POINTERS
;
LXI H,DMADD
MVI M,0
LXI D,DMADD+1
LXI B,127
LDIR ;CLEAR THE BUFFER AREA
;
CLEAR: CALL CLRSC
;
CALL WHITE ;INVERT THE VIDEO
PRINT
.ASCII ST1 ;PRINTING THE HEADER
DB CR,LF ;BLOCK AND STATUS DISPLAYS
.ASCII ST2
.ASCII ST3
.ASCII ST4
.ASCII ST4.5
.ASCII / /
DB CR,LF
.ASCII ST5
.ASCII ST6
.ASCII / /
DB 0
CALL BLACK
REENT: LXI SP,STACK ;ENTRY HERE WILL UPDATE ALL
XYPR ; STATUS DISPLAYS
XY [1,@ST2]
LHLD DRIVE
MVI A,'A'
ADD L
TYPE
XYPR
XY [1,@ST2+@ST3]
MVI H,0
DAD H
LXI D,DSKTBL
DAD D
MOV A,M
CALL HEXOUT
XYPR
XY [1,@ST2+@ST3+@ST4]
INX H
MOV A,M
CALL HEXOUT
;
XYPR
XY [1,@ST2+@ST3+@ST4+@ST4.5]
PUSH H
MOV A,M
LXI H,GPTBL+NSECS
LXI B,NSECS
CCDR ;BC NOW CONTAINS LOGICAL SECTOR #
POP H
DCX H
MOV L,M
MVI H,0
DCR L
DCR L ;TRACK-2
JP .VALID ;JMP IF TRACK > 1
PRINT
.ASCIZ /SYS*/
JMPR .NTV
; NOW MULTIPLY HL BY 26
.VALID: DAD H ;X2
PUSH H
POP D
DAD H ;X4
DAD H ;X8
XCHG
DAD D
XCHG ;DE IS NOW X10
DAD H ;X16
DAD D ;X26
DAD B ;HL NOW THE TOTAL SECTOR NUMBER
;NOW DIVIDE BY 8
MOV A,L
ANI 0F8H
ORA H
RRC
RRC
RRC
CALL HEXOUT
MVI A,':'
TYPE
MOV A,L ;GET REMAINDER
ANI 7
ADI '1' ;ADD ASCII BIAS & INCREMENT
TYPE
;
.NTV: LDA AUTONO
ORA A ;CHECK FOR AUTO-READ
JNZ RDSK ;JUMP IF AUTO-READ
;
XYPR
XY [2,@ST5,1]
.ASCIZ / BUFFER/
JMPR LP
RDRTN: XYPR ;EVERY DISK READ OR WRITE WILL
XY [2,@ST5,1] ; RETURN HERE AND UPDATE THE
.ASCIZ / DISK / ; SECOND STATUS LINE
LP: LXI H,AUTONO
XYPR
XY [2,@ST5+@ST6]
MOV A,M
ORA A
JRZ ..OFF
PRINT
.ASCIZ / ON /
JMPR ..ON
..OFF: PRINT
.ASCIZ / OFF/
..ON: CALL SPIT ;SPIT THE BUFFER ONTO THE SCREEN
;
; *********************
; * COMMAND PROCESSOR *
; *********************
;
GETCOM: XYPR
XY [15,0]
CALL ERAL ;ERASE THE PROMPT LINE
GETKEY ;GET THE COMMAND CHARACTER
LXI H,CMDADD-1
LXI B,CMDADD-CMDTBL+1
CCDR ;SCAN THE TABLE BACKWARDS
LXI H,CMDADD
DAD B
DAD B ;HL NOW POINTS TO THE ROUTINE'S ADDRESS
MOV E,M
INX H
MOV D,M
PUSH D ;SO A 'RET' WILL GO TO THE ROUTINE
SETUP: LHLD DRIVE
MOV C,L
MVI H,0
DAD H
LXI D,DSKTBL
DAD D ;HL POINT TO CURRENT DISK'S TRACK LOC.
LXI D,0
RET ;GO EXECUTE THE CHOSEN ROUTINE
;
; *********************
; * THE COMMAND TABLE *
; *********************
;
CMDTBL: .ASCII /DTSIO+-GNLRWAHCQM?/[3]
CMDADD: DW INFO,SELDRV,SELTRK,SELSEC,STPIN
DW STPOUT,NXSEC,LSTSEC,GROUP,NXGP
DW LSTGP,READ,WRITE,ASC,HXCMD
DW CLEAR,QUIT,MODE,INFO,QUIT
;
SELDRV: CALL ERAL
PRINT
.ASCIZ /DRIVE NUMBER?/
MVI E,0 ;FOR THE GHX ROUTINE
CALL GHX
CPI MAXDRV
JRNC SELDRV
STA DRIVE
JMP REENT
;
SELTRK: CALL ERAL
PRINT
.ASCIZ /DESIRED TRACK?/
CALL GETHEX
CPI 77 ;MAXIMUM TRACK NUMBER + 1
JRNC SELTRK
MOV M,A
JMP REENT
;
SELSEC: CALL ERAL
PRINT
.ASCIZ /DESIRED SECTOR?/
CALL GETHEX
ORA A
JRZ SELSEC
CPI NSECS+1
JRNC SELSEC
INX H ;POINT TO CURRENT DRIVE'S SECTOR LOC.
MOV M,A
JMP REENT
;
NXSEC: INX H
MOV A,M
INR A
CPI NSECS+1
JRNC ..NXT
MOV M,A
JMP REENT ;STAY ON SAME TRACK
..NXT: MVI A,1
MOV M,A
DCX H ;POINT TO CURRENT TRACK LOCATION
JMPR STPIN
;
LSTSEC: INX H
MOV A,M
DCR A
ORA A
JRZ ..LST
MOV M,A
JMP REENT ;STAY ON THE SAME TRACK
..LST: ADI 26
MOV M,A
DCX H ;POINT TO CURRENT TRACK LOCATION
JMPR STPOUT
;
NXGP: INX H ;GET PRESENT SECTOR #
MOV A,M
LXI B,NSECS
XCHG ;PUT SECTOR TABLE POINTER IN DE
LXI H,GPTBL+1 ;POINT TO 2ND ENTRY OF THIS TABLE
CCIR ;SEARCH FOR THE PRESENT SECTOR
MOV A,M ;GET THE NEXT SECTOR
XCHG ;POINT HL TO THE TABLE
MOV M,A
JPE REENT ;ODD PARITY MEANS END OF TABLE
DCX H
STPIN: MOV A,M
CPI 76 ;MAXIMUM TRACK NUMBER
JNC REENT
INR M
JMP REENT
;
LSTGP: INX H
MOV A,M
LXI B,NSECS
XCHG
LXI H,GPTBL+NSECS
CCDR
MOV A,M
XCHG
MOV M,A
JPE REENT
DCX H
STPOUT: MOV A,M
ORA A
JZ REENT
DCR M
JMP REENT
;
; *********************
; * SECTOR SKEW TABLE *
; *********************
; Assuming a sector interleave of 6 sectors
;
GPTBL: DB 22,1,7,13,19,25,5,11,17
DB 23,3,9,15,21,2,8,14,20
DB 26,6,12,18,24,4,10,16,22,1
;
GROUP: CALL ERAL
PRINT
.ASCIZ /GROUP NUMBER?/
CALL GETHEX
CPI MAXGP+1
JRNC GROUP
MVI A,0FFH
XCHG ;HL CONTAIN THE GROUP NUMBER
DAD H ;MULTIPLY # BY 8
DAD H
DAD H
LXI B,-NSECS
..AGN: INR A ;DIVIDE THE # BY NSECS
DAD B
JRC ..AGN
ADI 2 ;QUOTIENT PLUS 2 IS NEW TRACK #
STAX D
DSBC B ;HL IS THE LOGICAL SECTOR NUMBER
LXI B,GPTBL+1
DAD B ;(HL) IS NOW THE PHYSICAL SECTOR #
MOV A,M
INX D
STAX D
JMP REENT
;
MODE: LDA AUTONO ;TOGGLE THE AUTO-READ MODE
INR A
ANI 1
STA AUTONO
JNZ RDSK
JMP RDRTN
;
ASC: CALL ERAL
PRINT
.ASCIZ /ASCII BYTE NUMBER?/
CALL GETHEX
CPI 80H
JRNC ASC
..AGN: CALL MCUR ;Position the cursor on the screen.
CALL ACUR
CALL MCUR0
JRNC ..AGN
MOV M,A ;Update the DMA buffer.
MVI C,1 ;Ready to advance by one.
CALL RESTO
JMPR ..AGN
;
HXCMD: CALL ERAL
PRINT
.ASCIZ /HEX BYTE NUMBER?/
CALL GETHEX
CPI 80H
JRNC HXCMD
..AGN: CALL MCUR
CALL HCUR
CALL MCUR0
JRNC ..AGN
CALL HEXFIL
MVI C,0
JRZ ..FWD
MOV M,A
INR C
..FWD: CALL RESTO
JMPR ..AGN
;
MCUR: MOV E,A ;THE CURSOR POINTER
MVI D,0
LXI H,DMADD
DAD D ;HL TO THE CP IN THE BUFFER
CALL HCUR ;POSITION THE HEX CURSOR
CALL BTYPE
CALL BTYPE
CALL ACUR ;THE ASCII CURSOR
JMP BTYPE
MCUR0: GETKEY
JZ GIT ;LEAVE ON AN 'ESC'
MVI C,-1
CPI 'H'-40H ;MOVE LEFT?
RC
JRZ RESTO
MVI C,10H
CPI 'J'-40H
RC
JRZ RESTO
MVI C,1
CPI 'L'-40H
JRZ RESTO
CMC
RC
MVI C,-10H
RESTO: PUSH B
CALL RS
POP B
MOV A,E
ADD C
ANI 7FH ;INSURE IN SECTOR
RET
;
RS: CALL HCUR
MOV A,M
CALL HEXOUT
CALL ACUR
MOV A,M
ANI 7FH
CPI 20H
JRNC ..FW
MVI A,'.'
..FW: CPI 0FFH
JRNZ ..AGN
MVI A,'.'
..AGN: TYPE
RET
;
HCUR: PUSH D
MOV A,E
RRC
RRC
RRC
RRC
ANI 0FH
ADI 5
MOV D,A
MOV A,E
ANI 0FH
RLC
MOV E,A
CALL DEXY
MOV A,D
POP D
MOV D,A
RET
ACUR: PUSH D
MOV A,E
ANI 0FH
ADI 24H
MOV E,A
CALL DEXY
POP D
RET
;
GIT: CALL RS
LXI H,0
SHLD AUTONO
JMP REENT
;
HEXFIL: CALL HEXIT
RZ
MOV B,A
..AGN: GETKEY
RZ
CPI CR
JRZ ..XIT
CALL HEXIT
JRC ..AGN
RLCR B
RLCR B
RLCR B
RLCR B
ORA B
MOV B,A
XRA A
INR A ;JUST TO CLEAR Z-FLAG
..XIT: MOV A,B
RET
;
RDSK: CALL SETUP
READ: CALL IOSET
XYPR
XY [13,0]
GODO .READ
.IFN TEST, [
ORA A
JZ RDRTN
XYPR
XY [15,0,1]
.ASCIZ / ERROR ON READ!! /
GETKEY ]
JMP RDRTN
WRITE: CALL IOSET
XYPR
XY [13,0]
GODO .WRITE
JMP RDRTN
IOSET: GODO .SELDSK
MOV C,M
GODO .SETTRK
INX H
MOV C,M
GODO .SETSEC
RET
;
INFO: CALL CLRSC ;SPLASH THE HELP TEXT TO THE SCREEN
XYPR
XY [0,24,1]
.ASCII /COMMAND SUMMARY/[CR][LF]
.ASCII /D: select Drive (0,1,2,3) /
.ASCII /R: Read the current sector/[CR][LF]
.ASCII /T: select Track (0 - 4C) /
.ASCII /W: Write buffer to disk/[CR][LF]
.ASCII /S: select Sector (1 - 26) /
.ASCII /M: toggle the auto-read Mode/[CR][LF]
.ASCII /I: step In /[CR][LF]
.ASCII /O: step Out /
.ASCII /A: ASCII fill the buffer/[CR][LF]
.ASCII / /
.ASCII /H: Hex fill the buffer/[CR][LF]
.ASCII /+: next physical sector /[CR][LF]
.ASCII /-: last physical sector /
.ASCII /^H: move cursor left/[CR][LF]
.ASCII / /
.ASCII /^L: move cursor right /[CR][LF]
.ASCII /The following 3 commands /
.ASCII /^J: move cursor down /[CR][LF]
.ASCII /assume sector interleave of 6 /
.ASCII /^K: move cursor up /[CR][LF]
.ASCII /G: Group selection /
.ASCII /C: re-initialize the screen /[CR][LF]
.ASCII /N: Next logical sector /
.ASCII /Q: exit to CPM/[CR][LF]
.ASCII /L: Last logical sector /
.ASCII /^C: " " "/[CR][LF][0]
XYPR
XY [15,17,1]
.ASCIZ /Esc: general command Escape./
GETKEY
JMP CLEAR
;
; *********************
; * MISC. SUBROUTINES *
; *********************
;
;
IOCALL: LHLD 1 ;PICK UP THE BASE OF THE BIOS
MVI L,0
DAD D
PCHL ;GO TO THE REQUESTED ROUTINE
;
BTYPE: MVI A,'_'
TYPEX: MOV C,A
GODO [COUT]
RET
;
POSPR: XTHL
MOV D,M
INX H
MOV E,M
CALL DEXY
JMPR POSPR1
PRNTMSG: XTHL
MOV A,M
ZAGN: TYPE
POSPR1: INX H
MOV A,M
ORA A
JRNZ ZAGN
INX H
XTHL
RET
;
HEXOUT: PUSH B ;SAVE BC
MVI B,1 ;ITERATION COUNT
MOV C,A
RAR
RAR
RAR
RAR
..AGN: ANI 0FH
PUSH B
ADI '0'
CPI '9'+1
JRC ..OUT
ADI 7
..OUT: TYPE
POP B
DCR B
JRNZ ..DUN
MOV A,C
JMPR ..AGN
..DUN: POP B
RET
;
; READ HEX VALUES IN FROM THE KEYBOARD
;
GETHEX: GETKEY
JZ REENT
CALL HEXIT
JRC GETHEX
MOV E,A
MOV A,C
TYPE
GHX: GETKEY
JZ REENT
CPI CR
JRZ ..EX
CALL HEXIT
JRC GHX
RLCR E
RLCR E
RLCR E
RLCR E
ORA E
MOV E,A
MOV A,C
TYPE
..EX: MOV A,E
RET
;
; CONVERT THE CONTENTS OF THE ACCUMULATOR TO
; HEXIDECIMAL. SET CARRY ON ILLEGAL CHARACTERS
;
HEXIT: MOV C,A
SUI 30H
RC
CPI 0AH
CMC
RNC
SUI 7
CPI 0AH
RC
CPI 10H
CMC
RET
GK: GODO KEYIN
CPI ESC
RET
;
; **************************************
; * DISPLAY THE CONTENTS OF THE BUFFER *
; **************************************
;
SPIT: XYPR
XY [5,0]
LXI H,DMADD
MVI B,8 ;FOR 8 ROWS OF INFO
PUSH H
..BGN: MVI C,10H ;FOR 16 COLUMNS OF INFO
LXI H,..BUF
XTHL ;HL TO BUFFER AND STACK TO ..BUF
..AGN: MOV A,M
CALL HEXOUT
MOV A,M
ANI 7FH
CPI 7FH
JRZ ..BD
CPI ' '
JRNC ..OK
..BD: MVI A,'.'
..OK: XTHL ;GET THE ..BUF POSITION.
MOV M,A
INX H
XTHL
INX H ;ADVANCE IN THE BUFFER
DCR C ;SEE IF THERE IS MORE ON THIS LINE
JRNZ ..AGN
XTHL
PRINT
.ASCII / /
..BUF: DS 10H
DB CR,LF,0
DCR B ;MORE FROM THIS SECTOR?
JRNZ ..BGN
POP H
RET
DSKTBL: DS 8 ;ROOM ENOUGH FOR 4 DRIVES
DRIVE: DS 1 ;CURRENT DRIVE
AUTONO: DS 1 ;AUTO OR MANUAL READ
DS 32
STACK: DS 1
CLRSC: PRINT
.ASCIZ [ESC]/E/[0][0]
RET
BLACK: PRINT
.ASCIZ [ESC]/q/[0][0]
RET
WHITE: PRINT
.ASCIZ [ESC]/p/[0][0]
RET
ERAL: PRINT
.ASCIZ [CR][ESC]/l/[0][0]
RET
DEXY: MVI A,ESC
TYPE
MVI A,'Y'
TYPE
MOV A,D ;THE ROW NUMBER
ADI 20H
TYPE
MOV A,E ;THE COLUMN NUMBER
ADI 20H
TYPE
RET
.END EXAM