.TITLE MY -- MY HANDLER FOR XXDP+ V2.4/2.5 .IDENT /A.3/ ;+ ; Copyright (c) 2015 Oleg Safiullin ; ; Permission to use, copy, modify, and distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ; ; HISTORY: ; 1-APR-2015 A.0 INITIAL RELEASE ; 2-APR-2015 A.1 DON'T FORGET TO INDICATE I/O ERROR ; 4-APR-2015 A.2 FIX PRINTING OF ERROR MESSAGES ; 5-APR-2015 A.3 REDUCE CODE SIZE TO FIT INTO 1 BLOCK ;- ;+ ;DEVICE DESCRIPTOR BLOCK OFFSETS ;- XSV =: -12 ;SERVICE ROUTINE XDN =: -2 ;DRIVE NUMBER XER =: -1 ;ERROR STATUS XCM =: 0 ;COMMAND REGISTER ADDRESS XWC =: 2 ;WORD COUNT XBA =: 4 ;BUFFER ADDRESS XDT =: 6 ;BLOCK NUMBER XCO =: 10 ;COMMAND ;+ ;DEVICE COMMAND CODES ;- INIT$ =: 0 ;INITIALIZE DEVICE READ$ =: 1 ;READ WRITE$ =: 2 ;WRITE RES$FN =: 3 ;RESTORE FUNCTION FOR MONITOR ;+ ;DEVICE CODE BYTES ;- MULUN$ =: 100 ;DRIVER PERMITS MULTIPLE DEVICES ;+ ;MY REGISTER AND BIT DEFINITIONS ;- MYCS =: 0 ;MY CONTROL/STATUS REGISTER MYDA =: 2 ;MY DATA REGISTER .ASECT ;+ ;XXDP DEVICE DRIVER PARAMETER TABLE ;- .WORD DISPAT ;DISPATCH ROUTINE .WORD "MY ;DRIVER NAME .BYTE MULUN$ ;DEVICE CODE .BYTE 333 ;RETURNED DEVICE STATUS (DEVICE TYPE) .WORD BCODE ;BOOT CODE OFFSET .BYTE 'A ;UNIT # (REV A) .BYTE '3 ;ERROR STATUS (PATCH 3) .WORD 172140 ;COMMAND REGISTER ADDR .WORD 0 ;WORD COUNT .WORD 0 ;BUS ADDRESS .WORD 0 ;BLOCK NUMBER .WORD 0 ;COMMAND .WORD DIRBLK ;POINTS TO 1ST DIR BLOCK .WORD 0 ;FOR MONITOR COMPATIBILITY ;+ ;PARAMETERS USED TO DEFINE DISK LAYOUT ;- DIRBLK: .WORD 3 ;1ST UFD BLOCK ADDR .WORD 16. ;NUMBER OF UFD BLOCKS .WORD 19. ;1ST BIT MAP BLOCK ADDR .WORD 4 ;NUMBER OF MAP BLOCKS .WORD 1 ;MFD1 BLOCK ADDR .WORD 2 ;VERSION 2 FLAG .WORD 1600. ;MAX NUMBER OF BLOCKS ON DEVICE .WORD 55. ;# OF BLOCKS TO PREALLOCATE AT ZERO .WORD 1 ;INTERLEAVE FACTOR .WORD 0 ;BOOT BLOCK # MONBLK: .WORD 23. ;MONITOR CORE IMAGE BLOCK # .WORD 0 ;MFD REFRESHED FLAG ;+ ;ERROR MESSAGES ;- MWTERR: .ASCIZ / ? WR ERR/ MRDERR: .ASCIZ / ? RD ERR/ ILLERR: .ASCIZ / ? ILLEGAL CMND ERROR/ .EVEN ;+ ;MAIN DISPATCH ROUTINE ;- DISPAT: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) ; MOV R2,-(SP) ; MOV R3,-(SP) ; JSR R4,10$ ;DO A TABLE SEARCH ;+ ;FUNCTION TABLE ;- .WORD INIT$,INIT-. ;INITIALIZE .WORD RES$FN,RESTOR-. ;MONITOR RESTORE .WORD READ$,DRIVER-. ;READ .WORD WRITE$,DRIVER-. ;WRITE .WORD -1 ;END OF TABLE 10$: CMP (R4)+,XCO(R5) ;IS IT OUR FUNCTION? BEQ 30$ ;EQ = YES TST (R4)+ ;TO NEXT FUNCTION TST @R4 ;END OF TABLE? BPL 10$ ;PL = NO MOV PC,R0 ;NOT LEGAL COMMAND ADD #ILLERR-.,R0 ; EMT 3 ; EMT 23 ; MOVB #-1,XER(R5) ;SIGNAL 20$: MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 ; MOV (SP)+,R2 ; MOV (SP)+,R1 ; MOV (SP)+,R0 ; TSTB XER(R5) ;SET ERROR INDICATOR RETURN ;RETURN 30$: ADD @R4,R4 ;GET REAL ADDRESS CALL @R4 ;AND DO IT BR 20$ ;AND LEAVE ;+ ;INITIALIZE ROUTINE ;- INIT: CLRB XER(R5) ;ASSUME GOOD RESULT RETURN ;RETURN ;+ ;ROUTINE TO READ PART OF THE MONITOR CORE IMAGE ;- RESTOR: ADD MONBLK,XDT(R5) ;MAKE BLK NUMBER RELATIVE TO 0 MOV #READ$,XCO(R5) ;DO A READ FUNCTION JMP @XSV(R5) ;LET DRIVER TO DO IT AND RETURN ;+ ;READ/WRITE DRIVER FOR THE MY ;- DRIVER: CLRB XER(R5) ;ASSUME GOOD RESULT MOV XDT(R5),R0 ;GET BLOCK NUMBER MOV XDN(R5),R4 ;GET DEVICE NUMBER BIC #^C3,R4 ;MASK IRRELEVANT BITS MOV #10.,R2 ;SET RETRY/SECTOR COUNT MOV #16.,R3 ;SET LOOP COUNT CLR R1 ;CLEAR REMAINDER 10$: ASL R0 ;DOUBLE LEFT SHIFT ROL R1 ; CMP R1,R2 ;SUTRACT OUR DIVISOR? BLO 20$ ;IF LO NO SUB R2,R1 ;SUBTRACT OUR DIVISOR INC R0 ;ADD IN LOW BIT 20$: DEC R3 ;DECREMENT REPEAT COUNT BGT 10$ ;IF GT MORE TO GO INC R1 ;R1->SECTOR MOV PC,R3 ;GET ADDRESS OF I/O DESCRIPTOR ADD #DESCR+10-.,R3 ;+10 ASR R0 ;R0->TRACK BCC 30$ ;IF CC, SIDE 0 BIS #4,R4 ;SET SIDE 1 30$: MOV XWC(R5),-(R3) ;SET WORD COUNT MOVB R0,-(R3) ;SET TRACK MOVB R1,-(R3) ;SET SECTOR MOV XBA(R5),-(R3) ;SET BUFFER ADDRESS MOV R4,-(R3) ;SET UNIT & SIDE MOV #1,R0 ;ASSUME READ FUNCTION CMP #READ$,XCO(R5) ;READ FUNCTION? BEQ 40$ ;YES MOV #3,R0 ;SET WRITE FUNCTION 40$: MOV XCM(R5),R4 ;GET DEVICE REGISTER ADDR BIT #40,@R4 ;CONTROLLER READY? BEQ .-4 ;NO 60$: MOV R0,@R4 ;SEND COMMAND TSTB @R4 ;DATA REQUESTED? BPL .-2 ;NO MOV R3,MYDA(R4) ;START I/O 70$: BIT #40,@R4 ;I/O DONE? BEQ 70$ ;NO TST @R4 ;I/O ERROR? BPL 90$ ;NO DEC R2 ;RETRY BNE 60$ ; DECB XER(R5) ;INDICATE ERROR CMP #READ$,XCO(R5) ;READ ERROR? BEQ 80$ ;YES MOV PC,R0 ;ELSE WRITE ERROR ADD #MWTERR-.,R0 ; EMT 44 ; RETURN ;RETURN 80$: MOV PC,R0 ;WRITE ERROR ADD #MRDERR-.,R0 ; EMT 44 ; 90$: RETURN ;RETURN DESCR: .BLKW 4 ;I/O DESCRIPTOR BEGIN =: 1046 ;MONITOR START ADDRESS ;+ ;BOOTSTRAP CODE ;- BCODE: NOP ;START BOOT ROUTINE BR START ; .WORD 6 ;TRAP CATCHER HALT ; .WORD 12 ; HALT ; .BLKB 4 ; MYCSR: .WORD 172140 ;CSR ADDRESS START: NOP ; BR START1 ; .BLKB 12 ; .WORD 0,0 ; .BLKB 24 ; START1: MOV #60000,SP ;INITIALIZE STACK POINTER MOV MYCSR,R1 ;GET CSR ADDRESS MOV MYDA(R1),R2 ;GET BOOTED DEVICE UNIT SWAB R2 ; BIC #^C3,R2 ; JSR R2,10$ ;R2=I/O DESCRIPTOR ADDRESS .WORD 0,1000,405,17400 ;I/O DESCRIPTOR 10$: BIS @SP,@R2 ;SET DEVICE UNIT 20$: MOV #10.,R3 ;SET RETRY COUNT 30$: BIT #40,@R1 ;CONTROLLER READY? BEQ 30$ ;EQ = NO 35$: MOV #1,@R1 ;READ COMMAND 40$: TSTB @R1 ;DATA REQUESTED? BPL 40$ ;PL = NO MOV R2,2(R1) ;START I/O 50$: BIT #40,@R1 ;WAIT FOR COMPLETION BEQ 50$ ; TST @R1 ;I/O ERROR? BPL 60$ ;PL = NO DEC R3 ;RETRY BNE 30$ ; HALT ;HALT BR 20$ ;TRY AGAIN 60$: MOV (SP)+,R2 ;RESTORE UNIT NUMBER JMP @#BEGIN ;START XXDP+ .END