Merge pull request #52 from tjboldt/basic-extension

Basic extension
This commit is contained in:
Terence Boldt 2021-12-28 16:38:55 -05:00 committed by GitHub
commit 4eac3e2791
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 366 additions and 1 deletions

175
Apple2/RPi.Command.asm Normal file
View File

@ -0,0 +1,175 @@
.ORG $300
INBUF = $200 ;GETLN input buffer.
WAIT = $FCA8 ;Monitor wait routine.
BELL = $FF3A ;Monitor bell routine.
EXTRNCMD = $BE06 ;External cmd JMP vector.
XTRNADDR = $BE50 ;Ext cmd implementation addr.
XLEN = $BE52 ;length of command string-1.
XCNUM = $BE53 ;CI cmd no. (ext cmd - 0).
PBITS = $BE54 ;Command parameter bits.
XRETURN = $FF58 ;Known RTS instruction.
InputByte = $c0fe
OutputByte = $c0fd
InputFlags = $c0fb
OutputFlags = $c0f7
ReadBlockCommand = $01
WriteBlockCommand = $02
GetTimeCommand = $03
ChangeDriveCommand = $04
ExecCommand = $05
LoadFileCommand = $06
SaveFileCommand = $07
MenuCommand = $08
InputString = $fd67
PrintChar = $fded
Keyboard = $c000
ClearKeyboard = $c010
Wait = $fca8
;
; FIRST SAVE THE EXTERNAL COMMAND ADDRESS SO YOU WON'T
; DISCONNECT ANY PREVIOUSLY CONNECTED COMMAND.
;
LDA EXTRNCMD+1
STA NXTCMD
LDA EXTRNCMD+2
STA NXTCMD+1
;
LDA #<RPI ;Install the address of our
STA EXTRNCMD+1 ; command handler in the
LDA #>RPI ; external command JMP
STA EXTRNCMD+2 ; vector.
RTS
;
RPI: LDX #0 ;Check for our command.
NXTCHR: LDA INBUF,X ;Get first character.
ora #$20 ;Make it lower case
CMP CMD,X ;Does it match?
BNE NOTOURS ;No, back to CI.
INX ;Next character
CPX #CMDLEN ;All characters yet?
BNE NXTCHR ;No, read next one.
;
LDA #CMDLEN-1 ;Our cmd! Put cmd length-1
;lda #$8d
;sta $02ff
;lda #$fe
STA XLEN ; in CI global XLEN.
LDA #<XRETURN ;Point XTRNADDR to a known
STA XTRNADDR ; RTS since we'll handle
LDA #>XRETURN ; at the time we intercept
STA XTRNADDR+1 ; our command.
LDA #0 ;Mark the cmd number as
STA XCNUM ; zero (external).
STA PBITS ;And indicate no parameters
STA PBITS+1 ; to be parsed.
lda #$8d
jsr $fded
clc
bcc SendCommand
;
NOTOURS: SEC ; ALWAYS SET CARRY IF NOT YOUR
JMP (NXTCMD) ; CMD AND LET NEXT COMMAND TRY
; ; TO CLAIM IT.
SendCommand:
bit ClearKeyboard
lda #$05 ;send command 5 = exec
jsr SendByte
ldy #$03 ;skip over "RPI"
getInput:
lda $0200,y
cmp #$8d
beq sendNullTerminator
and #$7f
jsr SendByte
iny
bne getInput
sendNullTerminator:
lda #$00
jsr SendByte
DumpOutput:
jsr GetByte
bcs skipOutput
cmp #$00
beq endOutput
jsr PrintChar
skipOutput:
bit Keyboard ;check for keypress
bpl DumpOutput ;keep dumping output if no keypress
lda Keyboard ;send keypress to RPi
jsr PrintChar
and #$7f
jsr SendByte
bit ClearKeyboard
clc
bcc DumpOutput
endOutput:
clc
jmp (NXTCMD)
HelpCommand:
.byte "a2help",$00
SendByte:
pha
waitWrite:
lda InputFlags
rol
rol
bcs waitWrite
pla
sta OutputByte
lda #$1e ; set bit 0 low to indicate write started
sta OutputFlags
finishWrite:
lda InputFlags
rol
rol
bcc finishWrite
lda #$1f
sta OutputFlags
rts
GetByte:
lda #$1d ;set read flag low
sta OutputFlags
waitRead:
lda InputFlags
rol
bcc readByte
bit Keyboard ;keypress will abort waiting to read
bpl waitRead
lda #$1f ;set all flags high and exit
sta OutputFlags
sec ;failure
rts
readByte:
lda InputByte
pha
lda #$1f ;set all flags high
sta OutputFlags
finishRead:
lda InputFlags
rol
bcc finishRead
pla
clc ;success
rts
;macro for string with high-bit set
.macro aschi str
.repeat .strlen (str), c
.byte .strat (str, c) | $80
.endrep
.endmacro
CMD: aschi "rpi"
CMDLEN = 3 ;Our command length
;
NXTCMD: .byte 0,0 ; STORE THE NEXT EXT CMD'S
; ADDRESS HERE.

