;
; DOS SIMULATOR
;
; MODIFICATIONS TO CP/M TO IMPROVE ITS COMPATIBILITY
; WITH CROMENCO'S DISK OPERATING SYSTEM.
;
; NOTE: CROMENCOS DISK SYSTEM TREATS CP/M
; CALLS AS A SUBSET OF THEIR OWN SYSTEM, IN
; ADDITION, SEVERAL OF THE CP/M CALLS HAVE
; BEEN EMBLISHED.
;
; NOT ALL OF THE SPECIAL CALLS HAVE BEEN COVERED BY
; THESE MODIFICATIONS. ALSO YOU WILL NEED A Z80 PROCESSOR
; TO RUN MOST PROGRAMS WRITEN FOR THE CROMENCO
; DISK SYSTEM.
;
; IMPLEMNTATION NOTES:
;
; (1) CPMB = STARTING ADDRESS OF CP/M BDOS
; (2) THESE INTERNAL LOCATIONS ARE FOR
;     CP/M VERSION 1.4. (AND CAN BE EXPECTED TO VARY)
;     (A) CPMB+807H, A JUMP IN CP/M WHICH
;         IS REPLACED BY A JUMP TO DSIM.
;     (B) CPMB+0A07H, A FLAG/CHR BUFFER USED
;         BY THE CP/M I/O ROUTINES
;     (C) CPMB+869H, 8FAH, AND 9F8H FOR
;         THE CONTROL C ADDRESS.
; (3) IN THE GOCPM ROUTINE IN WARM BOOT, ADD:
;         LXI H,DSIM
;         SHLD CPMB+807H
;     THIS PROVIDES THE LINK TO DSIM
; (4) DSIM CAN RESIDE IN THE CBIOS.
; (5) REMEMBER, DON'T LET THE CBIOS GET TO
;     LONG, OR THERE WON'T BE SPACE FOR IT
;     ON THE DISK.
; (6) DMAADD IS ADDRESS OF LOCATION WHERE CP/M STORES
;     THE DMA ADDRESS.
;
; DOS SIMULATOR
;
; FIRST SORT OUT THE CP/M CALLS WE
; NEED TO MODIFY.
;
DSIM:   MOV     A,C             ; GET COMMAND
       CPI     0AH             ; READ BUFFER?
       JZ      FLIN            ; YES
       CPI     0FH             ; OPEN FILE?
       JZ      FHL             ; YES
       CPI     11H             ; SEARCH FOR FILE?
       JZ      FHL             ; YES
       CPI     12H             ; SEARCH FOR NEXT?
       JZ      FHL             ; YES
       ORA     A               ; RETURN TO DOS?
       JZ      WBOOT           ; YES
       JMP     CPMB+841H       ; IF BIT=7=0 NORMAL CPM
;
; ADDED CALLS
;
       ANI     0FH             ; INPUT W/OUT ECHO
       JZ      CONIN1          ; YES
       CPI     02H             ; CONTROL C?
       JZ      SCC             ; YES
       CPI     06H             ; SET UP FCB?
       JZ      SFCB            ; YES
       CPI     09H             ; DO DE=DE*HL?
       JZ      CMULT           ; YES
       CPI     0AH             ; DO HL=HL/DE?
       JZ      SDIV            ; YES
;
; IF WE GET HERE, CALL IS NOT HANDLED
; THIS JUMP IS TO THE BREAKPOINT ROUTINE
; IN MY PROM MONITOR, AND SHOULD BE REPLACED
; ANYWAY YOU SEE FIT
;
       JMP     0C108H
;
; CHANGE CONTROL C ADDRESS
;
SCC:    XCHG                    ; GET ADDRESS
       SHLD    CPMB+869H
       SHLD    CPMB+8FAH
       SHLD    CPMB+9F8H
       XRA     A
       RET
;
; ADD NULL TO INPUT BUFFER
;
FLIN:   PUSH    D               ; SAVE BUFFER ADD
       CALL    CPMB+841H       ; GO GET INPUT
       POP     H               ; GET ADDRESS
       MOV     A,M             ; REQ. NO.
       INX     H
       MOV     C,M             ; ACTUAL
       CMP     C
       RZ                      ; BUFFER FULL
       INX     H               ; FIRST CHAR
       XRA     A
       MOV     B,A
       DAD     B               ; GET LAST LOC
       MOV     M,A             ; ADD NULL
       RET
;
; NON ECHO CONSOLE INPUT
;
CONIN1: LDA     CPMB+0A07H      ; CPM CHR READY FLAG
       ORA     A
       JNZ     CONIN2          ; ONE WAITING
       CALL    CONIN
