* I/O Opcode 2 - READ
*
* This routine will store the next record of the specified file
* in the user's buffer provided
*   1. The file is open
*   2. We have not reached end of file yet
*
* Once it determines that the file is open and not at end of file,
* it must determine if the contents of the buffer is valid.  If not,
* it will read the next sector from the disk.  If convient, it will
* read 2 sectors and use all 512 bytes of the buffer.
*
* Date: April 22, 1995
* Author: David Nieters
*
* Well, it's less than one week till Lima and I'm still writing
* new code.  Let's home I get some of this working in time so it
* looks like it's 90% done like Don has been telling everybody.
*
* Modification History
*
* November 20, 1995 - Fixed directory file access to return the
*      exact length for each filename instead of padded with
*      spaces.  Also, returns a null string when reached the
*      end instead of 10 spaces.  Will add subdirectory listings
*      later.
*

READ0
       ANDI R12,>FF00
       AI   R12,24

       LDCR @B02,4            Select RAM bank 2
       BLWP @IFO              Check to make sure file is open
       JEQ  READ2

READ1  BL   @DSRERR
       DATA >0700             File error

READ2  CB   @56(R5),@B02      See if file has been opened for reading
       JEQ  READ3
       CB   @56(R5),@ZERO     or update access
       JEQ  READ3
       CB   @56(R5),@B05      Or directory access
       JEQ  READ3A

       BL   @DSRERR
       DATA >0200             Bad open attribute?

READ3A B    @READ60           Handle directory read

READ4  B    @READ50           Handle the relative read

READ3  LDCR @ZERO,4           Check for sequential access
       MOVB @PABBUF+1,R1      Get flags
       ANDI R1,>0100
       JNE  READ4

       LDCR @B02,4


* We know that the file is open and we are reading sequentially.
* Now check to see if we're at end of file.
*
       MOV  @4(R5),R1         Get FDR address
       MOV  @62(R5),R2        Get sector/record number
       MOV  @54(R5),R3        Get the pointer within the buffer

       LDCR @2(R5),4          Select BANK with FDR

* If the file is empty, we must be reading
* past the end of file.

       C    @ZERO,@18(R1)
       JEQ  READ5

       SWPB R2
       C    R2,@18(R1)        See if we're in the last sector written
       JNE  READ7

* Here we check for fixed or variable length records.  If fixed,
* the value in R2 was the last record written and we know we're
* at the end of the file.  It the records are variable length, we
* check to see if we're pointing to an end of sector marker.
*

       MOVB @12(R1),R0        Check for fixed or variable length
       ANDI R0,>8000
       JNE  READ6

READ5
       LDCR @B02,4           Close file if attempting to
       CLR  @4(R5)           read past end of file

       BL   @DSRERR
       DATA >0500             Attempt to read past end of file

READ6  LDCR @B02,4            Select RAM bank 2
       LDCR @3(R5),4          Select bank with buffer
       CB   *R3,@B255         Are we at the end of the sector?
       JEQ  READ5

READ7  LDCR @B02,4            Select RAM bank 2
       C    @50(R5),@ZERO     Have we read the 1st sector yet?
       JNE  READ20

* We have to read in the 1st sector of the file
*
       LDCR @2(R5),4          Select bank with the FDR in it
       MOV  @40(R1),R7        Get 1st AU allocate in file
       LDCR @B02,4            Select RAM bank 2
       MOV  R7,@50(R5)        Save current AU
       CLR  @52(R5)           We're reading 1st sector if this AU
       CLR  @58(R5)           Set buffer size to 256 for now
       MOV  @6(R5),@54(R5)    Set pointer to beginning of buffer

       LDCR @B04,4            Select RAM bank 4
       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       MOV  @SAUTBL(R3),R3    Get the Sectors/AU for this disk
       MPY  R3,R7
       LI   R1,SECBUF
       SRL  R8,1
       JNC  READ8
       AI   R1,>100
READ8  SRL  R7,1
       JNC  READ9
       AI   R8,>8000
READ9  LDCR @ZERO,4
       BLWP @BANKIT
       DATA SCSIRD
       JEQ  READ10
       BL   @DSRERR
       DATA >0600             Device error

* Now that we have read the block from the disk, see if we
* can use all 512 bytes, or only 256
*
READ10 LDCR @B02,4            Select RAM bank 2
       CI   R3,2              Make sure Sectors/AU > 1
       JL   READ11
       CI   R1,SECBUF         Make sure we start at beginning
       JNE  READ11

       SETO @58(R5)           We're using all 512 bytes!