BIN
Apple2/RPi.Command.bin Normal file

Binary file not shown.

181
Apple2/RPi.Command.lst Normal file
View File

@ -0,0 +1,181 @@
ca65 V2.17 - Raspbian 2.17-1
Main file : RPi.Command.asm
Current file: RPi.Command.asm
000000r 1 .ORG $300
000300 1 INBUF = $200 ;GETLN input buffer.
000300 1 WAIT = $FCA8 ;Monitor wait routine.
000300 1 BELL = $FF3A ;Monitor bell routine.
000300 1 EXTRNCMD = $BE06 ;External cmd JMP vector.
000300 1 XTRNADDR = $BE50 ;Ext cmd implementation addr.
000300 1 XLEN = $BE52 ;length of command string-1.
000300 1 XCNUM = $BE53 ;CI cmd no. (ext cmd - 0).
000300 1 PBITS = $BE54 ;Command parameter bits.
000300 1 XRETURN = $FF58 ;Known RTS instruction.
000300 1 InputByte = $c0fe
000300 1 OutputByte = $c0fd
000300 1 InputFlags = $c0fb
000300 1 OutputFlags = $c0f7
000300 1
000300 1 ReadBlockCommand = $01
000300 1 WriteBlockCommand = $02
000300 1 GetTimeCommand = $03
000300 1 ChangeDriveCommand = $04
000300 1 ExecCommand = $05
000300 1 LoadFileCommand = $06
000300 1 SaveFileCommand = $07
000300 1 MenuCommand = $08
000300 1
000300 1 InputString = $fd67
000300 1 PrintChar = $fded
000300 1 Keyboard = $c000
000300 1 ClearKeyboard = $c010
000300 1 Wait = $fca8
000300 1
000300 1 ;
000300 1 ; FIRST SAVE THE EXTERNAL COMMAND ADDRESS SO YOU WON'T
000300 1 ; DISCONNECT ANY PREVIOUSLY CONNECTED COMMAND.
000300 1 ;
000300 1 AD 07 BE LDA EXTRNCMD+1
000303 1 8D E3 03 STA NXTCMD
000306 1 AD 08 BE LDA EXTRNCMD+2
000309 1 8D E4 03 STA NXTCMD+1
00030C 1 ;
00030C 1 A9 17 LDA #<RPI ;Install the address of our
00030E 1 8D 07 BE STA EXTRNCMD+1 ; command handler in the
000311 1 A9 03 LDA #>RPI ; external command JMP
000313 1 8D 08 BE STA EXTRNCMD+2 ; vector.
000316 1 60 RTS
000317 1 ;
000317 1 A2 00 RPI: LDX #0 ;Check for our command.
000319 1 BD 00 02 NXTCHR: LDA INBUF,X ;Get first character.
00031C 1 09 20 ora #$20 ;Make it lower case
00031E 1 DD E0 03 CMP CMD,X ;Does it match?
000321 1 D0 27 BNE NOTOURS ;No, back to CI.
000323 1 E8 INX ;Next character
000324 1 E0 03 CPX #CMDLEN ;All characters yet?
000326 1 D0 F1 BNE NXTCHR ;No, read next one.
000328 1 ;
000328 1 A9 02 LDA #CMDLEN-1 ;Our cmd! Put cmd length-1
00032A 1 ;lda #$8d
00032A 1 ;sta $02ff
00032A 1 ;lda #$fe
00032A 1 8D 52 BE STA XLEN ; in CI global XLEN.
00032D 1 A9 58 LDA #<XRETURN ;Point XTRNADDR to a known
00032F 1 8D 50 BE STA XTRNADDR ; RTS since we'll handle
000332 1 A9 FF LDA #>XRETURN ; at the time we intercept
000334 1
000334 1 8D 51 BE STA XTRNADDR+1 ; our command.
000337 1 A9 00 LDA #0 ;Mark the cmd number as
000339 1 8D 53 BE STA XCNUM ; zero (external).
00033C 1 8D 54 BE STA PBITS ;And indicate no parameters
00033F 1 8D 55 BE STA PBITS+1 ; to be parsed.
000342 1 A9 8D lda #$8d
000344 1 20 ED FD jsr $fded
000347 1 18 clc
000348 1 90 04 bcc SendCommand
00034A 1 ;
00034A 1 38 NOTOURS: SEC ; ALWAYS SET CARRY IF NOT YOUR
00034B 1 6C E3 03 JMP (NXTCMD) ; CMD AND LET NEXT COMMAND TRY
00034E 1 ; ; TO CLAIM IT.
00034E 1
00034E 1 SendCommand:
00034E 1 2C 10 C0 bit ClearKeyboard
000351 1 A9 05 lda #$05 ;send command 5 = exec
000353 1 20 99 03 jsr SendByte
000356 1 A0 03 ldy #$03 ;skip over "RPI"
000358 1 getInput:
000358 1 B9 00 02 lda $0200,y
00035B 1 C9 8D cmp #$8d
00035D 1 F0 08 beq sendNullTerminator
00035F 1 29 7F and #$7f
000361 1 20 99 03 jsr SendByte
000364 1 C8 iny
000365 1 D0 F1 bne getInput
000367 1 sendNullTerminator:
000367 1 A9 00 lda #$00
000369 1 20 99 03 jsr SendByte
00036C 1 DumpOutput:
00036C 1 20 B7 03 jsr GetByte
00036F 1 B0 07 bcs skipOutput
000371 1 C9 00 cmp #$00
000373 1 F0 19 beq endOutput
000375 1 20 ED FD jsr PrintChar
000378 1 skipOutput:
000378 1 2C 00 C0 bit Keyboard ;check for keypress
00037B 1 10 EF bpl DumpOutput ;keep dumping output if no keypress
00037D 1 AD 00 C0 lda Keyboard ;send keypress to RPi
000380 1 20 ED FD jsr PrintChar
000383 1 29 7F and #$7f
000385 1 20 99 03 jsr SendByte
000388 1 2C 10 C0 bit ClearKeyboard
00038B 1 18 clc
00038C 1 90 DE bcc DumpOutput
00038E 1 endOutput:
00038E 1 18 clc
00038F 1 6C E3 03 jmp (NXTCMD)
000392 1
000392 1 HelpCommand:
000392 1 61 32 68 65 .byte "a2help",$00
000396 1 6C 70 00
000399 1
000399 1 SendByte:
000399 1 48 pha
00039A 1 waitWrite:
00039A 1 AD FB C0 lda InputFlags
00039D 1 2A rol
00039E 1 2A rol
00039F 1 B0 F9 bcs waitWrite
0003A1 1 68 pla
0003A2 1 8D FD C0 sta OutputByte
0003A5 1 A9 1E lda #$1e ; set bit 0 low to indicate write started
0003A7 1 8D F7 C0 sta OutputFlags
0003AA 1 finishWrite:
0003AA 1 AD FB C0 lda InputFlags
0003AD 1 2A rol
0003AE 1 2A rol
0003AF 1 90 F9 bcc finishWrite
0003B1 1 A9 1F lda #$1f
0003B3 1 8D F7 C0 sta OutputFlags
0003B6 1 60 rts
0003B7 1
0003B7 1 GetByte:
0003B7 1 A9 1D lda #$1d ;set read flag low
0003B9 1 8D F7 C0 sta OutputFlags
0003BC 1 waitRead:
0003BC 1 AD FB C0 lda InputFlags
0003BF 1 2A rol
0003C0 1 90 0C bcc readByte
0003C2 1 2C 00 C0 bit Keyboard ;keypress will abort waiting to read
0003C5 1 10 F5 bpl waitRead
0003C7 1 A9 1F lda #$1f ;set all flags high and exit
0003C9 1 8D F7 C0 sta OutputFlags
0003CC 1 38 sec ;failure
0003CD 1 60 rts
0003CE 1 readByte:
0003CE 1 AD FE C0 lda InputByte
0003D1 1 48 pha
0003D2 1 A9 1F lda #$1f ;set all flags high
0003D4 1 8D F7 C0 sta OutputFlags
0003D7 1 finishRead:
0003D7 1 AD FB C0 lda InputFlags
0003DA 1 2A rol
0003DB 1 90 FA bcc finishRead
0003DD 1 68 pla
0003DE 1 18 clc ;success
0003DF 1 60 rts
0003E0 1
0003E0 1
0003E0 1 ;macro for string with high-bit set
0003E0 1 .macro aschi str
0003E0 1 .repeat .strlen (str), c
0003E0 1 .byte .strat (str, c) | $80
0003E0 1 .endrep
0003E0 1 .endmacro
0003E0 1
0003E0 1 F2 F0 E9 CMD: aschi "rpi"
0003E3 1 CMDLEN = 3 ;Our command length
0003E3 1 ;
0003E3 1 00 00 NXTCMD: .byte 0,0 ; STORE THE NEXT EXT CMD'S
0003E5 1 ; ADDRESS HERE.
0003E5 1

