Apple2-IO-RPi/RaspberryPi/apple2driver/driver.go

130 lines
3.3 KiB
Go
Raw Normal View History

// Copyright Terence J. Boldt (c)2020-2023
// Use of this source code is governed by an MIT
// license that can be found in the LICENSE file.
2022-01-11 04:00:58 +00:00
// This file contains the main driver code for the Raspberry Pi side of
// the Apple2-IO-RPi hardware. Commands are sent from the Apple II and
// responses are sent back from the Raspberry Pi.
2022-01-11 04:00:58 +00:00
2021-05-30 11:18:39 +00:00
package main
import (
2021-10-06 12:34:18 +00:00
"flag"
2021-05-30 11:18:39 +00:00
"fmt"
"os"
2021-10-06 12:34:18 +00:00
"path/filepath"
"time"
2021-05-30 11:18:39 +00:00
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/a2io"
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/drive"
2021-05-30 11:18:39 +00:00
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/handlers"
2022-02-08 03:01:06 +00:00
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/info"
2022-12-31 15:56:57 +00:00
"github.com/tjboldt/ProDOS-Utilities/prodos"
2021-05-30 11:18:39 +00:00
)
const resetCommand = 0
2021-11-03 09:33:09 +00:00
const readBlockCommand = 1
const writeBlockCommand = 2
const getTimeCommand = 3
const changeDriveCommand = 4 // not currently used
2021-11-03 09:33:09 +00:00
const execCommand = 5
const loadFileCommand = 6
const saveFileCommand = 7 // not implemented yet
2021-11-03 09:33:09 +00:00
const menuCommand = 8
const shellCommand = 9
2021-05-30 11:18:39 +00:00
func main() {
drive1Name, drive2Name := getFlags()
drive1, drive2 := getDriveFiles(drive1Name, drive2Name)
2021-05-30 11:18:39 +00:00
2023-01-27 03:33:08 +00:00
driveImageDir, err := drive.GetDriveImageDirectory()
if err == nil {
os.Chdir(driveImageDir)
}
2022-02-08 03:01:06 +00:00
fmt.Printf("Starting Apple II RPi v%s...\n", info.Version)
2021-05-30 11:18:39 +00:00
2021-10-30 11:03:18 +00:00
comm := a2io.A2Gpio{}
handlers.SetCommunication(comm)
comm.Init()
2021-05-30 11:18:39 +00:00
// In case Apple II is waiting, send 0 byte to start
comm.WriteByte(0)
2021-05-30 11:18:39 +00:00
for {
2021-10-30 11:03:18 +00:00
command, err := comm.ReadByte()
2021-05-30 11:18:39 +00:00
if err == nil {
switch command {
case resetCommand:
handlers.ResetCommand()
2021-11-03 09:33:09 +00:00
case readBlockCommand:
handlers.ReadBlockCommand(drive1, drive2)
2021-11-03 09:33:09 +00:00
case writeBlockCommand:
2021-10-06 12:34:18 +00:00
handlers.WriteBlockCommand(drive1, drive2)
2021-11-03 09:33:09 +00:00
case getTimeCommand:
2021-05-30 11:18:39 +00:00
handlers.GetTimeCommand()
2021-11-03 09:33:09 +00:00
case execCommand:
handlers.ExecCommand(&drive1, &drive2)
2021-11-03 09:33:09 +00:00
case loadFileCommand:
2021-05-30 11:18:39 +00:00
handlers.LoadFileCommand()
2021-11-03 09:33:09 +00:00
case menuCommand:
2021-06-01 23:08:21 +00:00
handlers.MenuCommand()
case shellCommand:
handlers.ShellCommand()
2021-05-30 11:18:39 +00:00
}
// temporary workaround for busy wait loop heating up the RPi
} else {
2023-11-02 00:00:21 +00:00
time.Sleep(time.Millisecond * 200)
2021-05-30 11:18:39 +00:00
}
}
}
2021-10-06 12:34:18 +00:00
func getFlags() (string, string) {
2021-10-06 12:34:18 +00:00
var drive1Name string
var drive2Name string
execName, _ := os.Executable()
path := filepath.Dir(execName)
path = filepath.Join(path, "..")
path, _ = filepath.EvalSymlinks(path)
flag.StringVar(&drive1Name, "d1", "", "A ProDOS format drive image for drive 1")
2022-12-31 15:56:57 +00:00
flag.StringVar(&drive2Name, "d2", "", "A ProDOS format drive image for drive 2 and will be used for drive 1 if drive 1 empty")
2021-10-06 12:34:18 +00:00
flag.Parse()
return drive1Name, drive2Name
}
func getDriveFiles(drive1Name string, drive2Name string) (prodos.ReaderWriterAt, prodos.ReaderWriterAt) {
2022-12-31 16:39:10 +00:00
var drive1 prodos.ReaderWriterAt
var drive2 prodos.ReaderWriterAt
2021-10-06 12:34:18 +00:00
var err error
if len(drive1Name) > 0 {
fmt.Printf("Opening Drive 1 as: %s\n", drive1Name)
drive1, err = os.OpenFile(drive1Name, os.O_RDWR, 0755)
2022-12-31 15:56:57 +00:00
logAndExitOnErr(err)
} else {
directory, err := drive.GetDriveImageDirectory()
logAndExitOnErr(err)
drive1, err = drive.GenerateDriveFromDirectory("APPLE2.IO.RPI", directory)
2022-12-31 15:56:57 +00:00
logAndExitOnErr(err)
2021-10-06 12:34:18 +00:00
}
if len(drive2Name) > 0 {
2022-12-31 15:56:57 +00:00
fmt.Printf("Opening Drive 2 as: %s\n", drive2Name)
drive2, err = os.OpenFile(drive2Name, os.O_RDWR, 0755)
logAndExitOnErr(err)
2021-10-06 12:34:18 +00:00
}
2022-12-31 15:56:57 +00:00
return drive1, drive2
}
func logAndExitOnErr(err error) {
if err != nil {
fmt.Printf("ERROR: %s", err.Error())
2021-10-06 12:34:18 +00:00
os.Exit(1)
}
2022-12-31 15:56:57 +00:00
}