page ncrcsd equ 20h ncrodr equ 20h ncricr equ 21h ncrmr equ 22h ncrtcr equ 23h ncrcsbs equ 24h ncrser equ 24h ncrbsr equ 25h ncrsds equ 25h ncridr equ 26h ncrsdtr equ 26h ncrrpi equ 27h ncrsdir equ 27h ncrdack equ 28h ;************************************** ; ; scsi ncr interface ; ;entry: ; a = target address ; hl = point to scsi cmd ; de = point to data block ;exit: ; a = 0 ok (sets zero) ; a = 0ffh scsi timeout ; a = teac error ;************************************** sasi:: ;save scsi device id ld (target),a ;save block pointers cmd/data ld (cmd.ptr),hl ;save cmd ld (dat.ptr),de ;save data ;do the IO call select ;start io ;get exit status ld a,(status) or a ret ;***************************************** ; ;start IO here ; ;This is a state machine which is driven ;by the NCR chip. We could be here for a ;short period or for ever depending on the ;SCSI chip ; ;****************************************** select:: ;clear NCRs idea of the scsi state xor a out (ncricr),a ;state of buss out (ncrtcr),a ;what buss should be cleararbit: ;clear ncr mode xor a out (ncrmr),a ;reset ncr interrupts in a,(ncrrpi) ;put address on buss ld a,(target) out (ncrodr),a ;turn on data buss in a,(ncricr) or 01h out (ncricr),a ;put select on buss ld a,05h out (ncricr),a ;delay untill busy ld bc,6000h stim: ;check for busy in a,(ncrcsbs) and 040h ;mask busy jp nz,selectok dec c jp nz,stim dec b jp nz,stim ;buss timeout xor a out (ncrodr),a dec a ld (status),a jp alldone selectok: xor a alldone: ;check for timeout error ld b,a ;save status ld a,01h out (ncricr),a xor a out (ncricr),a ;clear data buss ld a,b or a ret nz dec a ld (status),a ;set dma mode and mointer busy ld a,06h out (ncrmr),a ;check ncr status after select scsirdy: in a,(ncrbsr) and 10h ;check for interrupt jr nz,scsiint in a,(ncrcsbs) and 20h ;check for sasi req jr z,scsirdy jp phase ;go to state look up ;this is the interrupt code scsiint: xor a out (ncricr),a ;free data buss in a,(ncrbsr) ;check for interrupt and 0ch jr nz,scsiexit ;this is the start of the code that switch phases phase: xor a out (ncrmr),a in a,(ncrrpi) ;reset ints ld a,06h out (ncrmr),a ;set dma and mointer busy in a,(ncrcsbs) ;update phase and 1ch ;mask used bits rra ld e,a rra out (ncrtcr),a ;update expected phase ;look up phase and jump to it ld d,0 ld hl,phasetable add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a ld d,40h jp (hl) phasetable: dw phase0 dw phase1 dw phase2 dw phase3 dw phase4 dw phase5 dw phase6 dw phase7 ;data out phase phase0: ld hl,(dat.ptr) ld e,1 jp wscsi ;data in phase phase1: ld hl,(dat.ptr) ld e,1 jp rscsi ;command out phase phase2: ld hl,(cmd.ptr) ld e,1 jp wscsi ;status in phase phase3: ld hl,status ld e,1 jp rscsi ;message phase phase7: ld hl,message ld e,1 jp rscsi ;bad phases phase4: phase5: phase6: scsiexit: xor a out (ncrtcr),a out (ncrmr),a in a,(ncrrpi) ret ;general scsi write code wscsi: ld a,01h ;assert data buss out (ncricr),a ld c,ncrdack out (ncrsds),a ;start dma ;check for dma req wscsi1: in a,(ncrbsr) ld b,a and d jr z,wscsi2 ;no dma now ;do io ld b,e otir jp wscsi1 ;check for interrupt wscsi2: ld a,b and 10h jp z,wscsi1 jp scsiint ;general scsi read rscsi: ld c,ncrdack out (ncrsdir),a ;start dma read ;wait for dma rscsi1: in a,(ncrbsr) ld b,a and d jr z,rscsi2 ;no dma now ;do the io ld b,e inir jp rscsi1 ;check for interrupt rscsi2: ld a,b and 10h jp z,rscsi1 ;no ints now jp scsiint page target: db 0 status: db 0 message: db 0 cmd.ptr: dw 0 dat.ptr: dw 0