;
;       WHODERE.ASM by R.H.JOHNSON
;       Modifications by BILL WOOD (New name WHODERE1.ASM)
;
;       What you say in secret,
;               shall be shouted from the house tops.
;
; An SAU to display sneaky Bios reads and writes.
;
;          A DEBUG PROGRAM FOR DISK READS AND WRITES
; This program will list all disk reads and writes to the
; CRT: (if CRT is TRUE) or to the LST: (if CRT is FALSE).
;
; N O T E :  This program runs in HI memory.
;            CP/M must be moved below HI memory to allow
;            room for this program. Set LOAD above CP/M.
;
;            As this program must use direct BIOS call
;            for CONOUT, the program may not work with
;            future releases of CP/M . The BDOS call "6"
;            for direct BIOS calls will not work with
;            this program as we would have two BDOS
;            call at the same time.           B Wood.
;
;MODIFICATIONS:
;                       ------------
;03/30/82
;       Added routine to locate the address of BIOS.
;       Added conditional for output to CRT: or LST: .
;       Removed LDIR macro and added subroutine LDIR
;       to move memory. Program will now assemble with
;       ASM.COM .
;       Made other minor changes to program.
;
;               Bill Wood , Mississauga, Ontario, Canada.
;                       ------------
;
;04/02/82
;       Added on/off toggle for print out with CTRL ^A .
;       Check so program will not load a second time.
;              Bill Wood
;                       ------------
;
;
FALSE   EQU     0
TRUE    EQU     NOT FALSE
;
LOAD    EQU     62      ;FREE MEMORY SPACE ABOVE CP/M (IN K)
;
NEWBIOS EQU     (LOAD*1024)+1
;
CRT     EQU     TRUE    ;OUTPUT TO CRT: IF TRUE (LST: IF FALSE)
;
BASE    EQU     0       ;BASE OF CP/M
BDOS    EQU     BASE+5  ;BDOS CALL
STRING  EQU     09H     ;BDOS PRINT STRING
CR      EQU     0DH
LF      EQU     0AH
;
;
       ORG     100H
;
;DO NOT ALLOW PROGRAM TO BY LOADED A SECOND TIME (SYSTEM WILL CRASH)
START:  LHLD    BASE+1  ;GET BIOS ADDRESS IN HL
       LXI     B,07H   ;GET TO CONIN JMP ADDRESS
       DAD     B       ;ADD BC TO HL
       MOV     E,M
       INX     H
       MOV     D,M     ;ADDRESS NOW IN DE
       LXI     H,NEWIN ;GET ADDRESS
       MOV     A,H
       CMP     D
       JNZ     START1  ;IF NOT SAME MUST BE 1ST. LOAD
       MOV     A,L
       CMP     E
       JNZ     START1  ;IF NOT SAME MUST BE 1ST. LOAD
       LXI     D,LOADED
       MVI     C,STRING ;TELL THIS IS SECOND LOAD
       CALL    BDOS
       JMP     BASE    ;GET BACK TO CM/M
;
LOADED: DB      CR,LF,'DUMMY !    WHODERE1 IS LOADED'
       DB      CR,LF,'USE CTRL ^A TO TURN PROGRAM ON',CR,LF,'$'
;
;
;OK LOAD PROGRAM
;SET UP LOGOUT FOR CRT: OR LST:
START1: LHLD    BASE+1   ;GET BIOS ADDRESS IN HL
       LXI     B,18H    ;OFFSET TO SETDSK
       DAD     B        ;ADD BC TO HL
       SHLD    WASBIOS  ;STORE IT
;
       LHLD    BASE+1   ;GET BIOS ADDRESS IN HL
;
       IF      CRT
       LXI     B,9H     ;CONOUT (CRT:)
       ENDIF
;
       IF      NOT CRT
       LXI     B,12     ;LIST  (LST:)
       ENDIF
;
       DAD     B        ;ADD BC TO HL
       SHLD    OVLAY1+1 ;OVERLAY BIOS CALL+1  CRT: OR LST:
