|
|
|
@@ -1,14 +1,18 @@
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"periph.io/x/periph/conn/gpio"
|
|
|
|
|
"periph.io/x/periph/conn/gpio/gpioreg"
|
|
|
|
|
"periph.io/x/periph/host"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
"errors"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var edgeTimeout time.Duration
|
|
|
|
|
|
|
|
|
|
var out_write gpio.PinIO
|
|
|
|
@@ -31,23 +35,271 @@ var in_bit0 gpio.PinIO
|
|
|
|
|
const ReadBlockCommand = 1
|
|
|
|
|
const WriteBlockCommand = 2
|
|
|
|
|
const GetTimeCommand = 3
|
|
|
|
|
const ChangeDriveCommand = 4
|
|
|
|
|
const ExecCommand = 5
|
|
|
|
|
|
|
|
|
|
var debug bool = false
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
host.Init()
|
|
|
|
|
|
|
|
|
|
initGpio()
|
|
|
|
|
|
|
|
|
|
if len(os.Args) == 3 && os.Args[2] == "--debug" {
|
|
|
|
|
debug = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Starting Apple II RPi...\n")
|
|
|
|
|
|
|
|
|
|
fileName := os.Args[1]
|
|
|
|
|
|
|
|
|
|
file, err := os.OpenFile(fileName, os.O_RDWR, 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("ERROR: %s", err.Error())
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("Check for command\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
command, err := readByte()
|
|
|
|
|
if err != nil {
|
|
|
|
|
//fmt.Printf("Timed out waiting for command\n")
|
|
|
|
|
} else {
|
|
|
|
|
switch command {
|
|
|
|
|
case ReadBlockCommand:
|
|
|
|
|
handleReadBlockCommand(file)
|
|
|
|
|
case WriteBlockCommand:
|
|
|
|
|
handleWriteBlockCommand(file)
|
|
|
|
|
case GetTimeCommand:
|
|
|
|
|
handleGetTimeCommand()
|
|
|
|
|
case ExecCommand:
|
|
|
|
|
handleExecCommand()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func handleReadBlockCommand(file *os.File) {
|
|
|
|
|
blockLow, _ := readByte()
|
|
|
|
|
blockHigh, _ := readByte()
|
|
|
|
|
|
|
|
|
|
buffer := make([]byte, 512)
|
|
|
|
|
var block int64
|
|
|
|
|
block = int64(blockHigh)*256 + int64(blockLow)
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Read block %d\n", block)
|
|
|
|
|
|
|
|
|
|
file.ReadAt(buffer, int64(block)*512)
|
|
|
|
|
//dumpBlock(buffer)
|
|
|
|
|
readBlock(buffer)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func handleWriteBlockCommand(file *os.File) {
|
|
|
|
|
blockLow, _ := readByte()
|
|
|
|
|
blockHigh, _ := readByte()
|
|
|
|
|
|
|
|
|
|
buffer := make([]byte, 512)
|
|
|
|
|
var block int64
|
|
|
|
|
block = int64(blockHigh)*256 + int64(blockLow)
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Write block %d\n", block)
|
|
|
|
|
|
|
|
|
|
writeBlock(buffer)
|
|
|
|
|
file.WriteAt(buffer, int64(block)*512)
|
|
|
|
|
file.Sync()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func handleExecCommand() {
|
|
|
|
|
fmt.Printf("Reading command to execute...\n")
|
|
|
|
|
linuxCommand,err := readString()
|
|
|
|
|
fmt.Printf("Command to run: %s\n", linuxCommand)
|
|
|
|
|
cmd := exec.Command("bash", "-c", linuxCommand)
|
|
|
|
|
cmdOut, err := cmd.Output()
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("Failed to execute command\n")
|
|
|
|
|
writeString("Failed to execute command")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("Command output: %s\n", cmdOut)
|
|
|
|
|
apple2string := strings.Replace(string(cmdOut), "\n", "\r", -1)
|
|
|
|
|
err = writeString(apple2string)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("Failed to send command output\n")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func handleGetTimeCommand() {
|
|
|
|
|
/* 49041 ($BF91) 49040 ($BF90)
|
|
|
|
|
|
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
DATE: | year | month | day |
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
|
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
TIME: | hour | | minute |
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
|
|
|
|
|
49043 ($BF93) 49042 ($BF92)
|
|
|
|
|
*/
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
|
|
year := now.Year() % 100
|
|
|
|
|
month := now.Month()
|
|
|
|
|
day := now.Day()
|
|
|
|
|
hour := now.Hour()
|
|
|
|
|
minute := now.Minute()
|
|
|
|
|
|
|
|
|
|
bf91 := (byte(year) << 1) + (byte(month) >> 3)
|
|
|
|
|
bf90 := ((byte(month) & 15) << 5) + byte(day)
|
|
|
|
|
bf93 := byte(hour)
|
|
|
|
|
bf92 := byte(minute)
|
|
|
|
|
|
|
|
|
|
writeByte(bf90)
|
|
|
|
|
writeByte(bf91)
|
|
|
|
|
writeByte(bf92)
|
|
|
|
|
writeByte(bf93)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readBlock(buffer []byte) error {
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
err := writeByte(buffer[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeBlock(buffer []byte) error {
|
|
|
|
|
var err error
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
buffer[i], err = readByte()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func initGpio() {
|
|
|
|
|
out_write = gpioreg.ByName("GPIO5")
|
|
|
|
|
out_read = gpioreg.ByName("GPIO11")
|
|
|
|
|
out_commandWrite = gpioreg.ByName("GPIO9")
|
|
|
|
|
out_commandRead = gpioreg.ByName("GPIO10")
|
|
|
|
|
out_bit3 = gpioreg.ByName("GPIO22")
|
|
|
|
|
out_bit2 = gpioreg.ByName("GPIO27")
|
|
|
|
|
out_bit1 = gpioreg.ByName("GPIO17")
|
|
|
|
|
out_bit0 = gpioreg.ByName("GPIO4")
|
|
|
|
|
in_write = gpioreg.ByName("GPIO12")
|
|
|
|
|
in_read = gpioreg.ByName("GPIO16")
|
|
|
|
|
in_commandWrite = gpioreg.ByName("GPIO20")
|
|
|
|
|
in_commandRead = gpioreg.ByName("GPIO21")
|
|
|
|
|
in_bit3 = gpioreg.ByName("GPIO26")
|
|
|
|
|
in_bit2 = gpioreg.ByName("GPIO19")
|
|
|
|
|
in_bit1 = gpioreg.ByName("GPIO13")
|
|
|
|
|
in_bit0 = gpioreg.ByName("GPIO6")
|
|
|
|
|
|
|
|
|
|
in_write.In(gpio.PullDown, gpio.BothEdges)
|
|
|
|
|
in_read.In(gpio.PullDown, gpio.BothEdges)
|
|
|
|
|
|
|
|
|
|
edgeTimeout = time.Second * 5
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dumpBlock(buffer []byte) {
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
fmt.Printf("%02X ", buffer[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readString() (string, error) {
|
|
|
|
|
var inBytes bytes.Buffer
|
|
|
|
|
for {
|
|
|
|
|
inByte,err := readByte()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
if inByte == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
inBytes.WriteByte(inByte)
|
|
|
|
|
}
|
|
|
|
|
return string(inBytes.Bytes()), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeString(outString string) error {
|
|
|
|
|
for _, character := range outString {
|
|
|
|
|
err := writeByte(byte(character)|128)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("Failed to write string\n")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
writeByte(0)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readByte() (byte, error) {
|
|
|
|
|
data, err := readNibble()
|
|
|
|
|
data = data << byte(4)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
highNibble, err := readNibble()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
data += highNibble
|
|
|
|
|
//fmt.Printf("R%02X ", data)
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeByte(data byte) error {
|
|
|
|
|
//fmt.Printf("W%02X ", data)
|
|
|
|
|
err := writeNibble(data >> 4)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = writeNibble(data & 15)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readNibble() (byte, error) {
|
|
|
|
|
// let the Apple II know we are ready to read
|
|
|
|
|
//fmt.Printf("let the Apple II know we are ready to read\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("let the Apple II know we are ready to read\n")
|
|
|
|
|
}
|
|
|
|
|
out_read.Out(gpio.Low)
|
|
|
|
|
|
|
|
|
|
// wait for the Apple II to write
|
|
|
|
|
//fmt.Printf("wait for the Apple II to write\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("wait for the Apple II to write\n")
|
|
|
|
|
}
|
|
|
|
|
for in_write.Read() == gpio.High {
|
|
|
|
|
if !in_write.WaitForEdge(edgeTimeout) {
|
|
|
|
|
//fmt.Printf("Timed out reading nibble -- write stuck high\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("Timed out reading nibble -- write stuck high\n")
|
|
|
|
|
}
|
|
|
|
|
return 0, errors.New("Timed out reading nibble -- write stuck high\n")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get a nibble of data
|
|
|
|
|
//fmt.Printf("get a nibble of data\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("get a nibble of data\n")
|
|
|
|
|
}
|
|
|
|
|
var nibble byte
|
|
|
|
|
nibble = 0
|
|
|
|
|
bit3 := in_bit3.Read()
|
|
|
|
@@ -76,7 +328,9 @@ func readNibble() (byte, error) {
|
|
|
|
|
//fmt.Printf("wait for the Apple II to finish writing\n")
|
|
|
|
|
for in_write.Read() == gpio.Low {
|
|
|
|
|
if !in_write.WaitForEdge(edgeTimeout) {
|
|
|
|
|
//fmt.Printf("Timed out reading nibble -- write stuck low\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("Timed out reading nibble -- write stuck low\n")
|
|
|
|
|
}
|
|
|
|
|
return 0, errors.New("Timed out reading nibble -- write stuck low")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -84,23 +338,16 @@ func readNibble() (byte, error) {
|
|
|
|
|
return nibble, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readByte() (byte, error) {
|
|
|
|
|
data, err := readNibble()
|
|
|
|
|
data = data << byte(4)
|
|
|
|
|
if err != nil { return 0, err }
|
|
|
|
|
highNibble, err := readNibble()
|
|
|
|
|
if err != nil { return 0, err }
|
|
|
|
|
data += highNibble
|
|
|
|
|
//fmt.Printf("R%02X ", data)
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeNibble(data byte) error {
|
|
|
|
|
// wait for the Apple II to be ready to read
|
|
|
|
|
//fmt.Printf("wait for the Apple II to be ready to read\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("wait for the Apple II to be ready to read\n")
|
|
|
|
|
}
|
|
|
|
|
for in_read.Read() == gpio.High {
|
|
|
|
|
if !in_read.WaitForEdge(edgeTimeout) {
|
|
|
|
|
//fmt.Printf("Timed out writing nibble -- read stuck high\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("Timed out writing nibble -- read stuck high\n")
|
|
|
|
|
}
|
|
|
|
|
return errors.New("Timed out writing nibble -- read stuck high")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -130,176 +377,26 @@ func writeNibble(data byte) error {
|
|
|
|
|
out_bit0.Out(bit0)
|
|
|
|
|
|
|
|
|
|
// let Apple II know we're writing
|
|
|
|
|
//fmt.Printf("let Apple II know we're writing\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("let Apple II know we're writing\n")
|
|
|
|
|
}
|
|
|
|
|
out_write.Out(gpio.Low)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// wait for the Apple II to finsih reading
|
|
|
|
|
//fmt.Printf("wait for the Apple II to finsih reading\n")
|
|
|
|
|
for in_read.Read() == gpio.Low {
|
|
|
|
|
if !in_read.WaitForEdge(edgeTimeout) {
|
|
|
|
|
//fmt.Printf("Timed out writing nibble -- read stuck low\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("Timed out writing nibble -- read stuck low\n")
|
|
|
|
|
}
|
|
|
|
|
return errors.New("Timed out writing nibble -- read stuck low")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let the Apple II know we are done writing
|
|
|
|
|
//fmt.Printf("let the Apple II know we are done writing\n")
|
|
|
|
|
if debug {
|
|
|
|
|
fmt.Printf("let the Apple II know we are done writing\n")
|
|
|
|
|
}
|
|
|
|
|
out_write.Out(gpio.High)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeByte(data byte) error {
|
|
|
|
|
//fmt.Printf("W%02X ", data)
|
|
|
|
|
err := writeNibble(data >> 4)
|
|
|
|
|
if err != nil { return err }
|
|
|
|
|
err = writeNibble(data & 15)
|
|
|
|
|
if err != nil { return err }
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readBlock(buffer []byte) error {
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
err := writeByte(buffer[i])
|
|
|
|
|
if err != nil { return err }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func dumpBlock(buffer []byte) {
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
fmt.Printf("%02X ", buffer[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeBlock(buffer []byte) error {
|
|
|
|
|
var err error
|
|
|
|
|
for i := 0; i < 512; i++ {
|
|
|
|
|
buffer[i], err = readByte()
|
|
|
|
|
if err != nil { return err }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
host.Init()
|
|
|
|
|
|
|
|
|
|
out_write = gpioreg.ByName("GPIO5")
|
|
|
|
|
out_read = gpioreg.ByName("GPIO11")
|
|
|
|
|
out_commandWrite = gpioreg.ByName("GPIO9")
|
|
|
|
|
out_commandRead = gpioreg.ByName("GPIO10")
|
|
|
|
|
out_bit3 = gpioreg.ByName("GPIO22")
|
|
|
|
|
out_bit2 = gpioreg.ByName("GPIO27")
|
|
|
|
|
out_bit1 = gpioreg.ByName("GPIO17")
|
|
|
|
|
out_bit0 = gpioreg.ByName("GPIO4")
|
|
|
|
|
in_write = gpioreg.ByName("GPIO12")
|
|
|
|
|
in_read = gpioreg.ByName("GPIO16")
|
|
|
|
|
in_commandWrite = gpioreg.ByName("GPIO20")
|
|
|
|
|
in_commandRead = gpioreg.ByName("GPIO21")
|
|
|
|
|
in_bit3 = gpioreg.ByName("GPIO26")
|
|
|
|
|
in_bit2 = gpioreg.ByName("GPIO19")
|
|
|
|
|
in_bit1 = gpioreg.ByName("GPIO13")
|
|
|
|
|
in_bit0 = gpioreg.ByName("GPIO6")
|
|
|
|
|
|
|
|
|
|
in_write.In(gpio.PullDown, gpio.BothEdges)
|
|
|
|
|
in_read.In(gpio.PullDown, gpio.BothEdges)
|
|
|
|
|
|
|
|
|
|
edgeTimeout = time.Second * 5
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Starting Apple II RPi...\n")
|
|
|
|
|
fileName := os.Args[1]
|
|
|
|
|
file, err := os.OpenFile(fileName, os.O_RDWR, 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("ERROR: %s", err.Error())
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
//if err := f.Close(); err != nil {
|
|
|
|
|
//log.Fatal(err)
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//for in_write.Read() == gpio.Low {
|
|
|
|
|
// in_write.WaitForEdge(-1)
|
|
|
|
|
//}
|
|
|
|
|
buffer := make([]byte, 512)
|
|
|
|
|
//file.ReadAt(buffer, int64(0) * 512)
|
|
|
|
|
//dumpBlock(buffer)
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
//fmt.Printf("Check for command")
|
|
|
|
|
|
|
|
|
|
command,err := readByte();
|
|
|
|
|
if err != nil {
|
|
|
|
|
//fmt.Printf("Timed out waiting for command\n")
|
|
|
|
|
} else {
|
|
|
|
|
switch command {
|
|
|
|
|
case ReadBlockCommand:
|
|
|
|
|
blockLow,_ := readByte();
|
|
|
|
|
blockHigh,_ := readByte();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var block int64
|
|
|
|
|
block = int64(blockHigh) * 256 + int64(blockLow)
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Read block %d\n", block)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file.ReadAt(buffer, int64(block) * 512)
|
|
|
|
|
//dumpBlock(buffer)
|
|
|
|
|
readBlock(buffer)
|
|
|
|
|
break
|
|
|
|
|
case WriteBlockCommand:
|
|
|
|
|
blockLow,_ := readByte();
|
|
|
|
|
blockHigh,_ := readByte();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var block int64
|
|
|
|
|
block = int64(blockHigh) * 256 + int64(blockLow)
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Write block %d\n", block)
|
|
|
|
|
|
|
|
|
|
writeBlock(buffer)
|
|
|
|
|
file.WriteAt(buffer, int64(block) * 512)
|
|
|
|
|
file.Sync()
|
|
|
|
|
break
|
|
|
|
|
case GetTimeCommand:
|
|
|
|
|
/*
|
|
|
|
|
49041 ($BF91) 49040 ($BF90)
|
|
|
|
|
|
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
DATE: | year | month | day |
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
|
|
|
|
|
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
TIME: | hour | | minute |
|
|
|
|
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
|
|
|
|
|
49043 ($BF93) 49042 ($BF92)
|
|
|
|
|
*/
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
|
|
year := now.Year() % 100
|
|
|
|
|
month := now.Month()
|
|
|
|
|
day := now.Day()
|
|
|
|
|
hour := now.Hour()
|
|
|
|
|
minute := now.Minute()
|
|
|
|
|
|
|
|
|
|
bf91 := (byte(year) << 1) + (byte(month) >> 3)
|
|
|
|
|
bf90 := ((byte(month) & 15) << 5) + byte(day)
|
|
|
|
|
bf93 := byte(hour)
|
|
|
|
|
bf92 := byte(minute)
|
|
|
|
|
|
|
|
|
|
writeByte(bf90)
|
|
|
|
|
writeByte(bf91)
|
|
|
|
|
writeByte(bf92)
|
|
|
|
|
writeByte(bf93)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|