; > DiscBash1   Reads a sector using the F311-L11 controller, and prints
;               the contents of the sector on console.
;
;               Prompts user for track/sector required.
;
        ORG     512             ; Octal 1000
;
        MOV     #512,R6         ; initialise stack
        JSR     R7,@#CRLF
LOOP:   JSR     R7,@#CRLF
        JSR     R5,@#MSSG
        DEFS    " Track ?"
        DEFB    &A0
        ALIGN
        JSR     R7,@#GETV
        MOV     R5,R0
        JSR     R5,@#MSSG
        DEFS    "Sector ?"
        DEFB    &A0
        ALIGN
        JSR     R7,@#GETV
        MOV     R5,R1
        JSR     R7,@#DONE
        MOV     #7,@#O177170    ; load READ SECTOR command inc GO bit
        JSR     R7,@#TREQ
        MOV     R1,@#O177172    ; load sector number
        JSR     R7,@#TREQ
        MOV     R0,@#O177172    ; load track number
        JSR     R7,@#CRLF
        CLR     R0
        JSR     R7,@#DONE
        MOV     #3,@#O177170    ; load READ BUFFER command and GO bit
BYTE:   JSR     R7,@#TREQ
        MOV     @#O177172,R5    ; get byte
        JSR     R7,@#PRTH
        MOV     #&20,R5         ; space after each byte
        JSR     R7,@#PRTA
        INC     R0
        BIT     #15,R0
        BNE     BYTE
        JSR     R7,@#CRLF         ; newline after every 16 bytes
        BIT     #128,R0
        BEQ     BYTE
        BR      LOOP
;
DONE:   BIT     #O40,@#O177170  ; look for DONE bit
        BEQ     DONE
        RTS     R7
;
TREQ:   BIT     #O200,@#O177170 ; look for TRANSFER REQUEST bit
        BEQ     TREQ
        RTS     R7
;
; > Print_Lib   Library of console print subroutines
;
;               Includes PRTH - prints R5 (16 bits) in hex
;                        PRTO - prints R5 (16 bits) in octal
;                        PRTA - prints R5 (8 bits) in ASCII
;                        MSSG - prints the string following the JSR
;                               (terminate with top-bit-set character/byte)
;                        CRLF - prints carriage-return/linefeed
;
;       All subroutines link with R7 except MSSG (link with R5)
;
;
CRLF:   MOV     #13,R5          ; print <CR> and <LF> on console
        JSR     R7,@#PRTA
        MOV     #10,R5
        JSR     R7,@#PRTA
        RTS     R7
;
PRTH:   MOV     R5,-(R6)        ; print R5 in hex
        ASR     R5
        ASR     R5
        ASR     R5
        ASR     R5
        JSR     R7,@#HEX1
        MOV     (R6)+,R5
        BIC     #&F0,R5
HEX1:   BIS     #ASC"0",R5      ; make hex into ASCII and print it
        CMPB    #ASC"9",R5
        BPL     PRTA
        ADD     #7,R5
;
PRTA:   TSTB    @#O177564       ; wait for console XBUFF to be ready
        BPL     PRTA
        MOV     R5,@#O177566
        RTS     R7
;
PRTO:   MOV     R0,-(R6)        ; save R0,R4 on stack
        MOV     R4,-(R6)
        MOV     R5,R4
        MOV     #O30,R5         ; R4 will be 6x after shifts
        ROL     R4              ; rotate 1 bit from R4 to R5
        ROL     R5
        JSR     R7,@#PRTA       ; print - as ASCII since it's 6x
        MOV     #5,R0           ; set to do five octets
CLOOP:  MOV     #6,R5           ; 6>>3 becomes octal 60, ie "0"
        ROL     R4              ; rotate R4>R5: 3 bits of octal number
        ROL     R5              ; could use ASHC R4,#3 if we have EIS
        ROL     R4
        ROL     R5
        ROL     R4
        ROL     R5
        JSR     R7,@#PRTA       ; print a digit
        DEC     R0              ; one less digit to do
        BNE     CLOOP
        MOV     (R6)+,R4        ; restore caller's R4,R0
        MOV     (R6)+,R0
        RTS     R7