READ11
       MOV  @6(R5),R2         Get buffer address
       MOVB @3(R5),R3         Get buffer bank number
READ12 LDCR @ZERO,4           Select RAM bank 0
       MOV  *R1+,R0
       LDCR R3,4
       MOV  R0,*R2+
       CI   R1,SECBUF+512
       JNE  READ12

       LDCR @B02,4            Select RAM bank 2
       MOV  @4(R5),R1         Get FDR address
       LDCR @2(R5),4
       MOVB @12(R1),R0        Set sector # to 1 if a variable file
       ANDI R0,>8000
       JEQ  READ13
       LDCR @B02,4
       INC  @62(R5)
READ13
       B    @READ40


*****************************************************
*
*  Here we want to check to see if the buffer is
*  valid.  If it is not, then we must read the
*  next sector into the buffer.
*
*****************************************************

READ20
       LDCR @B02,4            Select RAM bank 2
       MOV  @4(R5),R1         Get pointer FDR

       LDCR @2(R5),4
       MOVB @12(R1),R2        Get file flags
       LDCR @B02,4            Select RAM bank 2
       ANDI R2,>8000          See if we have fixed length records
       JNE  READ2C
       B    @READ39
READ2C
       MOV  @54(R5),R1        Get pointer in buffer
       LDCR @3(R5),4          Select bank with buffer in it
       CB   *R1,@B255         If it starts with >FF, it's end of sector
       JEQ  READ2B
       B    @READ40
READ2B
       LDCR @B02,4            Select RAM bank 2
       INC  @62(R5)           Increment sector number

* We're at the end of the sector.  If we have a 512 byte buffer and
* we're still in the first 256 bytes, just go to second half of
* buffer.  Otherwise, read the next sector from the disk.
*
READ21
       LDCR @B02,4            Select RAM bank 2
       C    @58(R5),@ZERO     See if we have a 512 byte buffer
       JEQ  RD21A
       MOV  @54(R5),R1        See if we're in 1st half of buffer
       ANDI R1,>0100
       JNE  RD21A

       MOV  @54(R5),R1        OK, just go to next half
       ANDI R1,>FF00
       AI   R1,>100
       MOV  R1,@54(R5)        Save new pointer
       INC  @52(R5)           Increment sector counter
       LDCR @B04,4            Select RAM bank 4
       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       MOV  @SAUTBL(R3),R3
       LDCR @B02,4            Select RAM bank 2
       C    R3,@52(R5)        See if we transcended an AU boundry
       JNE  RD21B
       CLR  @52(R5)           Clear sector within AU
       INC  @50(R5)           increment AU number
RD21B  B    @READ40


* Well, it looks like we're going to have to read the
* next sector from disk
*
RD21A
       LDCR @B04,4            Select RAM bank 4
       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       MOV  @SAUTBL(R3),R3
       LDCR @B02,4            Select RAM bank 2
       MOV  @50(R5),R7        Get current AU
       INC  @52(R5)           go to next sector within AU
       C    @52(R5),R3        See if we need to go to next AU
       JNE  READ25

* If this was the last AU in the cluster, we must go
* to the next cluster.  Otherwise, just increment
* the current AU.

       CLR  @52(R5)
       MOV  @4(R5),R1         Get FDR address
       LDCR @2(R5),4          Select bank with FDR
       LI   R10,54            There are 54 total clusters/FDR
       AI   R1,42
READ22 MOV  *R1+,R2
       JEQ  READ23
       C    R2,R7
       JEQ  READ24
       INCT R1
       DEC  R10
       JNE  READ22
READ23 INC  R7
       JMP  READ25

READ24 MOV  *R1,R7
READ25
       LDCR @B02,4            Select RAM bank 2
       MOV  R7,@50(R5)        Save current AU
       MOV  @6(R5),@54(R5)    Reset pointer in buffer
       CLR  @58(R5)           Set buffer size to 256 byte (for now)
       MPY  R3,R7
       A    @52(R5),R8        Add in sector within AU
       JNC  READ26
       INC  R7
READ26 LI   R1,SECBUF
       SRL  R8,1
       JNC  READ27
       AI   R1,>100
READ27 SRL  R7,1
       JNC  READ28
       AI   R8,>8000
READ28 LDCR @ZERO,4           Select RAM bank 0
       BLWP @BANKIT           Read the sector from disk
       DATA SCSIRD
       JEQ  READ29
       BL   @DSRERR
       DATA >0600             Device error