;
;SET UP CONOUT FOR CRTMSG
       LHLD    BASE+1   ;GET BIOS ADDRESS IN HL
       LXI     B,9H     ;CONOUT
       DAD     B        ;ADD TO HL
       SHLD    OVLAY2+1 ;OVERLAY BIOS CALL+1 CRT:
;
;
;SET UP TO TEST BIOS CONIN FOR CTRL ^A
       LHLD    BASE+1
       LXI     B,07H    ;OFFSET TO CONIN
       DAD     B        ;ADD BC TO HL
       MOV     E,M
       INX     H
       MOV     D,M
       XCHG
       SHLD    OVLAY3+1 ;OVERLAY CONIN CALL+1
;
;
;       COPY PROGRAM TO HIGH CORE
       LXI     H,PROGRAM
       LXI     D,NEWBIOS
       LXI     B,PROEND-PROGRAM
       CALL    LDIR
;
;       COPY OLD BIOS JUMPS TO TABLE
       LHLD    WASBIOS
       LXI     D,OLDDSK
       LXI     B,18
       CALL    LDIR
;
;       COPY IN NEWBIOS TABLE
       LHLD    WASBIOS
       XCHG
       LXI     H,SELDSK
       LXI     B,18
       CALL    LDIR
;
       LXI     H,NEWIN
       XCHG             ;OVERLAY BIOS CONIN JMP
       LHLD    BASE+1
       LXI     B,07H    ;OFFSET TO CONIN
       DAD     B        ;ADD BC TO HL
       MOV     M,E
       INX     H
       MOV     M,D
;
       LXI     D,SIGNIN
       MVI     C,STRING ;PRINT STRING
       CALL    BDOS
;       DONE
       JMP     BASE
;
;
WASBIOS:DS      2
;
SIGNIN: DB      ' WHODERE1.ASM '
       DB      ' VERSION 2.1 '
       DB      ' 3/03/82  R.H.JOHNSON',CR,LF
       DB      ' REV(1) BY BILL WOOD 03/30/82',CR,LF,LF
       IF      CRT
       DB      ' ALL DISK READS AND WRITES WILL DISPLAY ON CRT:',CR,LF,LF
       ENDIF
       IF      NOT CRT
       DB      ' ALL DISK READS AND WRITES WILL DISPLAY ON LST:',CR,LF,LF
       ENDIF
       DB      '   N O T E :  USE CTRL ^A TO TOGGLE WHODERE ON & OFF',CR,LF
       DB      '                  WHODERE IS NOW OFF',CR,LF,LF,'$'
;
;
;       MOVE MEMORY
;       HL=GET    DE=PUT     BC=COUNT
;
LDIR:   MOV     A,B
       ORA     C
       RZ              ;RETURN IF COUNT IS 0
       MOV     A,M     ;GET IT
       INX     H
       XCHG
       MOV     M,A     ;PUT IT
       INX     H
       XCHG
       DCX     B       ;COUNT
       JMP     LDIR
;
;
;
;       BIOS OVERLAY TABLE
;
SELDSK: JMP     NEWDSK
SETTRK: JMP     NEWTRK
SETSEC: JMP     NEWSEC
SETDMA: JMP     NEWDMA
SETRED: JMP     NEWRED
SETWRT: JMP     NEWWRT
;
;
;       START OF RELOCATED CODE
;
PROGRAM:EQU     $
OFFSET: EQU     NEWBIOS-PROGRAM
;
NEWIN:  EQU     $+OFFSET
OVLAY3: CALL    $-$     ;BIOS CONIN (ADDRESS OVERLAY)
       PUSH    PSW     ;TEST ALL CONIN'S FOR CTRL A
       ANI     7FH     ;STRIP IT
       CPI     01H     ;CTRL A
       JZ      TOGFLA  ;YES TOGGLE PRINT FLAG
       POP     PSW
       RET