;
MSSG:   TSTB    @#O177564       ; prints message at word following call
        BPL     MSSG
        MOVB    (R5),@#O177566  ; print char just past where we were
        TSTB    (R5)+           ; see if it was last, and point to next
        BPL     MSSG            ; top bit set = finished
        INC     R5              ; in case it's not on a word boundary
        BIC     #1,R5           ; in case it was
        RTS     R5
;
; > Input_Lib   Library of subroutines to call console for input.
;
;               Includes GETA - gets a single ASCII character in R5
;                        GETV - gets a 16-bit decimal value in R5.
;                        GETO - gets a 16-bit octal value in R5
;                        GETH - gets a 16-bit hex value in R5
;                        GETS - gets a string to the buffer located by R5
;                               Size of buffer must be in R4.
;
;   All routines linked to by R7.
;
GETA:   TSTB    @#O177560       ; wait for character
        BPL     GETA
        MOV     @#O177562,R5
        RTS     R7
;
GETV:   CLR     -(R6)           ; clear a word on the stack
GETV1:  JSR     R7,@#GETA       ; get a character
        CMP     #33,R5
        BMI     DECIN           ; terminate on any control char or space
        JSR     R7,@#CRLF       ; ***** remove if not required *****
        MOV     (R6)+,R5
        RTS     R7
DECIN:  CMP     R5,#ASC"0"      ; check character>="0"
        BMI     GETV1
        CMP     #ASC"9",R5      ; check character<="9"
        BMI     GETV1
        JSR     R7,@#PRTA       ; ***** remove if not required *****
        BIC     #ASC"0",R5      ; ascii-to-decimal
        ASL     (R6)            ; times 2
        ADD     (R6),R5         ; add to the new value
        ASL     (R6)            ; times 4
        ASL     (R6)            ; times 8
        ADD     R5,(R6)         ; times 10, plus new value
        BR      GETV1
;
GETO:   CLR     -(R6)           ; stack space for value
GETO1:  JSR     R7,@#GETA
        CMP     #33,R5          ; terminate on any control char or space
        BMI     OCTIN
        JSR     R7,@#CRLF       ; ***** remove if not required *****
        MOV     (R6)+,R5
        RTS     R7
OCTIN:  CMP     R5,#ASC"0"      ; if not CR, test for numeric
        BMI     GETO1
        CMP     R5,#ASC"8"
        BPL     GETO1
        JSR     R7,@#PRTA       ; ***** remove if not required *****
        BIC     #&F8,R5         ; mask off to make octal
        ASL     (R6)            ; move one octet
        ASL     (R6)
        ASL     (R6)
        ADD     R5,(R6)         ; add this octet
        BR      GETO1
;
GETH:   CLR     -(R6)           ; clear a word on the stack
GETH1:  JSR     R7,@#GETA
        CMP     #33,R5          ; terminate on any control char or space
        BMI     HEXIN
        JSR     R7,@#CRLF       ; ***** remove if not required *****
        MOV     (R6)+,R5
        RTS     R7
HEXIN:  CMP     R5,#ASC"0"
        BMI     GETH1
        CMP     #ASC"F",R5
        BMI     GETH1
        CMP     #ASC"9",R5
        BPL     OKVAL
        CMP     R5,#ASC"A"
        BMI     GETH1
OKVAL:  JSR     R7,@#PRTA       ; ***** remove if not required *****
        CMP     #ASC"9",R5
        BPL     $+6
        SUB     #ASC"A"-ASC"9",R5
        BIC     #ASC"0",R5
        ASL     (R6)
        ASL     (R6)
        ASL     (R6)
        ASL     (R6)
        ADD     R5,(R6)
        BR      GETH1
;
