;; This example shows how it is possible to detect a Amstrad ;; or Vortex floppy disc controller. ;; ;; Both controllers use a NEC765 compatible floppy disc controller, ;; and the same control method to read/write to the discs ;; using the controller (polling). ;; ;; But the NEC765 controller is accessed through different ;; I/O port addressess for each controller. ;; ;; This example attempts to send a "invalid" command to the NEC765 ;; FDC. If the correct responses are detected, then it is assumed ;; that the controller is present and connected. org &4000 nolist .txt_output equ &bb5a .ams_fdc_io equ &fb7e ;; I/O address for main status register of NEC765 in Amstrad controller .vtx_fdc_io equ &fbf6 ;; I/O address for main status register of NEC765 in Vortex controller. ;;--------------------------------------------------- ;; ;; do detection and report result .do_detect ld hl,amstrad_di call output_text ;;------------------------------------ ;; detect amstrad floppy disc interface ld bc,ams_fdc_io call detect_fdc ld hl,detected jr nc,dd1 ld hl,not_detected .dd1 call output_text call crlf ;;------------------------------------ ;; detect vortex floppy disc interface ld hl,vortex_di call output_text ld bc,vtx_fdc_io call detect_fdc ld hl,detected jr nc,dd2 ld hl,not_detected .dd2 call output_text call crlf ret ;;----------------------------------------------------- ;; messages .amstrad_di defb "Amstrad disc interface",0 .vortex_di defb "Vortex disc interface",0 .detected defb " detected",0 .not_detected defb " not detected",0 ;;----------------------------------------------------- ;; new line .crlf ld a,13 call txt_output ld a,10 call txt_output ret ;;----------------------------------------------------- ;; output a null terminated string .output_text ld a,(hl) ;; get character inc hl ;; update character pointer or a ;; termination char (0)? ret z call txt_output ;; output character to screen jr output_text ;; loop for next character ;;----------------------------------------------------------------- ;; Entry conditions: ;; BC = I/O address for FDC main status register ;; ;; Exit conditions: ;; carry flag set -> not detected ;; carry flag clear -> detected ;; ;; assumes: ;; - I/O port for read data = I/O port for write data ;; - I/O port for read data = I/O port for write data = I/O port for main status register + 1 ;; - FDC is not executing a command at this time ;; ;; Attempts to execute a invalid command. .detect_fdc ;; initialise timeout ld e,0 .df1 ;; read main status register in a,(c) ;; isolate flags we are interested in and %11110000 ;; test for the following flags: ;; - Data register of FDC is ready for data transfer ;; - Data transfer direction is from CPU->FDC ;; - Not in Execution Mode ;; - FDC not busy cp %10000000 jr z,df2 ;; decrease timeout dec e jr nz,df1 ;; failed scf ret .df2 ;; ok... FDC is ready to accept a command ;;---------------------------------------- ;; write the "invalid" command inc c ;; BC = I/O address of FDC data register ;; code for invalid command xor a ;; write to FDC data register out (c),a dec c ;; BC = I/O address of FDC main status register ;;-------------------------- ;; wait for fdc to become busy ld e,0 .df3 ;; read main status register in a,(c) and %00010000 jr nz,df4 dec e jr nz,df3 ;; failed scf ret .df4 ;; saw fdc become busy ;;-------------------------------- ;; wait for execution phase ld e,0 .df5 in a,(c) and %11110000 ;; test for the following flags: ;; - Data register of FDC is ready for data transfer ;; - Data transfer direction is from CPU->FDC ;; - Not in Execution Mode ;; - FDC busy cp %11010000 jr z,df6 dec e jr nz,df5 ;; failed scf ret .df6 ;; ok saw start of result phase inc c ;; BC = I/O address of FDC data register ;; read result phase data in a,(c) dec c cp &80 jr nz,df7 ;; ok successful or a ret .df7 ;; failed scf ret