;
TOGFLA: EQU     $+OFFSET ;PRINT FLAG
       PUSH    H
       PUSH    D       ;PSW IS PUSHED
       PUSH    B
       LXI     H,FLAG
       MOV     A,M     ;GET FLAG
       CMA             ;FLIP IT (TOGGLE)
       MOV     M,A     ;PUT IT BACK
       CPI     0
       JZ      TOG1    ;IT'S OFF SO SAY IT
       LXI     H,FLGON ;IT'S ON SO SAY IT
       JMP     TOG2
TOG1:   EQU     $+OFFSET
       LXI     H,FLGOFF
TOG2:   EQU     $+OFFSET
       CALL    CRTMSG  ;PRINT MESSAGE (ON OR OFF)
       POP     B       ;MUST USE BIOS AS WE HAVE A BDOS CONIN CALL
       POP     D       ;ON THE GO. CAN'T HAVE TWO BDOS CALLS AT THE
       POP     H       ;SAME TIME.
       POP     PSW
       MVI     A,CR    ;SEND BACK A CR
       RET
;
FLAG:   EQU     $+OFFSET
       DB      0       ;START WITH PRINT FLAG NOT SET
;
FLGON:  EQU     $+OFFSET
       DB      '^A WHODERE ON',CR,LF,0
FLGOFF: EQU     $+OFFSET
       DB      '^A WHODERE OFF',CR,LF,0
;
;
NEWDSK: EQU     $+OFFSET        ;CONVERT DISK # TO LETTER
       PUSH    PSW             ;PUT IN TABLE,
       MOV     A,C             ;AND DOIT
       STA     TDISK
       POP     PSW
       JMP     OLDDSK
;
NEWTRK: EQU     $+OFFSET        ;SEEK TO TRACK
       PUSH    PSW             ;PUT IN TABLE,
       MOV     A,C             ;AND DOIT
       STA     TTRACK
       POP     PSW
       JMP     OLDTRK
NEWSEC: EQU     $+OFFSET        ;SET SECTOR NUMBER
       PUSH    PSW             ;PUT IN TABLE,
       MOV     A,C             ;AND DOIT
       STA     TSECT
       POP     PSW
       JMP     OLDSEC
NEWDMA: EQU     $+OFFSET        ;SET START ADDRESS FOR I/O
       PUSH    PSW             ;PUT IN TABLE,
       MOV     A,B             ;AND DOIT
       STA     TDMA
       MOV     A,C
       STA     TDMA+1
       POP     PSW
       JMP     OLDDMA
NEWRED: EQU     $+OFFSET        ;READ SELECTED SECTOR
       PUSH    PSW             ;PUT IN TABLE, DISPLAY
       MVI     A,'R'           ;AND DOIT
       STA     OPCD
       CALL    CNVERT
       POP     PSW
       JMP     OLDRED
NEWWRT: EQU     $+OFFSET        ;WRITE SELECTED SECTOR
       PUSH    PSW             ;PUT IN TABLE, DISPLAY
       MVI     A,'W'           ;AND DOIT
       STA     OPCD
       CALL    CNVERT
       POP     PSW
       JMP     OLDWRT
;
; CONVERTS STRING POINTED TO BY HL AND PUTS
; RESULT IN MEMORY POINTED TO BY DE
CNVERT: EQU     $+OFFSET
       PUSH    H
       LXI     H,FLAG  ;TEST PRINT FLAG
       MOV     A,M
       CPI     0
       JNZ     CNVER1  ;FLAG IS SET SO PRINT IT
       POP     H
       RET             ;FLAG NOT SET SO NO PRINT OUT
CNVER1: EQU     $+OFFSET
       PUSH    D
       PUSH    B
       LXI     H,TDISK
       LXI     D,DISK
       CALL    CVERT
;
       LXI     H,TTRACK
       LXI     D,TRACK
       CALL    CVERT
;
       LXI     H,TSECT
       LXI     D,SECT
       CALL    CVERT
;
       LXI     H,TDMA
       LXI     D,DMA
       CALL    CVERT
;
       LXI     H,TDMA+1
       LXI     D,DMA+2
       CALL    CVERT