READ29
       LDCR @B02,4
       CI   R3,2              See if we can use a 512 byte buffer
       JL   RD29A
       CI   R1,SECBUF
       JNE  RD29A
       SETO @58(R5)
RD29A
       MOV  @6(R5),R2         Get buffer address
       MOVB @3(R5),R4

READ30 LDCR @ZERO,4           Select RAM bank 0
       MOV  *R1+,R10
       LDCR R4,4
       MOV  R10,*R2+
       CI   R1,SECBUF+512
       JNE  READ30
       JMP  READ40

R21HLP B    @RD21A            Help the JH instruction below
R22HLP B    @READ21

* If we are handling fixed length records, we handle the
* buffer validity a little differently.  Here goes

* If the pointer is exactly >200 greater than the base,
* we know we have to read the next sector.  If it is
* exactly >100 greater than the base and the buffer size
* is 256 bytes, we have to read the next sector.

READ39 LDCR @B02,4            Select RAM bank 2
       MOV  @54(R5),R1        Get pointer within buffer
       S    @6(R5),R1         Subtract the base address
       CI   R1,>200
       JEQ  R21HLP
       CI   R1,>100
       JNE  RD39A
       C    @58(R5),@ZERO     See if buffer size is 256
       JEQ  R21HLP            If so, read next sector
       INC  @52(R5)

RD39A  MOV  @54(R5),R1        Get pointer within buffer

       ANDI R1,>00FF
       MOV  @4(R5),R2         Get FDR address
       LDCR @2(R5),4          Select bank with FDR
       MOVB @17(R2),R4        Get record length
       SRL  R4,8
       A    R4,R1             See if we can add record length
       CI   R1,>0100          Without going over
       JH   R22HLP            If not, read next sector


* We know the buffer is good.  All we have to do now is
* transfer the record to the user's buffer.

READ40

* If we have a fixed length record, read that many bytes.
* If we have a variable length record, read the length
* byte first and read that many bytes.
*
       LDCR @B02,4            Select RAM bank 2
       MOV  @54(R5),R2        Get buffer pointer
       MOVB @3(R5),R3         Get buffer bank
       MOV  @4(R5),R1         Get Address of FDR
       LDCR @2(R5),4          Select bank where FDR is
       MOVB @12(R1),R0
       ANDI R0,>8000          Mask out fixed/variable bit
       JEQ  READ44

* Well, we have a variable length record.  Read the record
* size byte and store that many characters in the user's
* buffer.
*
       LDCR R3,4
       MOVB *R2+,R0
READ41
       LDCR @ZERO,4      Store record size in user's PAB
       MOV  @PABADR,R1
       ORI  R1,>4000
       AI   R1,5
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA
       NOP
       MOVB R0,@VDPWD

       JEQ  READ43            Skip copy if a null record
       SRL  R0,8

* Set the VDP write address to the user's buffer
*
       MOV  @PABBUF+2,R1
       ORI  R1,>4000
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA

       LDCR R3,4

READ42 MOVB *R2+,@VDPWD
       DEC  R0
       JNE  READ42

READ43 LDCR @B02,4
       MOV  R2,@54(R5)
       LDCR @ZERO,4
       B    @DSRRT

READ44 MOVB @17(R1),R0        Get fixed record length
       LDCR @B02,4            Select RAM bank 2
       INC  @62(R5)           Increment last record # read.
       JMP  READ41


READ49 BL   @DSRERR
       DATA >0500            Attempt to read past end of file
**
*
* Here is where we handle relative access reads.  The trick involves
* several divisions to compute where the record fits in the file.
*
**

READ50
       BL   @POSIT
       LDCR @ZERO,4
       MOV  @PABADR,R1       Increment record # in caller's PAB
       ORI  R1,>4000
       AI   R1,6
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA
       MOV  @PABBUF+6,R1
       INC  R1
       MOVB R1,@VDPWD
       SWPB R1
       MOVB R1,@VDPWD

       B    @READ40          Transfer record to user and return

**
*
* Here is where we handle directory reads.  Record 0 is the
* directory itself.  Records 1-127 are files.
*
**

READ60

* Store the # of characters written in the caller's PAB
*

       LDCR @ZERO,4           Select RAM bank 0
       MOV  @PABADR,R1
       ORI  R1,>4000
       AI   R1,5
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA
       LI   R0,38*256          Store record length
       MOVB R0,@VDPWD

* Set the VDP write address to the user's buffer
*
       MOV  @PABBUF+2,R1
       ORI  R1,>4000
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA

* See which record we are reading
*
       MOVB @PABBUF+1,R1
       ANDI R1,>0100
       JEQ  READ61

       MOV  @PABADR,R1       Increment record # in caller's PAB
       ORI  R1,>4000
       AI   R1,6
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA
       MOV  @PABBUF+6,R1
       INC  R1
       MOVB R1,@VDPWD
       SWPB R1
       MOVB R1,@VDPWD

       MOV  @PABBUF+2,R1
       ORI  R1,>4000
       SWPB R1
       MOVB R1,@VDPWA
       SWPB R1
       MOVB R1,@VDPWA

       MOV  @PABBUF+6,R1
       JMP  READ62

READ61 LDCR @B02,4           Sequential read, get from cache
       MOV  @62(R5),R1
       INC  @62(R5)
READ62
       CI   R1,0             See if reading directory
       JNE  READ70

* Copy the directory name to the user's buffer
*
       LDCR @B02,4
       MOV  @4(R5),R4
       LDCR @2(R5),4
       LI   R0,10
       AI   R4,9
READ63 CB   *R4,@SPACE
       JNE  RD63A
       DEC  R4
       DEC  R0
       JNE  READ63

RD63A  SWPB R0
       MOVB R0,@VDPWD        Set name length
       JEQ  RD63C
       SWPB R0
       S    R0,R4
       INC  R4
RD63B  MOVB *R4+,@VDPWD
       DEC  R0
       JNE  RD63B
RD63C
* Now get the rest of the info
*   R8 = Record type (Always zero)
*   R9 = Total # of AU's on the disk
*   R10 = # of free AU's on the disk

* Now get the number of free AU's on the disk.  We read the
* entire bitmap from disk and count the number of zeros.
* There's got to be a better way to do this, and when I
* think of it, I'll change this code.
*
       CLR  R7
       CLR  R8
       LI   R4,SECBUF+>100   The bitmap is right after VIB
       CLR  R10              R10 Keeps track of # of free AU's
       LDCR @ZERO,4

READ64 BLWP @BANKIT
       DATA SCSIRD
       JEQ  READ65

       AI   R8,16            If error, read copy
       BLWP @BANKIT
       DATA SCSIRD
       AI   R8,-16
READ65
* If the value is 0, we can just add 16 to the number of
* free AU's.  Otherwise, we have to count the bits in R1.

* If we just read the VIB, get the disk size here

       CI   R8,0
       JNE  RD65A
       MOV  @SECBUF+10,R5    Save in R5 for now
       MOV  @SECBUF+16,R2    Get sectors/AU
       SRL  R2,12
       INC  R2
RD65A
       MOV  *R4+,R1
       JNE  READ68

       AI   R10,16
READ66 CI   R4,SECBUF+>200
       JNE  RD65A

READ67 LI   R4,SECBUF
       INC  R8
       CI   R8,16
       JNE  READ64

* Now report the disk size and free space.  We use
* the new 20 bit integer routine for this!

       MOV  R2,R9            Store Sectors/AU in another REG
       CLR  R1               File type = 0
       CLR  R2
       BL   @I20TOR

       MOV  R5,R1            Disk size in AU's
       MPY  R9,R1
       BL   @I20TOR

       MOV  R10,R1
       MPY  R9,R1
       BL   @I20TOR

       LDCR @ZERO,4
       B    @DSRRT

READ68 CI   R1,-1
       JEQ  READ66
       LI   R0,16
READ69 SLA  R1,1
       JOC  RD69A
       INC  R10
RD69A  DEC  R0
       JNE  READ69
       JMP  READ66


* READ80  We're past all the filenames, return
* information on subdirectories now.
*
READ80 S    R3,R1            Subtract # of files
       MOVB @23(R2),R3       Get # of subdirectories
       SRL  R3,8
       C    R1,R3
       JH   READ81
       B    @READ91

READ81 CLR  @VDPWD           String length
       LI   R1,3             Return 3 RAXID 100 numbers
       LI   R2,>0808
READ82 MOV  R2,@VDPWD
       LI   R3,8
READ83 CLR  @VDPWD
       DEC  R3
       JNE  READ83
       DEC  R1
       JNE  READ82
       LDCR @ZERO,4
       B    @DSRRT
**
*
* Here we are retrieving information about a file.  If the
* record number is out of range, return all zeros.
*
**

