mirror of
https://github.com/DoctorWkt/pdp7-unix.git
synced 2026-01-28 21:01:39 +00:00
Merge pull request #163 from sebras/describe/dskio.s
Attempt to describe purpose of source code in dskio.s
This commit is contained in:
135
src/cmd/dskio.s
135
src/cmd/dskio.s
@@ -1,78 +1,119 @@
|
||||
" dskio
|
||||
|
||||
" Reads 10 blocks from side 0 at block address AC into buffer dskbuf
|
||||
dskrd0: 0
|
||||
dzm side
|
||||
jms dskio; 02000
|
||||
jmp i dskrd0
|
||||
dzm side " set side to 0
|
||||
jms dskio; 02000 " read 10 blocks starting at block AC on side 0
|
||||
jmp i dskrd0 " return to caller
|
||||
|
||||
" Writes 10 blocks from buffer dskbuf onto side 0 at block address AC
|
||||
dskwr0: 0
|
||||
dzm side
|
||||
jms dskio; 03000
|
||||
jmp i dskwr0
|
||||
dzm side " set side to 0
|
||||
jms dskio; 03000 " write 10 blocks tarting at block AC on side 0
|
||||
jmp i dskwr0 " return to caller
|
||||
|
||||
" Reads 10 blocks from side 1 at block address AC into buffer dskbuf
|
||||
dskrd1: 0
|
||||
lmq
|
||||
lmq " set side to 1
|
||||
lac o200000
|
||||
dac side
|
||||
lacq
|
||||
jms dskio; 02000
|
||||
jmp i dskrd1
|
||||
jms dskio; 02000 " read 10 blocks starting at block AC on side 1
|
||||
jmp i dskrd1 " return to caller
|
||||
|
||||
" Writes 10 blocks from buffer dskbuf onto side 1 at block address AC
|
||||
dskwr1: 0
|
||||
lmq
|
||||
lmq " Set side to 1
|
||||
lac o200000
|
||||
dac side
|
||||
lacq
|
||||
jms dskio; 03000
|
||||
jmp i dskwr1
|
||||
|
||||
jms dskio; 03000 " write 10 blocks starting at block AC on side 1
|
||||
jmp i dskwr1 " return to caller
|
||||
|
||||
" dskio depends on the DSLS_BITS after jump to subroutine:
|
||||
" jms dskio; DSLS_BITS
|
||||
" DSLS_BITS 02000 causes a read, 03000 causes a write.
|
||||
"
|
||||
" In both cases 10 blocks worth of data is either transferred from
|
||||
" disk into dskbuf (read), or transferred from dskbuf onto the disk
|
||||
" (write). A block is the same as a segment, each comprising 64 words.
|
||||
"
|
||||
" The location on disk is controlled by the variable "side" and the
|
||||
" value in AC, representing the number of blocks from the start
|
||||
" of the side.
|
||||
"
|
||||
" dskio takes the block address passed in AC, divides it by 80
|
||||
" to get the track address, and as a remainder the segment address.
|
||||
" Both are then re-encoded as BCD, shifted to the correct bit
|
||||
" positions (explained below) and ORed together with the value of
|
||||
" the "side" variable (representing the hundreds flag in the disk
|
||||
" address). This disk address is then passed on to the disk just
|
||||
" before starting the transfer in chunks of 10 segments each.
|
||||
"
|
||||
" The disk address for RB09 disks is formatted like this:
|
||||
"
|
||||
" * Bit 0 not used
|
||||
" * Bit 1 hundreds flag for track address
|
||||
" * Bits 2-5 Tens digit for track address as BCD
|
||||
" * Bits 6-9 Units digit for track address as BCD
|
||||
" * Bits 10-13 Tens digit for segment address as BCD
|
||||
" * Bits 14-17 Units digit for segment address as BCD
|
||||
"
|
||||
" If the disk indicates an error the transfer is attempted 10 times
|
||||
" before dskio gives up and halts the program.
|
||||
dskio: 0
|
||||
cll; idiv; 80
|
||||
dac 2f
|
||||
lacq
|
||||
idiv; 10
|
||||
cll; idiv; 80 " compute binary track and segment addresses
|
||||
dac 2f " store binary segment address
|
||||
lacq " get binary track address back into AC
|
||||
idiv; 10 " compute BCD track address from binary track address
|
||||
dac 3f
|
||||
lls 22
|
||||
xor 3f
|
||||
als 8
|
||||
dac 3f
|
||||
lac 2f
|
||||
idiv; 10
|
||||
xor 3f " OR together Tens and Units digits of BCD track address
|
||||
als 8 " shift BCD track address to bit position in disk address
|
||||
dac 3f " store BCD track address
|
||||
lac 2f " load binary segment address
|
||||
idiv; 10 " compute BCD segment address from binary segment address
|
||||
dac 2f
|
||||
lls 22
|
||||
xor 2f
|
||||
xor 3f
|
||||
xor side
|
||||
dac 2f
|
||||
-10
|
||||
xor 2f " OR together Tens and Units digits of BCD segment address
|
||||
xor 3f " OR together track and segment addresses
|
||||
xor side " OR together side, track and segment addresses
|
||||
" to make the complete disk address
|
||||
dac 2f " store disk address
|
||||
-10 " do at most 10 transfer attempts
|
||||
dac 3f
|
||||
1:
|
||||
dscs
|
||||
-640
|
||||
dscs " clear disk status
|
||||
-640 " prepare transfer of 10 segments (10 blocks)
|
||||
dslw
|
||||
lac dskbufp
|
||||
lac dskbufp " load pointer to dskbuf into MAC
|
||||
dslm
|
||||
lac 2f
|
||||
lac 2f " load previously computed disk address
|
||||
dsld
|
||||
lac dskio i
|
||||
lac dskio i " load disk status register (one bit is the read/write flag)
|
||||
dsls
|
||||
dssf
|
||||
dssf " wait for ERROR/DONE
|
||||
jmp .-1
|
||||
dsrs
|
||||
sma
|
||||
jmp 1f
|
||||
isz 3f
|
||||
jmp 1b
|
||||
hlt
|
||||
dsrs " read disk status into AC, bit 0 indicates errors
|
||||
sma " if bit 0 of AC is set, AC is negative.
|
||||
" if AC is negative, continue below and do another
|
||||
" transfer attempt...
|
||||
jmp 1f " ...otherwise jump to the subroutine exit code below
|
||||
isz 3f " increment transfer attempts, and...
|
||||
jmp 1b " ...retry if more attempts remain
|
||||
hlt " when no more attempts remain, stop program due to
|
||||
" persistent disk error
|
||||
1:
|
||||
isz dskio
|
||||
jmp i dskio
|
||||
2: 0
|
||||
3: 0
|
||||
isz dskio " skip over argument passed to dskio
|
||||
jmp i dskio " return to caller
|
||||
|
||||
o200000: 0200000
|
||||
dskbufp: dskbuf
|
||||
2: 0 " local variable storing first binary segment address,
|
||||
" then disk address
|
||||
3: 0 " local variable storing first BCD track address,
|
||||
" then loop counter
|
||||
|
||||
side: .=.+1
|
||||
dskbuf: .=.+640
|
||||
o200000: 0200000 " bit corresponding to set Hundreds flag in disk address
|
||||
dskbufp: dskbuf " pointer to transfer buffer
|
||||
|
||||
side: .=.+1 " which side to access
|
||||
dskbuf: .=.+640 " transfer buffer for 10 blocks
|
||||
|
||||
Reference in New Issue
Block a user