.TITLE IOSCAN -- I/O PAGE SCANNER .IDENT /V04.00/ ;+ ; Copyright (c) 2012, 1214 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. ;- IOBASE == 160000 ;I/O PAGE BASE ADDRESS PR0 == 0 ;CPU PRIORITY 0 PR7 == 340 ;CPU PRIORITY 7 .PSECT CODE,GBL,I,RO ;+ ;$ISCAN -- SCAN I/O PAGE. SHOULD BE CALLED AT PR7 ; ;INPUT: ; NONE ; ;OUTPUT: ; R1, R2 - DESTROYED ;- $ISCAN:: MOV #IOBASE,R1 ;;;SET I/O PAGE BASE ADDRESS MOV #IOMAP,R2 ;;;SET I/O PAGE BITMAP ADDRESS 10$: TST @R1 ;;;TEST I/O PAGE ADDRESS ROL @R2 ;;;SAVE STATUS ADD #2,R1 ;;;POINT TO NEXT ADDRESS BNE 20$ ;;;WE HAVE MORE ADDRESSES TO TEST RETURN ;;;RETURN 20$: BIT #37,R1 ;;;BITMAP WORD FILLED? BNE 10$ ;;;IF NE, NO TST (R2)+ ;;;SWITCH TO NEXT WORD BR 10$ ;;;LOOP ;+ ;$IPRNT -- PRINT EXISTENT I/O PAGE ADDRESSES ; ;INPUT: ; NONE ; ;OUTPUT: ; R1, R2 - DESTROYED ;- $IPRNT:: MOV #IOBASE,R1 ;SET I/O PAGE BASE ADDRESS MOV #IOMAP,R2 ;SET I/O PAGE BITMAP ADDRESS 10$: ROL @R2 ;GET ADDRESS STATUS BCS 30$ ;IF CS, NO SUCH ADDRESS MOV R1,R4 ;UPDATE LAST ADDRESS OF RANGE TST R3 ;FIRST ADDRESS OF RANGE SET? BNE 20$ ;IF NE, YES MOV R4,R3 ;SET FIRST ADDRESS OF RANGE 20$: ADD #2,R1 ;SWITCH TO NEXT ADDRESS BEQ $PADDR ;IF EQ, END OF I/O PAGE REACHED BIT #37,R1 ;BITMAP WORD TESTED? BNE 10$ ;NO, LOOP TST (R2)+ ;SWITCH TO NEXT WORD BR 10$ ;LOOP 30$: MOV #20$,-(SP) ;SET RETURN ADDRESS ;FALLTHROUGH ;+ ;$PADDR -- PRINT ADDRESS RANGE ; ;INPUT: ; R3 - FIRST ADDRESS OF RANGE ; R4 - LAST ADDRESS OF RANGE ;- $PADDR:: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; MOV R3,R1 ;GET FIRST ADDRESS BNE 20$ ;IF NE, ADDRESS RANGE SET 10$: MOV (SP)+,R2 ;RESTORE REGISTERS MOV (SP)+,R1 ; RETURN ;RETURN 20$: MOV #RANGE,R0 ;SET BUFFER ADDRESS CALL $OCTAL ;CONVERT TO ASCII CMP R3,R4 ;SINGLE ADDRESS RANGE? BEQ 30$ ;IF EQ, YES MOVB #'-,(R0)+ ;DASH MOV R4,R1 ;GET LAST ADDRESS OF RANGE CALL $OCTAL ;CONVERT TO ASCII 30$: CLRB @R0 ;MAKE STRING ASCIZ CLR R3 ;CLEAR ADDRESS RANGE CLR R4 ; MOV #RANGE,R0 ;PRINT STRING CALL $PRINT ; BR 10$ ;RETURN $OCTAL:: MOV #6,R2 ;SET DIGIT COUNT CLR -(SP) ;INITIALIZE DIGIT BR 20$ ;CONVERT HIGHEST BIT 10$: CLR @SP ;INITIALIZE DIGIT ROL R1 ;COPY DIGIT ROL @SP ; ROL R1 ; ROL @SP ; 20$: ROL R1 ; ROL @SP ; ADD #'0,@SP ;CONVERT TO ASCII MOVB @SP,(R0)+ ;COPY INTO BUFFER DEC R2 ;LOOP BNE 10$ ; TST (SP)+ ;RESTORE STACK RETURN ;RETURN .END ;THE END