CONIN2: PUSH    PSW
       XRA     A               ; CLEAR FLAG
       STA     CPMB+0A07H
       POP     PSW
       RET
;
; SIMPLE DIVIDE
;
SDIV:   MOV     A,D             ; CHECK FOR ZERO
       ORA     E
       JNZ     SDIV1
       MOV     L,A             ; ANSWER
       MOV     H,A
       DCR     A               ; A=FF
       RET
SDIV1:  LXI     B,1
SDIV2:  MOV     A,L
       SUB     E
       MOV     L,A
       MOV     A,H
       SBB     D
       MOV     H,A
       JM      SDIV3
       INX     B
       JMP     SDIV2
;
SDIV3:  DAD     D
       DCX     B
       XCHG
       PUSH    B
       POP     H
       XRA     A
       RET
;
; MULTIPLY
;
CMULT:  MVI     A,10H
       STA     SHFT            ; TO DO
       PUSH    H               ; SWAP
       POP     B
       LXI     H,0             ; ZERO
CMULT1: DAD     H               ; SHIFT PRODUCT
       ORA     A               ; CLR CARRY
       MOV     A,E             ; 16 BIT SHIFT
       RAL
       MOV     E,A
       MOV     A,D
       RAL
       MOV     D,A
       JNC     CMULT2          ; IF NO CY, SKIP
       DAD     B               ; ADD
CMULT2: LDA     SHFT            ; SEE IF DONE
       DCR     A
       STA     SHFT            ; JUST IN CASE
       JNZ     CMULT1          ; MORE
       PUSH    H
       POP     D
       RET
;
; FIX HL ON SEARCH, OPEN COMMANDS
;
FHL:    CALL    CPMB+841H
       CPI     0FFH            ; SKIP?
       RZ                      ; YES
       PUSH    PSW
       RRC
       RRC
       RRC
       ANI     60H
       LHLD    DMAADD
       MVI     D,0
       MOV     E,A
FHL1:   DAD     D               ; BASE ADDRESS
       MOV     A,M             ; EMPTY?
       CPI     0E5H
       JZ      FHLE            ; YES, SKIP
       PUSH    H               ; SAVE
       LXI     D,0FH           ; CHECK EXT
       DAD     D
       MOV     A,M
       CPI     80H             ; FULL?
       JNZ     FHLE1
       MVI     A,0EFH
       CMP     L
       JZ      FHLE1
       POP     H
       LXI     D,20H
       JMP     FHL1
;
FHLE1:  POP     H
FHLE:   POP     PSW
       RET
; SET UP FILE CONTROL BLOCK
;
; HL=SORCE
; DE=DEST
; FIRST CLEAR FCB
;
SFCB:   XCHG
       PUSH    H               ; SAVE FOR EXIT
       MVI     M,0
       INX     D               ; LOOK FOR COLON
       LDAX    D               ; GET CHAR
       DCX     D               ; IF NOT A COLON
       CPI     ':'
       JNZ     SFCB7           ; NOPE
       LDAX    D               ; GET DRIVE
       ANI     03H             ; STRIP
       MOV     M,A             ; SET FCB
       INX     D               ; AHEAD TO NAME
       INX     D
SFCB7:  INX     H
       PUSH    H               ; FOR FILENAME
       MVI     A,11
SFCB1:  MVI     M,20H           ; SPACE
       INX     H
       DCR     A
       JNZ     SFCB1
       MVI     A,21            ; CLEAR
SFCB2:  MVI     M,0
       INX     H
       DCR     A
       JNZ     SFCB2
       POP     H
       PUSH    H
;
; HL=FCB+1
; DE=SCORCE
; STACK=FCB+1,FCB
;
       MVI     C,8+1
SFCB3:  LDAX    D
       CPI     '.'
       JZ      SFCB4
       CPI     '/'
       JM      SEXIT
       DCR     C
       JZ      SFCB5
       MOV     M,A
       INX     H
       INX     D
       JMP     SFCB3
;
SFCB4:  INX     D
SFCB5:  POP     H
       PUSH    H       ; FOR EXIT
       LXI     B,8
       DAD     B
       MVI     C,3+1
SFCB6:  LDAX    D
       CPI     '/'
       JM      SEXIT
       DCR     C
       JZ      SEXIT
       MOV     M,A
       INX     H
       INX     D
       JMP     SFCB6
;
SEXIT:  XCHG
       POP     D
       POP     D
       RET
;
SHFT:   DB      0               ; RAM FOR MULT
;