Fix Codacy lint/security warnings

This commit is contained in:
Terence Boldt 2021-11-03 05:33:09 -04:00 committed by GitHub
parent c864b5e28d
commit b37855dbfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 196 additions and 156 deletions

View File

@ -20,14 +20,14 @@ Steps to reproduce the behavior:
A clear and concise description of what you expected to happen. A clear and concise description of what you expected to happen.
**Hardware (please complete the following information):** **Hardware (please complete the following information):**
- Host computer [e.g. ][, ][+, //e, IIgs, etc.] - Host computer (e.g. II, II+, //e, IIgs, etc.)
- Additional cards [e.g. Disk ][, 80 column, TranswarpGS, etc.] - Additional cards (e.g. Disk II, 80 column, TranswarpGS, etc.)
- Apple2-IO-RPi Version [e.g. prototype 4, prototype 5] - Apple2-IO-RPi Version (e.g. prototype 4, prototype 5)
- Origin [e.g. Self-made, purchased without RPi, purchased with RPi] - Origin (e.g. Self-made, purchased without RPi, purchased with RPi)
- When was firmware last updated - When was firmware last updated
**Software (please complete the following information):** **Software (please complete the following information):**
- When was repo on the card last updated build performed - When was repo on the card last updated build performed
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View File

@ -1,14 +1,14 @@
--- ---
name: Feature request name: Enhancement request
about: Suggest an idea for this project about: Suggest an improvement for this project
title: 'Feature: ' title: 'Enhancement: '
labels: '' labels: ''
assignees: '' assignees: ''
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] A clear and concise description of what the problem is.
**Describe the solution you'd like** **Describe the solution you'd like**
A clear and concise description of what you want to happen. A clear and concise description of what you want to happen.

View File

