program TO_SIMH_E11

! Read a "tape" in the format written by Van Snyder's autocoder, and
! write it in the E11 format Supnik's simh 1401 simulator
! (simh.trailing-edge.com) expects.  E11 is different from SIMH in that
! odd-length records are not padded.

! Autocoder writes records in ASCII.  Each record ends with a group
! mark.  The mapping from ASCII to BCD is given by the array
! ascii_to_bcd.

! simh wants records on "tapes" to be represented by a 32-bit little-
! endian count before and after the record.  The characters are
! represented in the low-order six bits of each byte, in BCD, with no
! parity.  A word mark is represented by a word mark character before
! the data character, just like on 1401 tapes.

! Output is done using Fortran unformatted write, which happens to
! produce what simh wants on many systems.

  use BCD_to_ASCII_m, only: ASCII_to_BCD
  use Machine, only: get_command_argument, hp, io_error

  integer :: I, IOSTAT, N
  character(len=32000) :: InBuf
  character(len=1023) :: Line ! From the command line

  call get_command_argument ( hp+1, line )

  open ( 10, file=trim(line), form='formatted', access='sequential', &
    & status='old', iostat=iostat )
  if ( iostat /= 0 ) then
    call io_error ( 'While opening input file', iostat, trim(line) )
    stop
  end if

  call get_command_argument ( hp+2, line )

  open ( 11, file=trim(line), form='unformatted', access='sequential', &
    & iostat=iostat, recl=32000 )
  if ( iostat /= 0 ) then
    call io_error ( 'While opening output file', iostat, trim(line) )
    stop
  end if

  do
    read ( 10, '(a)', end=9 ) inbuf
    n = len_trim(inbuf)
    do i = 1, n
      inbuf(i:i) = char(ascii_to_bcd(iachar(inbuf(i:i))))
    end do
    write ( 11 ) inbuf(:n)
  end do

  write ( 11 ) ! Maybe this writes a record with zero in the count field.
  ! simh appears to be happy without a 0x00000000 record to mark EOF, so
  ! long as the file ends.

9 close ( 10 )
  close ( 11 )

end program TO_SIMH_E11