;
       LXI     H,TABSTG
       CALL    MSG
       POP     B
       POP     D
       POP     H
       RET
;
;
CVERT:  EQU     $+OFFSET
       MOV     A,M
       ANI     0F0H
       RRC
       RRC
       RRC
       RRC     ;CONVERT THE HIGH NIBBLE FIRST
       CALL    ASCII
       STAX    D
       INX     D
       MOV     A,M     ;STORE CHAR IN PRINT LINE
       ANI     0FH
       CALL    ASCII
       STAX    D
       RET             ;CONVERT LOW NIBBLE
;
;
;CONVERT A TO ASCII
;
ASCII:  EQU     $+OFFSET
       ADI     30H
       CPI     '9'+1   ;FE 3A OPCODE
       RM
       ADI     7
       RET             ;A NOW IN ASCIIFORM
;
;PMSG STRING POINTED TO BY HL TO LOGOUT
;MSB OF 1 IN LAST CHARACTER SENDS CR,LF.
;ZERO WILL ALSO END STRING WITH NO CR,LF...
;
;
MSG:    EQU     $+OFFSET
       MOV     C,M     ;C=CHAR TO SEND TO CONSOLE
       CALL    LOGOUT
       MOV     A,M
       ANI     80H
       JNZ     LFCR    ;LAST ONE IF MSB=1
       INX     H
       MOV     A,M
       ORA     A       ;TEST CHAR FOR 0
       RZ
       JMP     MSG
;
;SEND CR,LF TO CONSOLE
;
LFCR:   EQU     $+OFFSET
       MVI     C,CR
       CALL    LOGOUT
       MVI     C,LF
       CALL    LOGOUT
       RET
;
LOGOUT: EQU     $+OFFSET
       PUSH    H
       MOV     A,C
       ANI     7FH     ;STRIP HIGH BIT
       MOV     C,A     ;PUT IT BACK IN C FOR BIOS
OVLAY1: CALL    $-$     ;CALL BIOS (ADDRESS OVERLAYED)
       POP     H
       RET
;
;PRINT MESSAGE TO CRT VIA BIOS
CRTMSG: EQU     $+OFFSET
       MOV     C,M     ;C=CHAR TO SEND TO CONSOLE
       PUSH    H
OVLAY2: CALL    $-$     ;BIOS CONOUT
       POP     H
       INX     H
       MOV     A,M
       ORA     A       ;TEST CHAR FOR 0
       RZ
       JMP     CRTMSG
;
;       OLD BIOS STORAGE
OLDDSK: EQU     $+OFFSET
       DB 0,0,0
OLDTRK: EQU     $+OFFSET
       DB 0,0,0
OLDSEC: EQU     $+OFFSET
       DB 0,0,0
OLDDMA: EQU     $+OFFSET
       DB 0,0,0
OLDRED: EQU     $+OFFSET
       DB 0,0,0
OLDWRT: EQU     $+OFFSET
       DB 0,0,0
;
;PRINT TABLE STORAGE
TABSTG: EQU     $+OFFSET
       DB      ' DSK- '
;
DISK:   EQU     $+OFFSET
       DB      20H,20H
       DB      ' TRK- '
;
TRACK:  EQU     $+OFFSET
       DB      20H,20H
       DB      ' SEC- '
;
SECT:   EQU     $+OFFSET
       DB      20H,20H
       DB      ' DMA- '
;
DMA:    EQU     $+OFFSET
       DB      20H,20H,20H,20H
       DB      ' OPCD-  '
;
OPCD:   EQU     $+OFFSET
       DB      20H,0A0H
;
;
;TEMP VALUE STORAGE
;
TDISK:  EQU     $+OFFSET
       DB      0
TTRACK: EQU     $+OFFSET
       DB      0
TSECT:  EQU     $+OFFSET
       DB      0
TDMA:   EQU     $+OFFSET
       DB      0,0
TOPCD:  EQU     $+OFFSET
       DB      0
;
;
PROEND: EQU     $
;
;
       END     START