@ -43,7 +43,7 @@ cat \
DriveFirmware.bin CommandFirmware.bin FileAccessFirmware.bin MenuFirmware.bin \ DriveFirmware.bin CommandFirmware.bin FileAccessFirmware.bin MenuFirmware.bin \
> AT28C64B.bin > AT28C64B.bin
rm *.o rm ./*.o
rm DriveFirmware.bin rm DriveFirmware.bin
rm MenuFirmware.bin rm MenuFirmware.bin
rm CommandFirmware.bin rm CommandFirmware.bin

View File

@ -115,7 +115,7 @@ the community.
This Code of Conduct is adapted from the [Contributor Covenant][homepage], This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).
Community Impact Guidelines were inspired by [Mozilla's code of conduct Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity). enforcement ladder](https://github.com/mozilla/diversity).
@ -123,5 +123,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org [homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are available at
https://www.contributor-covenant.org/translations. [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations).

View File

@ -2,6 +2,6 @@
Thanks for looking into how to contribute. You can help the following ways: Thanks for looking into how to contribute. You can help the following ways:
- Submit an Issue (Bug or Feature) - Submit an Issue (Bug or Feature)
- Send email feedback - Send email feedback
- Contribute code via your fork and a pull request - Contribute code via your fork and a pull request

View File

@ -32,8 +32,8 @@ So far, this is a project and not a finished product. The current prototype is o
1. Have PCBs made from the gerber and drill files in the Hardware folder or email me for a blank or fully assembled board 1. Have PCBs made from the gerber and drill files in the Hardware folder or email me for a blank or fully assembled board
2. Solder chips, header and capacitors in place 2. Solder chips, header and capacitors in place
3. Attach Raspberry Pi Zero W facing outward from the card 3. Attach Raspberry Pi Zero W facing outward from the card
4. Install Raspberry Pi OS on microSD card https://www.raspberrypi.org/software/ 4. Install [Raspberry Pi OS](https://www.raspberrypi.org/software/) on microSD card
5. Configure wifi in boot/wpa_supplicant.conf https://howtoraspberrypi.com/how-to-raspberry-pi-headless-setup/ 5. Configure wifi in [boot/wpa_supplicant.conf](https://howtoraspberrypi.com/how-to-raspberry-pi-headless-setup/)
6. Add empty ssh file boot (for ssh access over wifi) 6. Add empty ssh file boot (for ssh access over wifi)
7. Put microSD card in the RPi 7. Put microSD card in the RPi
8. Install the expansion card into the Apple II 8. Install the expansion card into the Apple II
@ -56,10 +56,10 @@ So far, this is a project and not a finished product. The current prototype is o
17. `git clone https://github.com/tjboldt/Apple2-IO-RPi.git` 17. `git clone https://github.com/tjboldt/Apple2-IO-RPi.git`
18. `cd Apple2-IO-RPi/RaspberryPi/apple2driver` 18. `cd Apple2-IO-RPi/RaspberryPi/apple2driver`
19. `go get` 19. `go get`
21. `go build` 20. `go build`
22. `./apple2driver` 21. `./apple2driver`
23. Optional to step above, `./apple2driver -d1 YOUR_DRIVE.hdv` (Apple2-IO-RPi.hdv is automatically selected as drive 2), or `./apple2driver -d1 YOUR_DRIVE.hdv -d2 YOUR_SECOND_DRIVE.hdv` 22. Optional to step above, `./apple2driver -d1 YOUR_DRIVE.hdv` (Apple2-IO-RPi.hdv is automatically selected as drive 2), or `./apple2driver -d1 YOUR_DRIVE.hdv -d2 YOUR_SECOND_DRIVE.hdv`
24. Setup the Driver as a service or to autostart via cronjob (`crontab -e` then add the line `@reboot /home/pi/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver -d1 YOUR_DRIVE.hdv -d2 /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.hdv > /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.log`) 23. Setup the Driver as a service or to autostart via cronjob (`crontab -e` then add the line `@reboot /home/pi/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver -d1 YOUR_DRIVE.hdv -d2 /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.hdv > /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.log`)
## Setup if you received a complete board from me ## Setup if you received a complete board from me
1. Put in any slot (slot 7 preferred as it is the first to boot) 1. Put in any slot (slot 7 preferred as it is the first to boot)

View File

@ -5,8 +5,10 @@
// This file defines the interface for communicating with the Apple II via // This file defines the interface for communicating with the Apple II via
// the Raspberry Pi GPIO ports but can also be mocked out for tests or // the Raspberry Pi GPIO ports but can also be mocked out for tests or
// passed input to the user for interactive testing // passed input to the user for interactive testing
package a2io package a2io
// A2Io provides an interface to send and receive data to the Apple II
type A2Io interface { type A2Io interface {
Init() Init()
WriteByte(data byte) error WriteByte(data byte) error
@ -17,7 +19,3 @@ type A2Io interface {
ReadString() (string, error) ReadString() (string, error)
ReadBlock(buffer []byte) error ReadBlock(buffer []byte) error
} }
type A2Comm struct {
A2Io A2Io
}

View File

@ -4,6 +4,7 @@
// This file is used for communicating with the Apple II data bus via the // This file is used for communicating with the Apple II data bus via the
// GPIO ports on the Raspberry Pi // GPIO ports on the Raspberry Pi
package a2io package a2io
import ( import (
@ -19,80 +20,83 @@ import (
var edgeTimeout time.Duration var edgeTimeout time.Duration
var out_write gpio.PinIO var outWrite gpio.PinIO
var out_read gpio.PinIO var outRead gpio.PinIO
var out_reserved2 gpio.PinIO var outReserved2 gpio.PinIO
var out_reserved1 gpio.PinIO var outReserved1 gpio.PinIO
var out_bit7 gpio.PinIO var outBit7 gpio.PinIO
var out_bit6 gpio.PinIO var outBit6 gpio.PinIO
var out_bit5 gpio.PinIO var outBit5 gpio.PinIO
var out_bit4 gpio.PinIO var outBit4 gpio.PinIO
var out_bit3 gpio.PinIO var outBit3 gpio.PinIO
var out_bit2 gpio.PinIO var outBit2 gpio.PinIO
var out_bit1 gpio.PinIO var outBit1 gpio.PinIO
var out_bit0 gpio.PinIO var outBit0 gpio.PinIO
var in_write gpio.PinIO var inWrite gpio.PinIO
var in_read gpio.PinIO var inRead gpio.PinIO
var in_reserved2 gpio.PinIO var inReserved2 gpio.PinIO
var in_reserved1 gpio.PinIO var inReserved1 gpio.PinIO
var in_bit7 gpio.PinIO var inBit7 gpio.PinIO
var in_bit6 gpio.PinIO var inBit6 gpio.PinIO
var in_bit5 gpio.PinIO var inBit5 gpio.PinIO
var in_bit4 gpio.PinIO var inBit4 gpio.PinIO
var in_bit3 gpio.PinIO var inBit3 gpio.PinIO
var in_bit2 gpio.PinIO var inBit2 gpio.PinIO
var in_bit1 gpio.PinIO var inBit1 gpio.PinIO
var in_bit0 gpio.PinIO var inBit0 gpio.PinIO
// A2Gpio is the live implementation of A2Io interface
type A2Gpio struct { type A2Gpio struct {
} }
// Init initializes the GPIO ports on the Raspberry Pi
func (a2 A2Gpio) Init() { func (a2 A2Gpio) Init() {
host.Init() host.Init()
out_write = gpioreg.ByName("GPIO24") outWrite = gpioreg.ByName("GPIO24")
out_read = gpioreg.ByName("GPIO25") outRead = gpioreg.ByName("GPIO25")
out_reserved2 = gpioreg.ByName("GPIO7") //note GPIO7 and CPIO8 require extra effort to use outReserved2 = gpioreg.ByName("GPIO7") //note GPIO7 and CPIO8 require extra effort to use
out_reserved1 = gpioreg.ByName("GPIO8") outReserved1 = gpioreg.ByName("GPIO8")
out_bit7 = gpioreg.ByName("GPIO5") outBit7 = gpioreg.ByName("GPIO5")
out_bit6 = gpioreg.ByName("GPIO11") outBit6 = gpioreg.ByName("GPIO11")
out_bit5 = gpioreg.ByName("GPIO9") outBit5 = gpioreg.ByName("GPIO9")
out_bit4 = gpioreg.ByName("GPIO10") outBit4 = gpioreg.ByName("GPIO10")
out_bit3 = gpioreg.ByName("GPIO22") outBit3 = gpioreg.ByName("GPIO22")
out_bit2 = gpioreg.ByName("GPIO27") outBit2 = gpioreg.ByName("GPIO27")
out_bit1 = gpioreg.ByName("GPIO17") outBit1 = gpioreg.ByName("GPIO17")
out_bit0 = gpioreg.ByName("GPIO4") outBit0 = gpioreg.ByName("GPIO4")
in_write = gpioreg.ByName("GPIO23") inWrite = gpioreg.ByName("GPIO23")
in_read = gpioreg.ByName("GPIO18") inRead = gpioreg.ByName("GPIO18")
in_reserved2 = gpioreg.ByName("GPIO14") inReserved2 = gpioreg.ByName("GPIO14")
in_reserved1 = gpioreg.ByName("GPIO15") inReserved1 = gpioreg.ByName("GPIO15")
in_bit7 = gpioreg.ByName("GPIO12") inBit7 = gpioreg.ByName("GPIO12")
in_bit6 = gpioreg.ByName("GPIO16") inBit6 = gpioreg.ByName("GPIO16")
in_bit5 = gpioreg.ByName("GPIO20") inBit5 = gpioreg.ByName("GPIO20")
in_bit4 = gpioreg.ByName("GPIO21") inBit4 = gpioreg.ByName("GPIO21")
in_bit3 = gpioreg.ByName("GPIO26") inBit3 = gpioreg.ByName("GPIO26")
in_bit2 = gpioreg.ByName("GPIO19") inBit2 = gpioreg.ByName("GPIO19")
in_bit1 = gpioreg.ByName("GPIO13") inBit1 = gpioreg.ByName("GPIO13")
in_bit0 = gpioreg.ByName("GPIO6") inBit0 = gpioreg.ByName("GPIO6")
in_write.In(gpio.PullDown, gpio.BothEdges) inWrite.In(gpio.PullDown, gpio.BothEdges)
in_read.In(gpio.PullDown, gpio.BothEdges) inRead.In(gpio.PullDown, gpio.BothEdges)
out_reserved1.Out(gpio.High) outReserved1.Out(gpio.High)
out_reserved2.Out(gpio.High) outReserved2.Out(gpio.High)
out_read.Out(gpio.High) outRead.Out(gpio.High)
out_write.Out(gpio.High) outWrite.Out(gpio.High)
out_bit7.Out(gpio.Low) outBit7.Out(gpio.Low)
out_bit6.Out(gpio.Low) outBit6.Out(gpio.Low)
out_bit5.Out(gpio.Low) outBit5.Out(gpio.Low)
out_bit4.Out(gpio.Low) outBit4.Out(gpio.Low)
out_bit3.Out(gpio.Low) outBit3.Out(gpio.Low)
out_bit2.Out(gpio.Low) outBit2.Out(gpio.Low)
out_bit1.Out(gpio.Low) outBit1.Out(gpio.Low)
out_bit0.Out(gpio.Low) outBit0.Out(gpio.Low)
edgeTimeout = time.Second edgeTimeout = time.Second
} }
// ReadString reads a string from the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) ReadString() (string, error) { func (a2 A2Gpio) ReadString() (string, error) {
var inBytes bytes.Buffer var inBytes bytes.Buffer
for { for {
@ -105,9 +109,10 @@ func (a2 A2Gpio) ReadString() (string, error) {
} }
inBytes.WriteByte(inByte) inBytes.WriteByte(inByte)
} }
return string(inBytes.Bytes()), nil return inBytes.String(), nil
} }
// WriteString writes a string to the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) WriteString(outString string) error { func (a2 A2Gpio) WriteString(outString string) error {
for _, character := range outString { for _, character := range outString {
err := a2.WriteByte(byte(character) | 128) err := a2.WriteByte(byte(character) | 128)
@ -120,29 +125,30 @@ func (a2 A2Gpio) WriteString(outString string) error {
return nil return nil
} }
// ReadByte reads a byte from the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) ReadByte() (byte, error) { func (a2 A2Gpio) ReadByte() (byte, error) {
// let the Apple II know we are ready to read // let the Apple II know we are ready to read
out_read.Out(gpio.Low) outRead.Out(gpio.Low)
// wait for the Apple II to write // wait for the Apple II to write
for in_write.Read() == gpio.High { for inWrite.Read() == gpio.High {
if !in_write.WaitForEdge(edgeTimeout) { if !inWrite.WaitForEdge(edgeTimeout) {
out_read.Out(gpio.High) outRead.Out(gpio.High)
return 0, errors.New("Timed out reading byte -- write stuck high\n") return 0, errors.New("timed out reading byte -- write stuck high")
} }
} }
// get a nibble of data // get a nibble of data
var data byte var data byte
data = 0 data = 0
bit7 := in_bit7.Read() bit7 := inBit7.Read()
bit6 := in_bit6.Read() bit6 := inBit6.Read()
bit5 := in_bit5.Read() bit5 := inBit5.Read()
bit4 := in_bit4.Read() bit4 := inBit4.Read()
bit3 := in_bit3.Read() bit3 := inBit3.Read()
bit2 := in_bit2.Read() bit2 := inBit2.Read()
bit1 := in_bit1.Read() bit1 := inBit1.Read()
bit0 := in_bit0.Read() bit0 := inBit0.Read()
if bit7 == gpio.High { if bit7 == gpio.High {
data += 128 data += 128
@ -166,36 +172,37 @@ func (a2 A2Gpio) ReadByte() (byte, error) {
data += 2 data += 2
} }
if bit0 == gpio.High { if bit0 == gpio.High {
data += 1 data++
} }
// let the Apple II know we are done reading // let the Apple II know we are done reading
//fmt.Printf("let the Apple II know we are done reading\n") //fmt.Printf("let the Apple II know we are done reading\n")
out_read.Out(gpio.High) outRead.Out(gpio.High)
// wait for the Apple II to finish writing // wait for the Apple II to finish writing
//fmt.Printf("wait for the Apple II to finish writing\n") //fmt.Printf("wait for the Apple II to finish writing\n")
for in_write.Read() == gpio.Low { for inWrite.Read() == gpio.Low {
if !in_write.WaitForEdge(edgeTimeout) { if !inWrite.WaitForEdge(edgeTimeout) {
return 0, errors.New("Timed out reading byte -- write stuck low") return 0, errors.New("timed out reading byte -- write stuck low")
} }
} }
return data, nil return data, nil
} }
// WriteByte writes a byte to the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) WriteByte(data byte) error { func (a2 A2Gpio) WriteByte(data byte) error {
// check if the Apple II wants to send a byte to us first // check if the Apple II wants to send a byte to us first
if in_write.Read() == gpio.Low { if inWrite.Read() == gpio.Low {
out_write.Out(gpio.High) outWrite.Out(gpio.High)
return errors.New("Can't write byte while byte is incoming") return errors.New("can't write byte while byte is incoming")
} }
// wait for the Apple II to be ready to read // wait for the Apple II to be ready to read
for in_read.Read() == gpio.High { for inRead.Read() == gpio.High {
if !in_read.WaitForEdge(edgeTimeout) { if !inRead.WaitForEdge(edgeTimeout) {
out_write.Out(gpio.High) outWrite.Out(gpio.High)
return errors.New("Timed out writing byte -- read stuck high") return errors.New("timed out writing byte -- read stuck high")
} }
} }
@ -211,60 +218,61 @@ func (a2 A2Gpio) WriteByte(data byte) error {
if ((data & 128) >> 7) == 1 { if ((data & 128) >> 7) == 1 {
bit7 = gpio.High bit7 = gpio.High
} }
out_bit7.Out(bit7) outBit7.Out(bit7)
if ((data & 64) >> 6) == 1 { if ((data & 64) >> 6) == 1 {
bit6 = gpio.High bit6 = gpio.High
} }
out_bit6.Out(bit6) outBit6.Out(bit6)
if ((data & 32) >> 5) == 1 { if ((data & 32) >> 5) == 1 {
bit5 = gpio.High bit5 = gpio.High
} }
out_bit5.Out(bit5) outBit5.Out(bit5)
if ((data & 16) >> 4) == 1 { if ((data & 16) >> 4) == 1 {
bit4 = gpio.High bit4 = gpio.High
} }
out_bit4.Out(bit4) outBit4.Out(bit4)
if ((data & 8) >> 3) == 1 { if ((data & 8) >> 3) == 1 {
bit3 = gpio.High bit3 = gpio.High
} }
out_bit3.Out(bit3) outBit3.Out(bit3)
if ((data & 4) >> 2) == 1 { if ((data & 4) >> 2) == 1 {
bit2 = gpio.High bit2 = gpio.High
} }
out_bit2.Out(bit2) outBit2.Out(bit2)
if ((data & 2) >> 1) == 1 { if ((data & 2) >> 1) == 1 {
bit1 = gpio.High bit1 = gpio.High
} }
out_bit1.Out(bit1) outBit1.Out(bit1)
if (data & 1) == 1 { if (data & 1) == 1 {
bit0 = gpio.High bit0 = gpio.High
} }
out_bit0.Out(bit0) outBit0.Out(bit0)
// let Apple II know we're writing // let Apple II know we're writing
out_write.Out(gpio.Low) outWrite.Out(gpio.Low)
// wait for the Apple II to finsih reading // wait for the Apple II to finsih reading
//fmt.Printf("wait for the Apple II to finsih reading\n") //fmt.Printf("wait for the Apple II to finsih reading\n")
for in_read.Read() == gpio.Low { for inRead.Read() == gpio.Low {
if !in_read.WaitForEdge(edgeTimeout) { if !inRead.WaitForEdge(edgeTimeout) {
out_write.Out(gpio.High) outWrite.Out(gpio.High)
return errors.New("Timed out writing byte -- read stuck low") return errors.New("timed out writing byte -- read stuck low")
} }
} }
// let the Apple II know we are done writing // let the Apple II know we are done writing
out_write.Out(gpio.High) outWrite.Out(gpio.High)
return nil return nil
} }
// WriteBlock writes 512 bytes to the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) WriteBlock(buffer []byte) error { func (a2 A2Gpio) WriteBlock(buffer []byte) error {
for i := 0; i < 512; i++ { for i := 0; i < 512; i++ {
err := a2.WriteByte(buffer[i]) err := a2.WriteByte(buffer[i])
@ -276,6 +284,7 @@ func (a2 A2Gpio) WriteBlock(buffer []byte) error {
return nil return nil
} }
// ReadBlock reads 512 bytes from the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) ReadBlock(buffer []byte) error { func (a2 A2Gpio) ReadBlock(buffer []byte) error {
var err error var err error
for i := 0; i < 512; i++ { for i := 0; i < 512; i++ {
@ -288,6 +297,7 @@ func (a2 A2Gpio) ReadBlock(buffer []byte) error {
return nil return nil
} }
// WriteBuffer writes a buffer of bytes to the Apple II via Raspberry Pi's GPIO ports
func (a2 A2Gpio) WriteBuffer(buffer []byte) error { func (a2 A2Gpio) WriteBuffer(buffer []byte) error {
bufferSize := len(buffer) bufferSize := len(buffer)
for i := 0; i < bufferSize; i++ { for i := 0; i < bufferSize; i++ {

View File

@ -4,6 +4,7 @@
// This file is used for mocking the GPIO code so that unit tests can be run // This file is used for mocking the GPIO code so that unit tests can be run
// on any machine and not just a Raspberry Pi // on any machine and not just a Raspberry Pi
package a2io package a2io
import ( import (
@ -11,6 +12,7 @@ import (
"strings" "strings"
) )
// MockIoData is used to verify tests were successful
type MockIoData struct { type MockIoData struct {
BytesToRead []byte BytesToRead []byte
BytesWritten []byte BytesWritten []byte
@ -19,20 +21,24 @@ type MockIoData struct {
ErrorToThrow error ErrorToThrow error
} }
// MockIo implements A2Io to allow unit tests to run without needing GPIO functioning
type MockIo struct { type MockIo struct {
Data *MockIoData Data *MockIoData
} }
// Init is only here to complete A2Io interface
func (mockIo MockIo) Init() { func (mockIo MockIo) Init() {
} }
// WriteByte mocks writing a byte to the Apple II
func (mockIo MockIo) WriteByte(data byte) error { func (mockIo MockIo) WriteByte(data byte) error {
mockIo.Data.BytesWritten[mockIo.Data.NumberBytesWritten] = data mockIo.Data.BytesWritten[mockIo.Data.NumberBytesWritten] = data
mockIo.Data.NumberBytesWritten++ mockIo.Data.NumberBytesWritten++
return mockIo.Data.ErrorToThrow return mockIo.Data.ErrorToThrow
} }
// WriteString mocks writing a string to the Apple II
func (mockIo MockIo) WriteString(outString string) error { func (mockIo MockIo) WriteString(outString string) error {
for i, b := range outString { for i, b := range outString {
mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = byte(b) mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = byte(b)
@ -41,6 +47,7 @@ func (mockIo MockIo) WriteString(outString string) error {
return mockIo.Data.ErrorToThrow return mockIo.Data.ErrorToThrow
} }
// WriteBlock mocks writing a block to the Apple II
func (mockIo MockIo) WriteBlock(buffer []byte) error { func (mockIo MockIo) WriteBlock(buffer []byte) error {
for i, b := range buffer { for i, b := range buffer {
mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = b mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = b
@ -49,6 +56,7 @@ func (mockIo MockIo) WriteBlock(buffer []byte) error {
return mockIo.Data.ErrorToThrow return mockIo.Data.ErrorToThrow
} }
// WriteBuffer mocks writing a buffer to the Apple II
func (mockIo MockIo) WriteBuffer(buffer []byte) error { func (mockIo MockIo) WriteBuffer(buffer []byte) error {
for i, b := range buffer { for i, b := range buffer {
mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = b mockIo.Data.BytesWritten[i+mockIo.Data.NumberBytesWritten] = b
@ -57,17 +65,19 @@ func (mockIo MockIo) WriteBuffer(buffer []byte) error {
return mockIo.Data.ErrorToThrow return mockIo.Data.ErrorToThrow
} }
// ReadByte mocks reading a byte from the Apple II
func (mockIo MockIo) ReadByte() (byte, error) { func (mockIo MockIo) ReadByte() (byte, error) {
b := mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead] b := mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead]
mockIo.Data.NumberBytesRead++ mockIo.Data.NumberBytesRead++
return b, mockIo.Data.ErrorToThrow return b, mockIo.Data.ErrorToThrow
} }
// ReadString mocks reading a null terminated string from the Apple II
func (mockIo MockIo) ReadString() (string, error) { func (mockIo MockIo) ReadString() (string, error) {
builder := strings.Builder{} builder := strings.Builder{}
for { for {
if mockIo.Data.NumberBytesRead > len(mockIo.Data.BytesToRead) { if mockIo.Data.NumberBytesRead > len(mockIo.Data.BytesToRead) {
return "", errors.New("Read more data than available") return "", errors.New("read more data than available")
} }
builder.WriteByte(mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead]) builder.WriteByte(mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead])
mockIo.Data.NumberBytesRead++ mockIo.Data.NumberBytesRead++
@ -79,9 +89,10 @@ func (mockIo MockIo) ReadString() (string, error) {
return builder.String(), mockIo.Data.ErrorToThrow return builder.String(), mockIo.Data.ErrorToThrow
} }
// ReadBlock mocks reading a 512 byte block from the Apple II
func (mockIo MockIo) ReadBlock(buffer []byte) error { func (mockIo MockIo) ReadBlock(buffer []byte) error {
if mockIo.Data.NumberBytesRead+512 > len(mockIo.Data.BytesToRead) { if mockIo.Data.NumberBytesRead+512 > len(mockIo.Data.BytesToRead) {
return errors.New("Read more data than available") return errors.New("read more data than available")
} }
for i := 0; i < 512; i++ { for i := 0; i < 512; i++ {
buffer[i] = mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead] buffer[i] = mockIo.Data.BytesToRead[mockIo.Data.NumberBytesRead]

View File

@ -5,6 +5,7 @@
// This file is only used during development for interactive testing of the // This file is only used during development for interactive testing of the
// driver code. Simply replace `comm := a2io.A2Gpio{}` with // driver code. Simply replace `comm := a2io.A2Gpio{}` with
// `comm := a2io.UserIo{}` in the driver.go file to allow local testing // `comm := a2io.UserIo{}` in the driver.go file to allow local testing
package a2io package a2io
import ( import (
@ -13,28 +14,34 @@ import (
"strings" "strings"
) )
// UserIo implements A2Io for the purpose of debugging locally
type UserIo struct { type UserIo struct {
} }
// Init is only here to complete A2Io interface
func (userIo UserIo) Init() { func (userIo UserIo) Init() {
} }
// WriteByte simulates writing to the Apple II but uses stdout instead
func (userIo UserIo) WriteByte(data byte) error { func (userIo UserIo) WriteByte(data byte) error {
fmt.Printf("WriteByte: %02X\n", data) fmt.Printf("WriteByte: %02X\n", data)
return nil return nil
} }
// WriteString simulates writing to the Apple II but uses stdout instead
func (userIo UserIo) WriteString(outString string) error { func (userIo UserIo) WriteString(outString string) error {
fmt.Printf("WriteString: %s\n", strings.ReplaceAll(outString, "\r", "\n")) fmt.Printf("WriteString: %s\n", strings.ReplaceAll(outString, "\r", "\n"))
return nil return nil
} }
// WriteBlock simulates writing to the Apple II but uses stdout instead
func (userIo UserIo) WriteBlock(buffer []byte) error { func (userIo UserIo) WriteBlock(buffer []byte) error {
fmt.Printf("WriteBlock:\n") fmt.Printf("WriteBlock:\n")
return userIo.WriteBuffer(buffer) return userIo.WriteBuffer(buffer)
} }
// WriteBuffer simulates writing to the Apple II but uses stdout instead
func (userIo UserIo) WriteBuffer(buffer []byte) error { func (userIo UserIo) WriteBuffer(buffer []byte) error {
fmt.Printf("WriteBuffer:\n") fmt.Printf("WriteBuffer:\n")
for i, b := range buffer { for i, b := range buffer {
@ -47,6 +54,7 @@ func (userIo UserIo) WriteBuffer(buffer []byte) error {
return nil return nil
} }
// ReadByte simulates reading to the Apple II but uses stdin instead
func (userIo UserIo) ReadByte() (byte, error) { func (userIo UserIo) ReadByte() (byte, error) {
fmt.Printf("ReadByte: ") fmt.Printf("ReadByte: ")
var b byte var b byte
@ -55,6 +63,7 @@ func (userIo UserIo) ReadByte() (byte, error) {
return b, nil return b, nil
} }
// ReadString simulates reading to the Apple II but uses stdin instead
func (userIo UserIo) ReadString() (string, error) { func (userIo UserIo) ReadString() (string, error) {
fmt.Printf("ReadString: ") fmt.Printf("ReadString: ")
var s string var s string
@ -63,6 +72,7 @@ func (userIo UserIo) ReadString() (string, error) {
return s, nil return s, nil
} }
// ReadBlock should simulate reading to the Apple II but is not yet supported
func (userIo UserIo) ReadBlock(buffer []byte) error { func (userIo UserIo) ReadBlock(buffer []byte) error {
fmt.Printf("ReadBlock: (Not supported)") fmt.Printf("ReadBlock: (Not supported)")
return errors.New("ReadBlock not supported") return errors.New("ReadBlock not supported")

View File

@ -17,14 +17,14 @@ import (
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/handlers" "github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/handlers"
) )
const ReadBlockCommand = 1 const readBlockCommand = 1
const WriteBlockCommand = 2 const writeBlockCommand = 2
const GetTimeCommand = 3 const getTimeCommand = 3
const ChangeDriveCommand = 4 const changeDriveCommand = 4
const ExecCommand = 5 const execCommand = 5
const LoadFileCommand = 6 const loadFileCommand = 6
const SaveFileCommand = 7 const saveFileCommand = 7
const MenuCommand = 8 const menuCommand = 8
func main() { func main() {
drive1, drive2 := getDriveFiles() drive1, drive2 := getDriveFiles()
@ -40,17 +40,17 @@ func main() {
command, err := comm.ReadByte() command, err := comm.ReadByte()
if err == nil { if err == nil {
switch command { switch command {
case ReadBlockCommand: case readBlockCommand:
handlers.ReadBlockCommand(drive1, drive2) handlers.ReadBlockCommand(drive1, drive2)
case WriteBlockCommand: case writeBlockCommand:
handlers.WriteBlockCommand(drive1, drive2) handlers.WriteBlockCommand(drive1, drive2)
case GetTimeCommand: case getTimeCommand:
handlers.GetTimeCommand() handlers.GetTimeCommand()
case ExecCommand: case execCommand:
handlers.ExecCommand() handlers.ExecCommand()
case LoadFileCommand: case loadFileCommand:
handlers.LoadFileCommand() handlers.LoadFileCommand()
case MenuCommand: case menuCommand:
handlers.MenuCommand() handlers.MenuCommand()
} }
} }
@ -71,8 +71,8 @@ func getDriveFiles() (*os.File, *os.File) {
flag.StringVar(&drive2Name, "d2", defaultFileName, "A ProDOS format drive image for drive 2 and will be used for drive 1 if drive 1 empty") flag.StringVar(&drive2Name, "d2", defaultFileName, "A ProDOS format drive image for drive 2 and will be used for drive 1 if drive 1 empty")
flag.Parse() flag.Parse()
var drive1 *os.File = nil var drive1 *os.File
var drive2 *os.File = nil var drive2 *os.File
var err error var err error
if len(drive1Name) > 0 { if len(drive1Name) > 0 {

View File

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This file is used for handling ProDOS image block reading and writing // This file is used for handling ProDOS image block reading and writing
package handlers package handlers
import ( import (
@ -14,10 +15,11 @@ import (
var oldFirmware = false var oldFirmware = false
// ReadBlockCommand handles requests to read ProDOS blocks
func ReadBlockCommand(drive1 *os.File, drive2 *os.File) { func ReadBlockCommand(drive1 *os.File, drive2 *os.File) {
blockLow, _ := comm.ReadByte() blockLow, _ := comm.ReadByte()
blockHigh, _ := comm.ReadByte() blockHigh, _ := comm.ReadByte()
var driveUnit byte = 0 var driveUnit byte
var err error var err error
if !oldFirmware { if !oldFirmware {
@ -50,11 +52,12 @@ func ReadBlockCommand(drive1 *os.File, drive2 *os.File) {
} }
} }
// WriteBlockCommand handles requests to write ProDOS blocks
func WriteBlockCommand(drive1 *os.File, drive2 *os.File) { func WriteBlockCommand(drive1 *os.File, drive2 *os.File) {
blockLow, _ := comm.ReadByte() blockLow, _ := comm.ReadByte()
blockHigh, _ := comm.ReadByte() blockHigh, _ := comm.ReadByte()
var driveUnit byte = 0 var driveUnit byte
var err error var err error
if !oldFirmware { if !oldFirmware {

View File

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This file is used for setting up the communications for the handlers // This file is used for setting up the communications for the handlers
package handlers package handlers
import ( import (
@ -11,6 +12,7 @@ import (
var comm a2io.A2Io var comm a2io.A2Io
// SetCommunication configures whether to use real or mock communications
func SetCommunication(commIO a2io.A2Io) { func SetCommunication(commIO a2io.A2Io) {
comm = commIO comm = commIO
} }

View File

@ -4,6 +4,7 @@
// This file is contains the handler for executing Linux and internal // This file is contains the handler for executing Linux and internal
// commands // commands
package handlers package handlers
import ( import (
@ -17,6 +18,7 @@ import (
var forceLowercase = false var forceLowercase = false
// ExecCommand handles requests for the Apple II executing Linux commands
func ExecCommand() { func ExecCommand() {
workingDirectory, err := os.Getwd() workingDirectory, err := os.Getwd()
if err != nil { if err != nil {
@ -109,7 +111,6 @@ func execCommand(linuxCommand string, workingDirectory string) {
cmd.Wait() cmd.Wait()
comm.WriteByte(0) comm.WriteByte(0)
return return
default:
} }
} }
} }
@ -183,13 +184,12 @@ func getStdin(stdin io.WriteCloser, done chan bool, inputComplete chan bool, use
stdin.Close() stdin.Close()
userCancelled <- true userCancelled <- true
return return
} else {
if b == 13 {
b = 10
}
fmt.Printf("%c", b)
io.WriteString(stdin, string(b))
} }
if b == 13 {
b = 10
}
fmt.Printf("%c", b)
io.WriteString(stdin, string(b))
} }
} }
} }

View File

@ -4,6 +4,7 @@
// This file is contains the handler for retrieving the ProDOS timestamp // This file is contains the handler for retrieving the ProDOS timestamp
// based on the current time // based on the current time
package handlers package handlers
import ( import (
@ -13,6 +14,7 @@ import (
"github.com/tjboldt/ProDOS-Utilities/prodos" "github.com/tjboldt/ProDOS-Utilities/prodos"
) )
// GetTimeCommand handles the request to get ProDOS time bytes
func GetTimeCommand() { func GetTimeCommand() {
fmt.Printf("Sending date/time...\n") fmt.Printf("Sending date/time...\n")
prodosTime := prodos.DateTimeToProDOS(time.Now()) prodosTime := prodos.DateTimeToProDOS(time.Now())

View File

@ -4,6 +4,7 @@
// This file is contains the handler for loading files directly from the // This file is contains the handler for loading files directly from the
// Raspberry Pi onto the Apple II // Raspberry Pi onto the Apple II
package handlers package handlers
import ( import (
@ -11,6 +12,7 @@ import (
"os" "os"
) )
// LoadFileCommand handles requests to direct read files from Linux to the Apple II
func LoadFileCommand() { func LoadFileCommand() {
fileName, _ := comm.ReadString() fileName, _ := comm.ReadString()

View File

@ -4,12 +4,14 @@
// This file is contains the handler for displaying the menu of choices on // This file is contains the handler for displaying the menu of choices on
// the Apple II // the Apple II
package handlers package handlers
import ( import (
"fmt" "fmt"
) )
// MenuCommand handles the request to show menu options on the Apple II
func MenuCommand() { func MenuCommand() {
fmt.Printf("Sending menu...\n") fmt.Printf("Sending menu...\n")
comm.WriteString("Apple2-IO-RPi\r" + comm.WriteString("Apple2-IO-RPi\r" +