READ70 LDCR @B02,4
       MOV  @4(R5),R2        Get DDR address
       LDCR @2(R5),4

       MOVB @22(R2),R3       Get # of files in directory
       SRL  R3,8
       C    R1,R3
       JH   READ80

* See if the FDIR has been loaded into the buffer.  If it
* hasn't, read it in now

       MOV  @24(R2),R7       Get AU of FDIR just in case
       LDCR @B02,4
       C    @58(R5),@ZERO
       JNE  READ75

       SETO @58(R5)          Set flag
       MOV  R6,R3            Read FDIR
       SRL  R3,8
       SLA  R3,1
       LDCR @B04,4
       MPY  @SAUTBL(R3),R7
       LI   R2,SECBUF
       SRL  R8,1
       JNC  READ71
       AI   R2,>100
READ71 SRL  R7,1
       JNC  READ72
       AI   R8,>8000
READ72 LDCR @ZERO,4
       BLWP @BANKIT
       DATA SCSIRD

       JEQ  READ73
       BL   @DSRERR
       DATA >0600

READ73 LDCR @B02,4
       MOV  @6(R5),R3        Get buffer address
       MOVB @3(R5),R4        Get buffer Bank
       LI   R0,256

READ74 LDCR @ZERO,4
       MOV  *R2+,R7
       LDCR R4,4
       MOV  R7,*R3+
       DECT R0
       JNE  READ74

READ75
       DEC  R1
       SLA  R1,1
       LDCR @B02,4
       MOV  @6(R5),R4        Get address of buffer
       LDCR @3(R5),4

       A    R1,R4
       MOV  *R4,R7           Get AU of FDR

       LI   R1,SECBUF
       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       LDCR @B04,4
       MPY  @SAUTBL(R3),R7
       SRL  R8,1
       JNC  READ76
       AI   R1,>100
READ76 SRL  R7,1
       JNC  READ77
       AI   R8,>8000
READ77 LDCR @ZERO,4
       BLWP @BANKIT
       DATA SCSIRD
       JEQ  READ78
       BL   @DSRERR
       DATA >0600

READ78 LI   R0,10            Copy filename to user's buffer
       MOV  R1,R9
       AI   R1,9
RD78A  CB   *R1,@SPACE
       JNE  RD78B
       DEC  R1
       DEC  R0
       JNE  RD78A
RD78B  SWPB R0
       MOVB R0,@VDPWD        File length shouldn't be zero
       JEQ  RD79Z            but just in case...
       SWPB R0
       MOV  R9,R1
READ79 MOVB *R1+,@VDPWD
       DEC  R0
       JNE  READ79

RD79Z  MOV  R9,R1

       MOV  @14(R1),R9       # of sectors allocated
       MOVB @17(R1),R10      # of bytes/record
       SRL  R10,8

* Now see what type of file it is.  We return the following
*
* 1: Display/Fixed
* 2: Display/Variable
* 3: Internal/Fixed
* 4: Internal/Variable
* 5: Program file
*
* If the file is protected, these numbers are inverted

       LI   R8,5
       MOVB @12(R1),R0
       ANDI R0,>0100     Check for program file
       JNE  RD79B
       LI   R8,1         Assume Display/Fixed
       MOVB @12(R1),R0
       ANDI R0,>8000     Check for variable records
       JEQ  RD79A
       INC  R8
RD79A  MOVB @12(R1),R0
       ANDI R0,>0200     Check for internal
       JEQ  RD79B
       INCT R8
RD79B

* Now check to see if the file is protected
       MOV  @12(R1),R0
       COC  @PROBIT,R0
       JNE  RD79C
       NEG  R8
RD79C

* Now we just have to convert some 16 bit integers to radix 100
* format and store in the user's buffer and go home.
*
READ90
       MOV  R8,R2
       BL   @ITORAD
       MOV  R9,R2
       BL   @ITORAD
       MOV  R10,R2
       BL   @ITORAD

       LDCR @ZERO,4
       B    @DSRRT

**
*
* READ91 - Here we return information on a subdirectory
*
**

READ91 DEC  R1
       SLA  R1,1
       LDCR @B02,4
       MOV  @4(R5),R4        Get address of DDR
       LDCR @2(R5),4

       A    R1,R4
       MOV  @28(R4),R7       Get AU of subdirectory DDR

       LI   R1,SECBUF
       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       LDCR @B04,4
       MPY  @SAUTBL(R3),R7
       SRL  R8,1
       JNC  READ92
       AI   R1,>100
READ92 SRL  R7,1
       JNC  READ93
       AI   R8,>8000
