Fortran CHIP-8 interpreter

Thanks, great to hear that!

It would be super cool to use LFortran to compile a subset of Fortran to CHIP8. This could be used for a basic computer and compiler course for students.

Essentially the CHIP-8 virtual machine can support the following elements of Fortran

  • integer bitwise and arithmetic operations
  • loading and storing memory
  • control flow (if, select case)
  • goto
  • subroutines and functions (to a maximum call depth of 12 levels)

In addition there would be an intrinsic library of “hardware” routines for:

  • drawing sprites to the screen
  • clearing the screen
  • setting the sound and delay timers
  • checking for key presses
  • converting an integer to a binary-coded decimal

Returning to the jumping X and O program, a relaxed Fortran dialect targeting CHIP-8 could look something this:

program jumping_x_and_o

! X sprite
word :: xs(*) = [b'10001000', &
                 b'01010000', &
                 b'00100000', &
                 b'01010000', &
                 b'10001000']

! O sprite
word :: os(*) = [b'11111000', &
                 b'10001000', &
                 b'10001000', &
                 b'10001000', &
                 b'11111000']

! block sprite
word :: bs(*) = [b'11111100', &
                 b'11111100', &
                 b'11111100', &
                 b'11111100', &
                 b'11111100', &
                 b'11111100']

word :: i, j

! Draw the square block
call draw(48,4,bs)

do
    call jump(xs) ! X jumping around
    call jump(os) ! O jumping around
end do

contains

    ! Randomly draw a pattern, until it overlaps with the block
    subroutine jump(pattern)
        word, intent(in) :: pattern(:)
        logical :: overlaps
        word :: x, y, k
        x = 30
        y = 13
        do
            call draw(x,y,pattern,overlaps)
            call delay(put=12)  ! wait for 12/60 of a second
            do 
                call delay(get=k)
                if (k == 0) exit
            end do
            if (overlaps) then
                call draw(i,j,pattern)  ! drawing the same pattern to erase it
                return
            else
            call draw(i,j,pattern) ! drawing the same pattern to erase it
            
            ! generate new coordinates
            x = rand(mask=z'3F') ! 6-bit random number [0, 63]
            y = rand(mask=z'1F') ! 5-bit random number [0, 31]
        end do

    end subroutine

end program

Here is how the manually-assembled program looks like (running in fc8),

2 Likes