View File

@ -46,6 +46,9 @@ DriveFirmware.bin CommandFirmware.bin FileAccessFirmware.bin MenuFirmware.bin \
ca65 Shell.asm -o Shell.o --listing Shell.lst || exit 1
ld65 Shell.o -o Shell.bin -C ../.cicd/none.cfg || exit 1
ca65 RPi.Command.asm -o RPi.Command.o --listing RPi.Command.lst || exit 1
ld65 RPi.Command.o -o RPi.Command.bin -C ../.cicd/none.cfg || exit 1
rm ./*.o
rm DriveFirmware.bin
rm MenuFirmware.bin
@ -54,4 +57,5 @@ rm FileAccessFirmware.bin
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i AT28C64B.bin -p /APPLE2.IO.RPI/AT28C64B.BIN || exit 1
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i Shell.bin -p /APPLE2.IO.RPI/SHELL || exit 1
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i RPi.Command.bin -p /APPLE2.IO.RPI/RPI.COMMAND -a 0x0300 || exit 1
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c ls

View File

@ -16,10 +16,11 @@ So far, this is a project and not a finished product. The current prototype is o
4. Load binary files directly from the RPi to the II
5. Update Apple II firmware in place from image on RPi
6. Supports two drive images at the same time (Note: backward compatible with previous firmware but requires firmware update in order to work with two drives)
7. Supports "RPI" command from BASIC to execute Linux commands from the command prompt or inside BASIC programs: `10 PRINT CHR$(4);"RPI ls -al /"`
## Roadmap
1. Extend BASIC.SYSTEM commands
1. RPI - Execute a single Linux command
1. RPI - Execute a single Linux command (DONE)
2. SH - Open a Linux shell
3. WGET - Download and save to file
2. Shell improvements

Binary file not shown.

View File

@ -31,6 +31,10 @@ func ExecCommand() {
if forceLowercase {
linuxCommand = strings.ToLower(linuxCommand)
}
linuxCommand = strings.Trim(linuxCommand, " ")
if linuxCommand == "" {
linuxCommand = "a2help"
}
fmt.Printf("Command to run: %s\n", linuxCommand)
if strings.HasPrefix(linuxCommand, "cd ") {
workingDirectory = strings.Replace(linuxCommand, "cd ", "", 1)