READ93 LDCR @ZERO,4
       BLWP @BANKIT
       DATA SCSIRD
       JEQ  READ94
       BL   @DSRERR
       DATA >0600

READ94 LI   R0,10            See how long the name is
       MOV  R1,R9
       AI   R1,9
READ95 CB   *R1,@SPACE
       JNE  READ96
       DEC  R1
       DEC  R0
       JNE  READ95
READ96 SWPB R0
       MOVB R0,@VDPWD        Store directory name length
       JEQ  READ98
       SWPB R0
       MOV  R9,R1
READ97 MOVB *R1+,@VDPWD
       DEC  R0
       JNE  READ97

READ98 MOV  R9,R1
       LI   R8,6             File type = 6 for directory
       LI   R9,2             Size = 2 for now
       CLR  R10              Record size = 0?
       JMP  READ90

************************************************************
*                                                          *
*  PROCEDURE ITORAD                                        *
*                                                          *
*  This procedure will take an unsigned integer stored in  *
*  R1 and convert it to RADIX 100 and store the result in  *
*  the file buffer.                                        *
*                                                          *
************************************************************

ITORAD

       MOVB @B08,@VDPWD        Store field length (8 bytes)

       CI   R2,0
       JEQ  ITOR00
       CI   R2,100
       JL   ITOR1
       CI   R2,10000
       JL   ITOR3

* If it is greater than 65530, assume it's negative
       CI   R2,65530
       JL   ITOR50
*      NEG  R2
*      ORI  R2,>4000
*      NEG  R2
       ANDI R2,>BFFF
       MOVB R2,@VDPWD
       SWPB R2
       MOVB R2,@VDPWD
       JMP  ITOR1A

* Here we are converting a number in the range of 10000-65535
*

ITOR50
       CLR  R1
ITOR5A MOVB @HEX42,@VDPWD
       LI   R0,4
ITOR5B LI   R3,10000
       DIV  R3,R1
       SWPB R1
       MOVB R1,@VDPWD
       CLR  R1
       LI   R3,100
       DIV  R3,R1
       SWPB R1
       MOVB R1,@VDPWD
       SWPB R2
       MOVB R2,@VDPWD
       JMP  ITOR2

* Here we are doing the number 0
*
ITOR00 LI   R0,8
       JMP  ITOR2

* Here are are converting a number in the range of 0-99
*
ITOR1
       MOVB @HEX40,@VDPWD
       SWPB R2
       MOVB R2,@VDPWD
ITOR1A LI   R0,6
ITOR2  CLR  @VDPWD
       DEC  R0
       JNE  ITOR2
       RT

* Here we are converting a number in the range of 100-9999
*
ITOR3
       MOVB @HEX41,@VDPWD
       LI   R0,5
ITOR3A
       CLR  R1
       LI   R3,100
       DIV  R3,R1
       SWPB R1
       MOVB R1,@VDPWD
       SWPB R2
       MOVB R2,@VDPWD
       JMP  ITOR2


************************************************************
*                                                          *
*  I20TOR - Convert 20 bit integer to RADIX 100            *
*                                                          *
*  This procedure will convert a 20 bit integer to RADIX   *
*  100 format.  The maximum size of a 20 bit integer is    *
*  1,048,575.                                              *
*                                                          *
*  Input:  R1, R2 = 20 bit integer (high 12 bits of R1     *
*                   must be zero).                         *
*                                                          *
*  Uses: R0, R1, R2, R3                                    *
*                                                          *
************************************************************

I20TOR
       MOVB @B08,@VDPWD        Store field length (8 bytes)

       CI   R1,0
       JNE  I20TO2
       CI   R2,0
       JEQ  ITOR00           Number is zero
       CI   R2,100
       JL   ITOR1            Number is 1-99
       CI   R2,10000
       JL   ITOR3            Number is 100-9999
       JMP  ITOR5A           Number is 10000-65535

I20TO2

* OK.  The number is greater than 65535.  See if it's
* less than 1,000,000
*
       CI   R1,15
       JL   ITOR5A           Number is < 983,040
       CI   R2,16960
       JL   ITOR5A

**
*
* Here we handle numbers 1,000,000-1,048,575
*
**

I20TO5 MOVB @HEX43,@VDPWD
       LI   R0,3
       MOVB @B01,@VDPWD
       CLR  R1
       AI   R2,-16960
       JMP  ITOR5B

HEX40  BYTE >40
HEX41  BYTE >41
HEX42  BYTE >42
HEX43  BYTE >43
