Skip to content

Commit

Permalink
Readline like input with persistent history
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanizag committed Aug 18, 2021
1 parent 425d80c commit 68f4cdf
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
bbz
dist/
firmware.o
.bzzhistory
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ References:
- [The MOS Reassembly for the BBC Micro](https://tobylobster.github.io/mos/mos/index.html)

## Features
- Some of the MOS entrypoints and VDU control codes are defined.
- Can run BBC BASIC and most of the language ROMs.
- Can load up to 16 sideways ROMs.
- Readline like input with persistent history (`-r` parameter)
- Some of the MOS entrypoints and VDU control codes are defined.
- Saves and loads files from the host filesystem.
- Does some of the mode 7 text coloring using ANSI escape codes on the terminal. Try `VDU 65,129,66,130,67,132,68,135,69,13,10` on BBC BASIC.
- OSCLI comands suported:
- *QUIT: exit
- *HELP
- *BASIC
- *FX
- *HOST cmd: execute a command on the host OS. Example: `*HOST ls -la`

Expand All @@ -50,6 +52,7 @@ AvaIlable flags (to put before the ROM filename if present):
-c dump to the console the CPU execution operations
-m dump to the console the MOS calls excluding console I/O calls
-p panic on not implemented MOS calls
-r use readline like input with history
-s dump to the console the accesses to Fred, Jim or Sheila
-rom0 string
filename for rom 0 (slot 0xf)
Expand Down
2 changes: 1 addition & 1 deletion bbz.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func RunMOS(env *environment) {
After an OSRDCH call: C=0 indicates that a valid character has
been read; C=1 flags an error condition, A contains an error number.
*/
ch, stop := env.in.readChar()
ch, stop := env.con.readChar()
if stop {
env.stop = true
return
Expand Down
49 changes: 49 additions & 0 deletions console.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"bufio"
"fmt"
"os"
)

type console interface {
readline() (string, bool)
readChar() (uint8, bool)
write(s string)
close()
}

type consoleSimple struct {
in *bufio.Scanner
}

func newConsoleSimple() *consoleSimple {
var c consoleSimple
c.in = bufio.NewScanner(os.Stdin)
return &c
}

func (c *consoleSimple) readline() (string, bool) {
if !c.in.Scan() {
return "", true
}
line := c.in.Text()
return line, false
}

func (c *consoleSimple) readChar() (uint8, bool) {
// TODO: capture keystrokes. We will just get the first char of the line
// and ignore the rest.
s, stop := c.readline()
if s == "" {
return ' ', stop
} else {
return s[0], stop
}
}

func (c *consoleSimple) write(s string) {
fmt.Print(s)
}

func (c *consoleSimple) close() {}
74 changes: 74 additions & 0 deletions consoleLiner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"fmt"
"io"
"os"
"strings"

"github.com/peterh/liner"
)

const historyFilename = ".bzzhistory"

type consoleLiner struct {
liner *liner.State
prompt string
}

func newConsoleLiner() *consoleLiner {
var c consoleLiner

c.liner = liner.NewLiner()
c.liner.SetCtrlCAborts(true)
if f, err := os.Open(historyFilename); err == nil {
c.liner.ReadHistory(f)
f.Close()
}

return &c
}

func (c *consoleLiner) close() {

if f, err := os.Create(historyFilename); err == nil {
c.liner.WriteHistory(f)
f.Close()
}

c.liner.Close()
}

func (c *consoleLiner) readline() (string, bool) {
fmt.Printf("\r")
line, err := c.liner.Prompt(c.prompt)
c.prompt = ""
if err == liner.ErrPromptAborted || err == io.EOF {
return "", true
}
if err != nil {
panic(err)
}
c.liner.AppendHistory(line)
return line, false
}

func (c *consoleLiner) readChar() (uint8, bool) {
// TODO: capture keystrokes. We will just get the first char of the line
// and ignore the rest.
s, stop := c.readline()
if s == "" {
return ' ', stop
} else {
return s[0], stop
}
}

func (c *consoleLiner) write(s string) {
if strings.HasSuffix(s, "\n") || strings.HasSuffix(s, "\r") {
c.prompt = ""
} else {
c.prompt += s
}
fmt.Print(s)
}
16 changes: 12 additions & 4 deletions environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type environment struct {
cpu *core6502.State
mem *acornMemory
vdu *vdu
in input
con console

// clock, used by OSWORD01 and 02
referenceTime time.Time
Expand All @@ -33,22 +33,30 @@ type environment struct {
panicOnErr bool
}

func newEnvironment(cpuLog bool, apiLog bool, apiLogIO bool, memLog bool, panicOnErr bool) *environment {
func newEnvironment(cpuLog bool, apiLog bool, apiLogIO bool, memLog bool, panicOnErr bool, readline bool) *environment {
var env environment
env.in = newInputSimple()
if readline {
env.con = newConsoleLiner()
} else {
env.con = newConsoleSimple()
}
env.referenceTime = time.Now()
env.timer = 0
env.lastTimerUpdate = time.Now()
env.mem = newAcornMemory(memLog)
env.cpu = core6502.NewNMOS6502(env.mem)
env.cpu.SetTrace(cpuLog)
env.vdu = newVdu()
env.vdu = newVdu(env.con)
env.apiLog = apiLog
env.apiLogIO = apiLogIO
env.panicOnErr = panicOnErr
return &env
}

func (env *environment) close() {
env.con.close()
}

func (env *environment) getFile(handle uint8) *os.File {
i := handle - 1
if i < maxFiles && env.file[i] != nil {
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ module github.com/ivanizag/bbz

go 1.16

// Update with go get github.com/ivanizag/izapple2/core6502@master
require github.com/ivanizag/izapple2 v0.0.0-20210725095035-e47730e13158
require (
// Update with go get github.com/ivanizag/izapple2/core6502@master
github.com/ivanizag/izapple2 v0.0.0-20210725095035-e47730e13158
github.com/peterh/liner v1.2.1
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng=
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/peterh/liner v1.2.1 h1:O4BlKaq/LWu6VRWmol4ByWfzx6MfXc5Op5HETyIy5yg=
github.com/peterh/liner v1.2.1/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
Expand Down
40 changes: 0 additions & 40 deletions input.go

This file was deleted.

9 changes: 7 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ func main() {
"p",
false,
"panic on not implemented MOS calls")

readline := flag.Bool(
"r",
false,
"use readline like input with history")
roms := make([]*string, 16)
for i := 0; i < 16; i++ {
roms[i] = flag.String(
Expand All @@ -55,7 +58,9 @@ func main() {
(*traceMOS) || (*traceMOSFull),
*traceMOSFull,
*traceMemory,
*panicOnErr)
*panicOnErr,
*readline)
defer env.close()

env.mem.loadFirmware()

Expand Down
2 changes: 1 addition & 1 deletion osWord.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func execOSWORD(env *environment) {
line. C not equal to zero indicates that an escape condition terminated
entry. Y is set to the length of the line, excluding the CR if C=0.
*/
line, stop := env.in.readline()
line, stop := env.con.readline()
if stop {
env.stop = true
return
Expand Down
9 changes: 5 additions & 4 deletions vdu.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import "fmt"

type vdu struct {
con console
queue []uint8

mode uint8
mode uint8

// Mode 0-6
textColour uint8
Expand All @@ -25,7 +25,7 @@ type vdu struct {

var argsNeeded [256]int

func newVdu() *vdu {
func newVdu(con console) *vdu {
// Init args needed array, 0 for all except:
argsNeeded[1] = 1
argsNeeded[17] = 1
Expand All @@ -41,6 +41,7 @@ func newVdu() *vdu {
argsNeeded[31] = 2

var v vdu
v.con = con
// Mode 7 on startup
v.mode = 7
v.m7fgColour = 7 // white
Expand Down Expand Up @@ -478,7 +479,7 @@ func (v *vdu) writeInternal(cmd uint8, q []uint8) {
}

if out != "" && !v.ignore {
fmt.Print(out)
v.con.write(out)
}
}

Expand Down

0 comments on commit 68f4cdf

Please sign in to comment.