Compare commits

...

8 Commits

Author SHA1 Message Date
Terence Boldt 8b04a0e926
Add clock driver, remove from firmware (#168) 2024-04-18 14:23:22 -04:00
Terence Boldt 1336371b49 Update setup.sh 2024-04-02 14:56:42 -04:00
Terence Boldt 7bc130582d Fix build script 2024-03-29 12:13:39 -04:00
Terence Boldt 0f58e987f1 Update setup and instructions 2024-03-29 12:13:39 -04:00
Terence Boldt de156de730 Fix Pico build 2024-03-29 12:13:39 -04:00
Oliver Schmidt 3441a73d9d Remove useless port mirrors. 2024-02-10 09:01:05 -05:00
Oliver Schmidt ab601d0897 Adjust AT28C64B.bin path. 2024-02-10 09:01:05 -05:00
Terence Boldt aa5910cee8
Initial Pico hardware support
* Added assemble.cmd for Windows.

In the long run, some (c)make-based cross-plafrom solution seems preferable.

* Fill up the menu page just like the other pages.

* Allow to assemble for different hardware types.

The first script parameter is used to set the ca65 symbol HW_TYPE. Without parameter, HW_TYPE is set to 0.

* Avoid unwanted i/o access.

Depending on the 6502, LDA addr,X and/or STA addr,X produce additional phantom reads. In order to avoid those phantom reads to do i/o access, I used the "classic" approach of moving those reads from page $C0 to page $BF.

* Made use of BIT instruction to access InputFlags from firmware.

Doing the same for access from disk-based software would require selfmodifying code as there's not bit <addr>,x instruction.

* Removed push/pop from GetByte.

After the replacing the rol instructions with bit instructions with a recent chnage, the only reason left to save a to the stack was setting the OutputFlags. But that can be done using x.

* Added InputFlags check for consistency.

* Added support for an alternative hardware type.

The new hardware type has simple UART-type interface. Beside the two data registers, there are only the two bits to indicate readability and writability of the data registers.

* Added another comminucation interface implementation.

Use ACM CDC (or another proprietary) USB serial device for communication.

Currently VID / PID of a Raspberry Pi Pico SDK CDC UART are hardcoded - see https://github.com/raspberrypi/usb-pid

* Revert "Avoid unwanted i/o access."

Neither the original hardware type nor the alternative hardware type have any read and write i/o port share addresses. Therefore phantom reads aren't an issue with those hardware types.

This reverts commit ae5cb754fb.

* Adapt to the different error signatures on Linux.

So far the code was only tested on Windows.

* Added implementation of the alternative hardware type.

The implemenation is based on a Raspberry Pi Pico - see https://github.com/a2retrosystems/A2retroNET

The new hardware type has a simple UART-type interface. Beside the two data registers, there are only the two bits to indicate readability and writability of the data registers.

* Modify the HD image for the alternative hardware type.

It is likely desirable to have two HD images for the two hardware types. And likely the apple2driver program should default to the right one based on its protocol setting. BUt given that the HD image(s) shouldn't be part of the actual Git repo anyhow, I don't do anything about this here and now.

* Fixed shell startup (?)

At least on the alternative hardware, this "blindly sending" a reset command causes the shell to be terminated right away:
The driver acknowldges the reset command with a zero byte - and that byte ends up being read by DumpOutput causing it to branch to endOutput.

Maybe that sending a reset command is beneficial on the original hardware. Then another .if is required. Or DumpOutput shouldn't quit on reading a zero byte - the shell handler doesn't seem to send it on purpose(?)

* Upate HD image with recent shell change.

* Fix shell shutdown (?)

At least on the alternative hardware, things happen this way:
1. The shell 'exit' command has ptyOut signal outputComplete and terminate. At this point, ptyIn is still blocked up to one second in ReadCharacter - and can therefore not react on outputComplete.
2. The outputComplete handler in ShellCommand sends a zero byte. This makes on the A2 DumpOutput return and the caller send a zero byte. ShellCommand must not return here as ptyIn is still blocked.
3. The zero byte from the A2 has ptyIn return from ReadCharacter, signal userCancelled and terminate.
4. ShellCommand can now return, but it must not send a zero byte, as the A2 is not expecting it - and will therefore later misinterpret it.

Maybe the original hardware needs another handling, then differentiation of behavior in shell.go becomes necessary.

* Moved boot text out of IIgs copyright message area.

Having the boot text start at the left border of the third line makes it look nice on the cold boot screen of all Apple II's - and there's where the user sees it for some time while waiting for the RPi to come up.

* Several adjustements:

- Get latest Go version as of now.
- Nowadays (?) GitHub 'git clone' seems to only work with a GitHub account. Therefore the zip download workaround. The becomes hopefully unnecessary soon with Go module magic.
- Use 'go mod tidy' to update .sum file for now.
- Error handling for an empty drive 2 is currently not exactly great, so download Total Replay for drive 2. Unfortunately there's no stable URL as of now.
- Use $USER and $HOME instead of hardcoded values.
- Removed deprecated syslog output directives.

* Added brief fork description.

* Added ProDOS-Utilities reference.

* Reverted back to using 'git clone'.

I've no idea why git acted up the other day :-( Now, everything is back to normal...

* Ignore Pico build directory.

* Updated from https://github.com/a2retrosystems/A2retroNET

* Updated from https://github.com/a2retrosystems/A2retroNET

At this point, nothing at all is done on an A2 reset. This can likely be improved. However, Apple2-IO-RPi doesn't seem to handle A2 reset exactly gracefully anyhow.

In general, it seems desirable to introduce some simple framing protocol - like SLIP - that allows to recover from an A2 reset in the middle of an Apple2-IO-RPi command execution.

Such a framing protocol would allow to introduce different frame types. One frame type could then be an A2 reset frame sent by the A2retroNET firmware.

* Make use of brand new stable Total Replay download URL.

Thanks to 4am :-)

* Fixed typos.

* Clone upstream ProDOS-Utilities.

My ProDOS-Utilities pull request was merged.

* Added support for boards without LED.

* Updated link.

* Adjusted to the current A2retroNET hardware.

* Removed support for the Pico W.

* Updated URL.

* Updated URL.

* Make use A2Pico library.

* Added link to A2Pico.

* Remove intermediates from repo.

* Build intermediates from Pico build.

* Have LED reflect status of logic ACM connection.

* Update upstream repo references.

* Adjust build instructions.

* Update README.md

* Fix build and update dependencies

* Fix binary comparison

* Fix firware bug on classic hardware

---------

Co-authored-by: Oliver Schmidt <ol.sc@web.de>
2024-02-05 22:49:09 -05:00
42 changed files with 1327 additions and 1833 deletions

View File

@ -22,15 +22,10 @@ body:
label: Hardware Version
description: What version of the hardware are you running?
options:
- Sixth Prototype (Purchased from Terence)
- Sixth Prototype (Self-assembled)
- Sixth Prototype (Purchased from third party)
- Fifth Prototype (Purchased from Terence)
- Fifth Prototype (Self-assembled)
- Fifth Prototype (Purchased from third party)
- Fourth Prototype (Purchased from Terence)
- Fourth Prototype (Self-assembled)
- Fourth Prototype (Purchased from third party)
- RPi Pico
- Sixth Prototype (lastest classic hardware)
- Fifth Prototype (classic hardware without jumper)
- Fourth Prototype (classic hardware with EPROM)
validations:
required: true
- type: dropdown
@ -39,6 +34,8 @@ body:
label: Firmware Version
description: What version of the firmware are you running? (shown on boot screen)
options:
- 8010 (initial RPi Pico hardware)
- 0010 (classic hardware)
- 000F
- Older (not shown on boot, pre-2022-Feb-07)
validations:
@ -49,6 +46,7 @@ body:
label: Driver Version
description: What version of the driver are you running? Check with `RPI a2version`
options:
- 002D (add support for RPi Pico hardware)
- 002C (fix nano editor)
- 002B (fix keyboard delay)
- 002A (reduce CPU usage)
@ -69,6 +67,8 @@ body:
label: Shell Version
description: What version of the shell are you running?`
options:
- 800F (initial RPi Pico support)
- 000F (classic hardware support)
- 000E (fix hang on exit)
- 000D (added version info)
- Older (pre-2022-Mar-01)

13
.gitignore vendored
View File

@ -1,6 +1,19 @@
*-bak
*.o
*.DS_Store
*.bin
*.lst
RaspberryPi/apple2driver/apple2driver
RaspberryPi/Apple2-IO-RPi.log
RaspberryPiPico/build/
Hardware/Apple2IORPi-backups/
RaspberryPiPico/Apple2-IO-RPi.*
RaspberryPiPico/CMakeCache.txt
RaspberryPiPico/CMakeFiles/
RaspberryPiPico/Makefile
RaspberryPiPico/_deps/
RaspberryPiPico/cmake_install.cmake
RaspberryPiPico/elf2uf2/
RaspberryPiPico/generated/
RaspberryPiPico/pico-sdk/
RaspberryPiPico/pioasm/

140
Apple2/Clock.Driver.asm Normal file
View File

@ -0,0 +1,140 @@
; Copyright Terence J. Boldt (c)2024
; Use of this source code is governed by an MIT
; license that can be found in the LICENSE file.
; This file contains the source for the clock
; driver for the Apple2-IO-RPi
EnableWriteLang = $C08B
DisableWriteLang = $C082
ProdosJump = $BF06
ProdosClockCode = $BF07
ProdosMachineId = $BF98
PrintChar = $FDED
PrintHex = $FDE3
PrintByte = $FDDA
GetTimeCommand = $03
.org $2000
; Find Apple2-IO-RPi card
ldx #$06
ldy #$09
CheckIdBytes:
lda $C700,y ; !! Self modifying code
cmp IdBytes,y
bne NextCard
dey
bne CheckIdBytes
jmp FoundCard
NextCard:
dec CheckIdBytes+2
ldy #$09
dex
bne CheckIdBytes
CardNotFound:
ldy #$00
PrintCardNotFound:
lda TextCardNotFound,y
beq Failed
ora #$80
jsr PrintChar
iny
bne PrintCardNotFound
Failed:
rts
FoundCard:
ldy #$00
PrintCardFound:
lda TextCardFound,y
beq PrintCardNumber
ora #$80
jsr PrintChar
iny
bne PrintCardFound
PrintCardNumber:
inx
txa
jsr PrintHex
lda #$8D
jsr PrintChar
; Change driver code to point to the card
txa
ora #$C0
sta GetByte+2
sta SendByte+2
; Change destination to be ProDOS clock code location
lda ProdosClockCode
sta DriverDestination+1
lda ProdosClockCode+1
sta DriverDestination+2
; Changing RTS to JMP enables clock driver
lda #$4C ; jump instruction
sta ProdosJump
; Enable writing to language card RAM
; by triggering switch twice
lda EnableWriteLang
lda EnableWriteLang
; write driver code to language card RAM
ldy #$00
WriteDriver:
lda Driver,y
DriverDestination:
sta $D742,y ; !! this address gets modified above
iny
cpy #EndDriver-Driver+2
bne WriteDriver
; Disable writing to language card RAM
lda DisableWriteLang
; Update ProDOS Machine ID to mark clock as enabled
lda ProdosMachineId
ora #$01
sta ProdosMachineId
ldy #$00
PrintFinished:
lda TextDriverInstalled,y
beq Finished
ora #$80
jsr PrintChar
iny
bne PrintFinished
Finished:
rts
IdBytes:
.byte $E0,$20,$E0,$00,$E0,$03,$E0,$3C,$A9,$3F
TextCardFound:
.byte "Found Apple2-IO-RPi in slot ",$00
TextCardNotFound:
.byte "Apple2-IO-RPi not found",$8D,$00
TextDriverInstalled:
.byte "Apple2-IO-RPi Clock driver version 0001",$8D,$00
Driver:
lda #GetTimeCommand
SendByte:
jsr $C749 ; !! address gets modified on installation
ldy #$00
getTimeByte:
GetByte:
jsr $C743 ; !! address gets modified on installation
sta $bf90,y
iny
cpy #$04
bne getTimeByte
EndDriver:
rts

View File

@ -2,8 +2,9 @@
; Use of this source code is governed by an MIT
; license that can be found in the LICENSE file.
; This file contains the source for the firmware
; that was formerly used to act as a pseudo-shell
; This file formerly contained the source for the
; firmware that had a pseudo command prompt
; but is now empty except required common bytes
;ProDOS Zero Page
Command = $42 ;ProDOS Command
@ -32,144 +33,41 @@ LoadFileCommand = $06
SaveFileCommand = $07
MenuCommand = $08
InputString = $fd67
PrintChar = $fded
Keyboard = $c000
ClearKeyboard = $c010
Wait = $fca8
.org SLOT*$100 + $C000
;ID bytes for booting and drive detection
cpx #$20 ;ID bytes for ProDOS and the
cpx #$00 ; Apple Autostart ROM
cpx #$20 ;ID bytes for ProDOS
cpx #$00 ;
cpx #$03 ;
cpx #$3C ;ID byte for Autostart ROM
ldx #SLOT*$10
stx $2b
stx Unit
;force EPROM to second page on boot
lda #$3f ;set all flags high and page 3 of EPROM for menu
jmp PageJump
;The following bytes must exist in this location for Pascal communications
;as they are standard pointers for entry points
.byte CommInit&$00FF ;low byte of rts for init of Pascal comms
.byte $43 ; low byte of read for Pascal comms
.byte $49 ; low byte of write for Pascal comms
.byte $4F ; low byte of rts for status of Pascal comms
CommInit:
lda #$0f ; set all flags high and page 0 for comm driver
sta OutputFlags
ldx #$00 ; set error code to 0 for success
rts
PageJump:
sta OutputFlags
jmp Start ;this jump is only called if coming in from PageJump with A=$2f
jmp Start ;this jump is only called if coming in from PageJump with A=$0f
;entry points for ProDOS
DriverEntry:
lda #$0f ;set all flags high and page 0 of EPROM
sta OutputFlags
jmp Start ; this is never called as the EPROM page changes
;load first two blocks and execute to boot
Start:
jsr $c300 ;enable 80 columns
lda #$05 ;execute command
jsr SendByte
ldy #$00
sendHelp:
lda HelpCommand,y
beq endSendHelp
jsr SendByte
iny
bne sendHelp
endSendHelp:
lda #$00
jsr SendByte
jsr DumpOutput
lda $33
pha
lda #$a4
sta $33
GetCommand:
jsr InputString
lda $0200
cmp #$8d ;skip when return found
beq GetCommand
jsr SendCommand
clc
bcc GetCommand
SendCommand:
bit ClearKeyboard
lda #$05 ;send command 5 = exec
jsr SendByte
ldy #$00
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:
rts
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
end:
rts
@ -178,5 +76,6 @@ end:
.endrepeat
.byte 0,0 ;0000 blocks = check status
.byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
.byte 23 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
.byte DriverEntry&$00FF ;low byte of entry

View File

@ -1,195 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : CommandFirmware.asm
Current file: CommandFirmware.asm
000000r 1 ; Copyright Terence J. Boldt (c)2020-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the firmware
000000r 1 ; that was formerly used to act as a pseudo-shell
000000r 1
000000r 1 ;ProDOS Zero Page
000000r 1 Command = $42 ;ProDOS Command
000000r 1 Unit = $43 ;ProDOS unit (SDDD0000)
000000r 1 BufferLo = $44
000000r 1 BufferHi = $45
000000r 1 BlockLo = $46
000000r 1 BlockHi = $47
000000r 1
000000r 1 ; ProDOS Error Codes
000000r 1 IOError = $27
000000r 1 NoDevice = $28
000000r 1 WriteProtect = $2B
000000r 1
000000r 1 InputByte = $c08e+SLOT*$10
000000r 1 OutputByte = $c08d+SLOT*$10
000000r 1 InputFlags = $c08b+SLOT*$10
000000r 1 OutputFlags = $c087+SLOT*$10
000000r 1
000000r 1 ReadBlockCommand = $01
000000r 1 WriteBlockCommand = $02
000000r 1 GetTimeCommand = $03
000000r 1 ChangeDriveCommand = $04
000000r 1 ExecCommand = $05
000000r 1 LoadFileCommand = $06
000000r 1 SaveFileCommand = $07
000000r 1 MenuCommand = $08
000000r 1
000000r 1 InputString = $fd67
000000r 1 PrintChar = $fded
000000r 1 Keyboard = $c000
000000r 1 ClearKeyboard = $c010
000000r 1 Wait = $fca8
000000r 1
000000r 1 .org SLOT*$100 + $C000
00C700 1 ;ID bytes for booting and drive detection
00C700 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the
00C702 1 E0 00 cpx #$00 ; Apple Autostart ROM
00C704 1 E0 03 cpx #$03 ;
00C706 1
00C706 1 A2 70 ldx #SLOT*$10
00C708 1 86 2B stx $2b
00C70A 1 86 43 stx Unit
00C70C 1
00C70C 1 ;force EPROM to second page on boot
00C70C 1 A9 3F lda #$3f ;set all flags high and page 3 of EPROM for menu
00C70E 1 PageJump:
00C70E 1 8D F7 C0 sta OutputFlags
00C711 1 4C 19 C7 jmp Start ;this jump is only called if coming in from PageJump with A=$2f
00C714 1
00C714 1 ;entry points for ProDOS
00C714 1 DriverEntry:
00C714 1 A9 0F lda #$0f ;set all flags high and page 0 of EPROM
00C716 1 8D F7 C0 sta OutputFlags
00C719 1
00C719 1 Start:
00C719 1 20 00 C3 jsr $c300 ;enable 80 columns
00C71C 1 A9 05 lda #$05 ;execute command
00C71E 1 20 95 C7 jsr SendByte
00C721 1 A0 00 ldy #$00
00C723 1 sendHelp:
00C723 1 B9 8E C7 lda HelpCommand,y
00C726 1 F0 06 beq endSendHelp
00C728 1 20 95 C7 jsr SendByte
00C72B 1 C8 iny
00C72C 1 D0 F5 bne sendHelp
00C72E 1 endSendHelp:
00C72E 1 A9 00 lda #$00
00C730 1 20 95 C7 jsr SendByte
00C733 1 20 6B C7 jsr DumpOutput
00C736 1
00C736 1 A5 33 lda $33
00C738 1 48 pha
00C739 1 A9 A4 lda #$a4
00C73B 1 85 33 sta $33
00C73D 1 GetCommand:
00C73D 1 20 67 FD jsr InputString
00C740 1 AD 00 02 lda $0200
00C743 1 C9 8D cmp #$8d ;skip when return found
00C745 1 F0 F6 beq GetCommand
00C747 1 20 4D C7 jsr SendCommand
00C74A 1 18 clc
00C74B 1 90 F0 bcc GetCommand
00C74D 1
00C74D 1 SendCommand:
00C74D 1 2C 10 C0 bit ClearKeyboard
00C750 1 A9 05 lda #$05 ;send command 5 = exec
00C752 1 20 95 C7 jsr SendByte
00C755 1 A0 00 ldy #$00
00C757 1 getInput:
00C757 1 B9 00 02 lda $0200,y
00C75A 1 C9 8D cmp #$8d
00C75C 1 F0 08 beq sendNullTerminator
00C75E 1 29 7F and #$7f
00C760 1 20 95 C7 jsr SendByte
00C763 1 C8 iny
00C764 1 D0 F1 bne getInput
00C766 1 sendNullTerminator:
00C766 1 A9 00 lda #$00
00C768 1 20 95 C7 jsr SendByte
00C76B 1 DumpOutput:
00C76B 1 20 B3 C7 jsr GetByte
00C76E 1 B0 07 bcs skipOutput
00C770 1 C9 00 cmp #$00
00C772 1 F0 19 beq endOutput
00C774 1 20 ED FD jsr PrintChar
00C777 1 skipOutput:
00C777 1 2C 00 C0 bit Keyboard ;check for keypress
00C77A 1 10 EF bpl DumpOutput ;keep dumping output if no keypress
00C77C 1 AD 00 C0 lda Keyboard ;send keypress to RPi
00C77F 1 20 ED FD jsr PrintChar
00C782 1 29 7F and #$7f
00C784 1 20 95 C7 jsr SendByte
00C787 1 2C 10 C0 bit ClearKeyboard
00C78A 1 18 clc
00C78B 1 90 DE bcc DumpOutput
00C78D 1 endOutput:
00C78D 1 60 rts
00C78E 1
00C78E 1 HelpCommand:
00C78E 1 61 32 68 65 .byte "a2help",$00
00C792 1 6C 70 00
00C795 1
00C795 1 SendByte:
00C795 1 48 pha
00C796 1 waitWrite:
00C796 1 AD FB C0 lda InputFlags
00C799 1 2A rol
00C79A 1 2A rol
00C79B 1 B0 F9 bcs waitWrite
00C79D 1 68 pla
00C79E 1 8D FD C0 sta OutputByte
00C7A1 1 A9 1E lda #$1e ; set bit 0 low to indicate write started
00C7A3 1 8D F7 C0 sta OutputFlags
00C7A6 1 finishWrite:
00C7A6 1 AD FB C0 lda InputFlags
00C7A9 1 2A rol
00C7AA 1 2A rol
00C7AB 1 90 F9 bcc finishWrite
00C7AD 1 A9 1F lda #$1f
00C7AF 1 8D F7 C0 sta OutputFlags
00C7B2 1 60 rts
00C7B3 1
00C7B3 1 GetByte:
00C7B3 1 A9 1D lda #$1d ;set read flag low
00C7B5 1 8D F7 C0 sta OutputFlags
00C7B8 1 waitRead:
00C7B8 1 AD FB C0 lda InputFlags
00C7BB 1 2A rol
00C7BC 1 90 0C bcc readByte
00C7BE 1 2C 00 C0 bit Keyboard ;keypress will abort waiting to read
00C7C1 1 10 F5 bpl waitRead
00C7C3 1 A9 1F lda #$1f ;set all flags high and exit
00C7C5 1 8D F7 C0 sta OutputFlags
00C7C8 1 38 sec ;failure
00C7C9 1 60 rts
00C7CA 1 readByte:
00C7CA 1 AD FE C0 lda InputByte
00C7CD 1 48 pha
00C7CE 1 A9 1F lda #$1f ;set all flags high
00C7D0 1 8D F7 C0 sta OutputFlags
00C7D3 1 finishRead:
00C7D3 1 AD FB C0 lda InputFlags
00C7D6 1 2A rol
00C7D7 1 90 FA bcc finishRead
00C7D9 1 68 pla
00C7DA 1 18 clc ;success
00C7DB 1 end:
00C7DB 1 60 rts
00C7DC 1
00C7DC 1 00 00 00 00 .repeat 251-<end
00C7E0 1 00 00 00 00
00C7E4 1 00 00 00 00
00C7E8 1 00 00 00 00
00C7EC 1 00 00 00 00
00C7F0 1 00 00 00 00
00C7F4 1 00 00 00 00
00C7F8 1 00 00 00 00
00C7FC 1 .byte 0
00C7FC 1 .endrepeat
00C7FC 1
00C7FC 1 00 00 .byte 0,0 ;0000 blocks = check status
00C7FE 1 07 .byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
00C7FF 1 14 .byte DriverEntry&$00FF ;low byte of entry
00C7FF 1

View File

@ -36,16 +36,27 @@ MenuCommand = $08
.org SLOT*$100 + $C000
;ID bytes for booting and drive detection
cpx #$20 ;ID bytes for ProDOS and the
cpx #$00 ; Apple Autostart ROM
cpx #$20 ;ID bytes for ProDOS
cpx #$00 ;
cpx #$03 ;
cpx #$3C ;ID byte for Autostart ROM
ldx #SLOT*$10
stx $2b
stx Unit
;force EPROM to second page on boot
lda #$3f ;set all flags high and page 3 of EPROM for menu
jmp PageJump
;The following bytes must exist in this location for Pascal communications
;as they are standard pointers for entry points
.byte CommInit&$00FF ;low byte of rts for init of Pascal comms
.byte CommRead&$00FF ; low byte of read for Pascal comms
.byte CommWrite&$00FF ; low byte of write for Pascal comms
.byte CommStatus&$00FF ; low byte of rts for status of Pascal comms
CommInit:
lda #$0f ; set all flags high and page 0 for comm driver
sta OutputFlags
ldx #$00 ; set error code to 0 for success
rts
PageJump:
sta OutputFlags
jmp Start ;this jump is only called if coming in from PageJump with A=$0f
@ -58,6 +69,10 @@ DriverEntry:
;load first two blocks and execute to boot
Start:
ldx #SLOT*$10
stx $2b
stx Unit
lda #$01 ;set read command
sta Command
@ -71,6 +86,21 @@ Start:
jmp $801 ;execute the block
CommRead:
jsr GetByte
ldx #$00 ; clear error code
rts
CommWrite:
jsr SendByte
ldx #$00 ; clear error code
rts
CommStatus:
ldx #$00 ; clear error code
sec ; set carry to indicate ready to read or write
rts
; ProDOS Driver code
; First check that this is the right drive
Driver:
@ -78,7 +108,7 @@ Driver:
lda Command; Check which command is being requested
beq GetStatus ;0 = Status command
cmp #ReadBlockCommand
beq ReadBlockAndSetTime
beq ReadBlock
cmp #WriteBlockCommand
beq WriteBlock
sec ;set carry as we don't support any other commands
@ -94,22 +124,7 @@ GetStatus:
rts
; ProDOS Read Block Command
ReadBlockAndSetTime:
lda BlockHi ; only get the time if block 0002
bne readBlock
lda BlockLo
cmp #$02
bne readBlock
ldy #$00 ;Get the current time on each block read for now
lda #GetTimeCommand
jsr SendByte
getTimeByte:
jsr GetByte
sta $bf90,y
iny
cpy #$04
bne getTimeByte
readBlock:
ReadBlock:
lda #ReadBlockCommand ;read the block after setting the clock
jsr SendByte
lda BlockLo
@ -161,41 +176,38 @@ write256:
rts
SendByte:
pha
waitWrite:
lda InputFlags
rol
rol
bcs waitWrite
pla
bit InputFlags
bvs SendByte
sta OutputByte
.if HW_TYPE = 0
lda #$0e ; set bit 0 low to indicate write started
sta OutputFlags
finishWrite:
lda InputFlags
rol
rol
bcc finishWrite
bit InputFlags
bvc finishWrite
lda #$0f
sta OutputFlags
.endif
rts
GetByte:
.if HW_TYPE = 0
lda #$0d ;set read flag low
sta OutputFlags
.endif
waitRead:
lda InputFlags
rol
bcs waitRead
bit InputFlags
bmi waitRead
lda InputByte
.if HW_TYPE = 0
pha
lda #$0f ;set all flags high
sta OutputFlags
finishRead:
lda InputFlags
rol
bcc finishRead
bit InputFlags
bpl finishRead
pla
.endif
end:
rts

View File

@ -1,214 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : DriveFirmware.asm
Current file: DriveFirmware.asm
000000r 1 ; Copyright Terence J. Boldt (c)2020-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the firmware
000000r 1 ; that allows the Apple II to boot from the card
000000r 1 ; and for ProDOS to recognize the card as two
000000r 1 ; hard drivers
000000r 1
000000r 1 ;ProDOS Zero Page
000000r 1 Command = $42 ;ProDOS Command
000000r 1 Unit = $43 ;ProDOS unit (SDDD0000)
000000r 1 BufferLo = $44
000000r 1 BufferHi = $45
000000r 1 BlockLo = $46
000000r 1 BlockHi = $47
000000r 1
000000r 1 ; ProDOS Error Codes
000000r 1 IOError = $27
000000r 1 NoDevice = $28
000000r 1 WriteProtect = $2B
000000r 1
000000r 1 InputByte = $c08e+SLOT*$10
000000r 1 OutputByte = $c08d+SLOT*$10
000000r 1 InputFlags = $c08b+SLOT*$10
000000r 1 OutputFlags = $c087+SLOT*$10
000000r 1
000000r 1 ReadBlockCommand = $01
000000r 1 WriteBlockCommand = $02
000000r 1 GetTimeCommand = $03
000000r 1 ChangeDriveCommand = $04
000000r 1 ExecCommand = $05
000000r 1 LoadFileCommand = $06
000000r 1 SaveFileCommand = $07
000000r 1 MenuCommand = $08
000000r 1
000000r 1 .org SLOT*$100 + $C000
00C700 1 ;ID bytes for booting and drive detection
00C700 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the
00C702 1 E0 00 cpx #$00 ; Apple Autostart ROM
00C704 1 E0 03 cpx #$03 ;
00C706 1
00C706 1 A2 70 ldx #SLOT*$10
00C708 1 86 2B stx $2b
00C70A 1 86 43 stx Unit
00C70C 1
00C70C 1 ;force EPROM to second page on boot
00C70C 1 A9 3F lda #$3f ;set all flags high and page 3 of EPROM for menu
00C70E 1 PageJump:
00C70E 1 8D F7 C0 sta OutputFlags
00C711 1 4C 1C C7 jmp Start ;this jump is only called if coming in from PageJump with A=$0f
00C714 1
00C714 1 ;entry points for ProDOS
00C714 1 DriverEntry:
00C714 1 A9 0F lda #$0f ;set all flags high and page 0 of EPROM
00C716 1 8D F7 C0 sta OutputFlags
00C719 1 4C 32 C7 jmp Driver
00C71C 1
00C71C 1 ;load first two blocks and execute to boot
00C71C 1 Start:
00C71C 1 A9 01 lda #$01 ;set read command
00C71E 1 85 42 sta Command
00C720 1
00C720 1 A9 00 lda #$00 ;block 0
00C722 1 85 46 sta BlockLo
00C724 1 85 47 sta BlockHi
00C726 1 85 44 sta BufferLo ;buffer at $800
00C728 1 A9 08 lda #$08
00C72A 1 85 45 sta BufferHi
00C72C 1 20 32 C7 jsr Driver ;get the block
00C72F 1
00C72F 1 4C 01 08 jmp $801 ;execute the block
00C732 1
00C732 1 ; ProDOS Driver code
00C732 1 ; First check that this is the right drive
00C732 1 Driver:
00C732 1 A6 43 ldx Unit
00C734 1 A5 42 lda Command; Check which command is being requested
00C736 1 F0 0C beq GetStatus ;0 = Status command
00C738 1 C9 01 cmp #ReadBlockCommand
00C73A 1 F0 10 beq ReadBlockAndSetTime
00C73C 1 C9 02 cmp #WriteBlockCommand
00C73E 1 F0 54 beq WriteBlock
00C740 1 38 sec ;set carry as we don't support any other commands
00C741 1 A9 53 lda #$53 ;Invalid parameter error
00C743 1 60 rts
00C744 1
00C744 1 ; ProDOS Status Command Handler
00C744 1 GetStatus:
00C744 1 A2 FF ldx #$ff ;low byte number of blocks
00C746 1 A0 FF ldy #$ff ;high byte number of blocks
00C748 1 A9 00 lda #$0 ;zero accumulator and clear carry for success
00C74A 1 18 clc
00C74B 1 60 rts
00C74C 1
00C74C 1 ; ProDOS Read Block Command
00C74C 1 ReadBlockAndSetTime:
00C74C 1 A5 47 lda BlockHi ; only get the time if block 0002
00C74E 1 D0 18 bne readBlock
00C750 1 A5 46 lda BlockLo
00C752 1 C9 02 cmp #$02
00C754 1 D0 12 bne readBlock
00C756 1 A0 00 ldy #$00 ;Get the current time on each block read for now
00C758 1 A9 03 lda #GetTimeCommand
00C75A 1 20 C0 C7 jsr SendByte
00C75D 1 getTimeByte:
00C75D 1 20 DE C7 jsr GetByte
00C760 1 99 90 BF sta $bf90,y
00C763 1 C8 iny
00C764 1 C0 04 cpy #$04
00C766 1 D0 F5 bne getTimeByte
00C768 1 readBlock:
00C768 1 A9 01 lda #ReadBlockCommand ;read the block after setting the clock
00C76A 1 20 C0 C7 jsr SendByte
00C76D 1 A5 46 lda BlockLo
00C76F 1 20 C0 C7 jsr SendByte
00C772 1 A5 47 lda BlockHi
00C774 1 20 C0 C7 jsr SendByte
00C777 1 8A txa
00C778 1 20 C0 C7 jsr SendByte
00C77B 1 A0 00 ldy #$0
00C77D 1 20 8B C7 jsr read256
00C780 1 E6 45 inc BufferHi
00C782 1 20 8B C7 jsr read256
00C785 1 C6 45 dec BufferHi
00C787 1 A9 00 lda #$0 ;zero accumulator and clear carry for success
00C789 1 18 clc
00C78A 1 60 rts
00C78B 1
00C78B 1 read256:
00C78B 1 20 DE C7 jsr GetByte
00C78E 1 91 44 sta (BufferLo),y
00C790 1 C8 iny
00C791 1 D0 F8 bne read256
00C793 1 60 rts
00C794 1
00C794 1 ; ProDOS Write Block Command
00C794 1 WriteBlock:
00C794 1 A9 02 lda #WriteBlockCommand
00C796 1 20 C0 C7 jsr SendByte
00C799 1 A5 46 lda BlockLo
00C79B 1 20 C0 C7 jsr SendByte
00C79E 1 A5 47 lda BlockHi
00C7A0 1 20 C0 C7 jsr SendByte
00C7A3 1 8A txa
00C7A4 1 20 C0 C7 jsr SendByte
00C7A7 1 A0 00 ldy #$0
00C7A9 1 20 B7 C7 jsr write256
00C7AC 1 E6 45 inc BufferHi
00C7AE 1 20 B7 C7 jsr write256
00C7B1 1 C6 45 dec BufferHi
00C7B3 1 A9 00 lda #$0 ;zero accumulator and clear carry for success
00C7B5 1 18 clc
00C7B6 1 60 rts
00C7B7 1
00C7B7 1 write256:
00C7B7 1 B1 44 lda (BufferLo),y
00C7B9 1 20 C0 C7 jsr SendByte
00C7BC 1 C8 iny
00C7BD 1 D0 F8 bne write256
00C7BF 1 60 rts
00C7C0 1
00C7C0 1 SendByte:
00C7C0 1 48 pha
00C7C1 1 waitWrite:
00C7C1 1 AD FB C0 lda InputFlags
00C7C4 1 2A rol
00C7C5 1 2A rol
00C7C6 1 B0 F9 bcs waitWrite
00C7C8 1 68 pla
00C7C9 1 8D FD C0 sta OutputByte
00C7CC 1 A9 0E lda #$0e ; set bit 0 low to indicate write started
00C7CE 1 8D F7 C0 sta OutputFlags
00C7D1 1 finishWrite:
00C7D1 1 AD FB C0 lda InputFlags
00C7D4 1 2A rol
00C7D5 1 2A rol
00C7D6 1 90 F9 bcc finishWrite
00C7D8 1 A9 0F lda #$0f
00C7DA 1 8D F7 C0 sta OutputFlags
00C7DD 1 60 rts
00C7DE 1
00C7DE 1 GetByte:
00C7DE 1 A9 0D lda #$0d ;set read flag low
00C7E0 1 8D F7 C0 sta OutputFlags
00C7E3 1 waitRead:
00C7E3 1 AD FB C0 lda InputFlags
00C7E6 1 2A rol
00C7E7 1 B0 FA bcs waitRead
00C7E9 1 AD FE C0 lda InputByte
00C7EC 1 48 pha
00C7ED 1 A9 0F lda #$0f ;set all flags high
00C7EF 1 8D F7 C0 sta OutputFlags
00C7F2 1 finishRead:
00C7F2 1 AD FB C0 lda InputFlags
00C7F5 1 2A rol
00C7F6 1 90 FA bcc finishRead
00C7F8 1 68 pla
00C7F9 1 end:
00C7F9 1 60 rts
00C7FA 1
00C7FA 1 00 00 .repeat 251-<end
00C7FC 1 .byte 0
00C7FC 1 .endrepeat
00C7FC 1
00C7FC 1 00 00 .byte 0,0 ;0000 blocks = check status
00C7FE 1 17 .byte 23 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
00C7FF 1 14 .byte DriverEntry&$00FF ;low byte of entry
00C800 1
00C800 1

View File

@ -2,9 +2,9 @@
; Use of this source code is governed by an MIT
; license that can be found in the LICENSE file.
; This file contains the source for the firmware
; that was formerly used to copy files from RPi
; to Apple II RAM
; This file formerly contained the source for the
; firmware that had a file access
; but is now empty except required common bytes
;ProDOS Zero Page
Command = $42 ;ProDOS Command
@ -33,122 +33,41 @@ LoadFileCommand = $06
SaveFileCommand = $07
MenuCommand = $08
InputString = $fd67
Monitor = $ff59
.org SLOT*$100 + $C000
;ID bytes for booting and drive detection
cpx #$20 ;ID bytes for ProDOS and the
cpx #$00 ; Apple Autostart ROM
cpx #$20 ;ID bytes for ProDOS
cpx #$00 ;
cpx #$03 ;
cpx #$3C ;ID byte for Autostart ROM
ldx #SLOT*$10
stx $2b
stx Unit
;force EPROM to second page on boot
lda #$3f ;set all flags high and page 3 of EPROM for menu
jmp PageJump
;The following bytes must exist in this location for Pascal communications
;as they are standard pointers for entry points
.byte CommInit&$00FF ;low byte of rts for init of Pascal comms
.byte $43 ; low byte of read for Pascal comms
.byte $49 ; low byte of write for Pascal comms
.byte $4F ; low byte of rts for status of Pascal comms
CommInit:
lda #$0f ; set all flags high and page 0 for comm driver
sta OutputFlags
ldx #$00 ; set error code to 0 for success
rts
PageJump:
sta OutputFlags
jmp Start ;this jump is only called if coming in from PageJump with A=$2f
jmp Start ;this jump is only called if coming in from PageJump with A=$0f
;entry points for ProDOS
DriverEntry:
lda #$0f ;set all flags high and page 0 of EPROM
sta OutputFlags
jmp Start ; this is never called as the EPROM page changes
;load first two blocks and execute to boot
Start:
lda #$a4
sta $33
GetFilename:
jsr InputString
LoadFile:
lda #$00
sta BufferLo
lda #$20
sta BufferHi
lda #$06 ; send command 6 = load
jsr SendByte
ldy #$00
sendFilename:
lda $0200,y
cmp #$8d
beq sendNullTerminator
and #$7f
jsr SendByte
iny
bne sendFilename
sendNullTerminator:
lda #$00
jsr SendByte
jsr GetByte
sta BlockLo ; not really a block, just using the memory space
jsr GetByte
sta BlockHi
NextPage:
lda BlockHi
beq ReadFinalPage
ldy #$00
NextByte:
jsr GetByte
sta (BufferLo),y
iny
bne NextByte
inc BufferHi
dec BlockHi
bne NextPage
ReadFinalPage:
lda BlockLo
beq ExitToMonitor
ldy #$00
NextByteFinal:
jsr GetByte
sta (BufferLo),y
iny
cpy BlockLo
bne NextByteFinal
ExitToMonitor:
jsr Monitor
SendByte:
pha
waitWrite:
lda InputFlags
rol
rol
bcs waitWrite
pla
sta OutputByte
lda #$2e ; set bit 0 low to indicate write started
sta OutputFlags
finishWrite:
lda InputFlags
rol
rol
bcc finishWrite
lda #$2f
sta OutputFlags
rts
GetByte:
lda #$2d ;set read flag low
sta OutputFlags
waitRead:
lda InputFlags
rol
bcs waitRead
lda InputByte
pha
lda #$2f ;set all flags high
sta OutputFlags
finishRead:
lda InputFlags
rol
bcc finishRead
pla
end:
rts
@ -157,6 +76,6 @@ end:
.endrepeat
.byte 0,0 ;0000 blocks = check status
.byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
.byte 23 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
.byte DriverEntry&$00FF ;low byte of entry

View File

@ -1,186 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : FileAccessFirmware.asm
Current file: FileAccessFirmware.asm
000000r 1 ; Copyright Terence J. Boldt (c)2020-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the firmware
000000r 1 ; that was formerly used to copy files from RPi
000000r 1 ; to Apple II RAM
000000r 1
000000r 1 ;ProDOS Zero Page
000000r 1 Command = $42 ;ProDOS Command
000000r 1 Unit = $43 ;ProDOS unit (SDDD0000)
000000r 1 BufferLo = $44
000000r 1 BufferHi = $45
000000r 1 BlockLo = $46
000000r 1 BlockHi = $47
000000r 1
000000r 1 ; ProDOS Error Codes
000000r 1 IOError = $27
000000r 1 NoDevice = $28
000000r 1 WriteProtect = $2B
000000r 1
000000r 1 InputByte = $c08e+SLOT*$10
000000r 1 OutputByte = $c08d+SLOT*$10
000000r 1 InputFlags = $c08b+SLOT*$10
000000r 1 OutputFlags = $c087+SLOT*$10
000000r 1
000000r 1 ReadBlockCommand = $01
000000r 1 WriteBlockCommand = $02
000000r 1 GetTimeCommand = $03
000000r 1 ChangeDriveCommand = $04
000000r 1 ExecCommand = $05
000000r 1 LoadFileCommand = $06
000000r 1 SaveFileCommand = $07
000000r 1 MenuCommand = $08
000000r 1
000000r 1 InputString = $fd67
000000r 1 Monitor = $ff59
000000r 1
000000r 1 .org SLOT*$100 + $C000
00C700 1 ;ID bytes for booting and drive detection
00C700 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the
00C702 1 E0 00 cpx #$00 ; Apple Autostart ROM
00C704 1 E0 03 cpx #$03 ;
00C706 1
00C706 1 A2 70 ldx #SLOT*$10
00C708 1 86 2B stx $2b
00C70A 1 86 43 stx Unit
00C70C 1
00C70C 1 ;force EPROM to second page on boot
00C70C 1 A9 3F lda #$3f ;set all flags high and page 3 of EPROM for menu
00C70E 1 PageJump:
00C70E 1 8D F7 C0 sta OutputFlags
00C711 1 4C 19 C7 jmp Start ;this jump is only called if coming in from PageJump with A=$2f
00C714 1
00C714 1 ;entry points for ProDOS
00C714 1 DriverEntry:
00C714 1 A9 0F lda #$0f ;set all flags high and page 0 of EPROM
00C716 1 8D F7 C0 sta OutputFlags
00C719 1
00C719 1 Start:
00C719 1 A9 A4 lda #$a4
00C71B 1 85 33 sta $33
00C71D 1
00C71D 1 GetFilename:
00C71D 1 20 67 FD jsr InputString
00C720 1
00C720 1 LoadFile:
00C720 1 A9 00 lda #$00
00C722 1 85 44 sta BufferLo
00C724 1 A9 20 lda #$20
00C726 1 85 45 sta BufferHi
00C728 1 A9 06 lda #$06 ; send command 6 = load
00C72A 1 20 74 C7 jsr SendByte
00C72D 1 A0 00 ldy #$00
00C72F 1 sendFilename:
00C72F 1 B9 00 02 lda $0200,y
00C732 1 C9 8D cmp #$8d
00C734 1 F0 08 beq sendNullTerminator
00C736 1 29 7F and #$7f
00C738 1 20 74 C7 jsr SendByte
00C73B 1 C8 iny
00C73C 1 D0 F1 bne sendFilename
00C73E 1 sendNullTerminator:
00C73E 1 A9 00 lda #$00
00C740 1 20 74 C7 jsr SendByte
00C743 1
00C743 1 20 92 C7 jsr GetByte
00C746 1 85 46 sta BlockLo ; not really a block, just using the memory space
00C748 1 20 92 C7 jsr GetByte
00C74B 1 85 47 sta BlockHi
00C74D 1 NextPage:
00C74D 1 A5 47 lda BlockHi
00C74F 1 F0 10 beq ReadFinalPage
00C751 1 A0 00 ldy #$00
00C753 1 NextByte:
00C753 1 20 92 C7 jsr GetByte
00C756 1 91 44 sta (BufferLo),y
00C758 1 C8 iny
00C759 1 D0 F8 bne NextByte
00C75B 1 E6 45 inc BufferHi
00C75D 1 C6 47 dec BlockHi
00C75F 1 D0 EC bne NextPage
00C761 1 ReadFinalPage:
00C761 1 A5 46 lda BlockLo
00C763 1 F0 0C beq ExitToMonitor
00C765 1 A0 00 ldy #$00
00C767 1 NextByteFinal:
00C767 1 20 92 C7 jsr GetByte
00C76A 1 91 44 sta (BufferLo),y
00C76C 1 C8 iny
00C76D 1 C4 46 cpy BlockLo
00C76F 1 D0 F6 bne NextByteFinal
00C771 1 ExitToMonitor:
00C771 1 20 59 FF jsr Monitor
00C774 1
00C774 1 SendByte:
00C774 1 48 pha
00C775 1 waitWrite:
00C775 1 AD FB C0 lda InputFlags
00C778 1 2A rol
00C779 1 2A rol
00C77A 1 B0 F9 bcs waitWrite
00C77C 1 68 pla
00C77D 1 8D FD C0 sta OutputByte
00C780 1 A9 2E lda #$2e ; set bit 0 low to indicate write started
00C782 1 8D F7 C0 sta OutputFlags
00C785 1 finishWrite:
00C785 1 AD FB C0 lda InputFlags
00C788 1 2A rol
00C789 1 2A rol
00C78A 1 90 F9 bcc finishWrite
00C78C 1 A9 2F lda #$2f
00C78E 1 8D F7 C0 sta OutputFlags
00C791 1 60 rts
00C792 1
00C792 1 GetByte:
00C792 1 A9 2D lda #$2d ;set read flag low
00C794 1 8D F7 C0 sta OutputFlags
00C797 1 waitRead:
00C797 1 AD FB C0 lda InputFlags
00C79A 1 2A rol
00C79B 1 B0 FA bcs waitRead
00C79D 1 AD FE C0 lda InputByte
00C7A0 1 48 pha
00C7A1 1 A9 2F lda #$2f ;set all flags high
00C7A3 1 8D F7 C0 sta OutputFlags
00C7A6 1 finishRead:
00C7A6 1 AD FB C0 lda InputFlags
00C7A9 1 2A rol
00C7AA 1 90 FA bcc finishRead
00C7AC 1 68 pla
00C7AD 1 end:
00C7AD 1 60 rts
00C7AE 1
00C7AE 1 00 00 00 00 .repeat 251-<end
00C7B2 1 00 00 00 00
00C7B6 1 00 00 00 00
00C7BA 1 00 00 00 00
00C7BE 1 00 00 00 00
00C7C2 1 00 00 00 00
00C7C6 1 00 00 00 00
00C7CA 1 00 00 00 00
00C7CE 1 00 00 00 00
00C7D2 1 00 00 00 00
00C7D6 1 00 00 00 00
00C7DA 1 00 00 00 00
00C7DE 1 00 00 00 00
00C7E2 1 00 00 00 00
00C7E6 1 00 00 00 00
00C7EA 1 00 00 00 00
00C7EE 1 00 00 00 00
00C7F2 1 00 00 00 00
00C7F6 1 00 00 00 00
00C7FA 1 00 00
00C7FC 1 .byte 0
00C7FC 1 .endrepeat
00C7FC 1
00C7FC 1 00 00 .byte 0,0 ;0000 blocks = check status
00C7FE 1 07 .byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
00C7FF 1 14 .byte DriverEntry&$00FF ;low byte of entry
00C800 1
00C800 1

View File

@ -45,21 +45,32 @@ vtab = $25
BasL = $28
htab80 = $057b
.org SLOT*$100 + $C000
.org SLOT*$100 + $C000
;ID bytes for booting and drive detection
cpx #$20 ;ID bytes for ProDOS and the
cpx #$00 ; Apple Autostart ROM
cpx #$20 ;ID bytes for ProDOS
cpx #$00 ;
cpx #$03 ;
cpx #$3C ;ID byte for Autostart ROM
ldx #SLOT*$10
stx $2b
stx Unit
lda #$3f ;set all flags high and page 3 of EPROM for menu
jmp PageJump
;The following bytes must exist in this location for Pascal communications
;as they are standard pointers for entry points
.byte CommInit&$00FF ;low byte of rts for init of Pascal comms
.byte $43 ; low byte of read for Pascal comms
.byte $49 ; low byte of write for Pascal comms
.byte $4F ; low byte of rts for status of Pascal comms
CommInit:
lda #$0f ; set all flags high and page 0 for comm driver
sta OutputFlags
ldx #$00 ; set error code to 0 for success
rts
;force EPROM to second page on boot
lda #$3f ;set all flags high and page 1 of EPROMi
PageJump:
sta OutputFlags
jmp Start
jmp Start ;this jump is only called if coming in from PageJump with A=$0f
;entry points for ProDOS
DriverEntry:
@ -73,10 +84,11 @@ Start:
lda #$fd
sta $37
;jsr Home ;clear screen and show menu options
lda #$10
lda #$02
sta vtab
jsr BasCalc
ldy #$00
sty htab
PrintString:
lda Text,y
beq WaitForRPi
@ -85,10 +97,11 @@ PrintString:
iny
bne PrintString
.if HW_TYPE = 0
WaitForRPi:
lda InputFlags
rol
bcs Reset
bit InputFlags
bmi Reset
lda #$ff
jsr Wait
lda #'.'+$80
@ -108,6 +121,37 @@ Reset:
beq Ok
jmp Reset
.else
WaitForRPi:
@1:
bit InputFlags
bmi @2
lda InputByte
jmp @1
@2:
bit InputFlags
bpl @4
bvs @3
lda #ResetCommand
sta OutputByte
@3:
lda #$ff
jsr Wait
lda #'.'+$80
jsr PrintChar
jmp @2
@4:
lda #$ff
jsr Wait
@5:
bit InputFlags
bmi Ok
lda InputByte
jmp @5
.endif
Ok:
lda #$8D
jsr PrintChar
@ -121,52 +165,54 @@ Boot:
jmp PageJump
SendByte:
pha
waitWrite:
lda InputFlags
rol
rol
bcs waitWrite
pla
bit InputFlags
bvs SendByte
sta OutputByte
.if HW_TYPE = 0
lda #$3e ; set bit 0 low to indicate write started
sta OutputFlags
finishWrite:
lda InputFlags
rol
rol
bcc finishWrite
bit InputFlags
bvc finishWrite
lda #$3f
sta OutputFlags
.endif
rts
GetByte:
lda #$3d ;set read flag low
sta OutputFlags
.if HW_TYPE = 0
ldx #$3d ;set read flag low
stx OutputFlags
.endif
waitRead:
lda InputFlags
rol
bcs waitRead
bit InputFlags
bmi waitRead
lda InputByte
pha
lda #$3f ;set all flags high
sta OutputFlags
.if HW_TYPE = 0
ldx #$3f ;set all flags high
stx OutputFlags
finishRead:
lda InputFlags
rol
bcc finishRead
pla
end:
bit InputFlags
bpl finishRead
.endif
rts
; NOTE: The text below exactly fills the remaining 256 bytes of firmware
Text:
.byte "Apple2-IO-RPi",$8d
.byte "(c)2020-2024 Terence J. Boldt",$8d
.byte $8d
.byte "Waiting for RPi FW:000F...",$00
.if HW_TYPE = 0
.byte "Waiting for RPi FW:0011"
.else
.byte "Waiting for RPi FW:8011"
.endif
end:
.byte $00
.repeat 251-<end
.byte 0
.endrepeat
.byte 0,0 ;0000 blocks = check status
.byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
.byte DriverEntry&$00FF ;low byte of entry

View File

@ -1,193 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : MenuFirmware.asm
Current file: MenuFirmware.asm
000000r 1 ; Copyright Terence J. Boldt (c)2020-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the firmware
000000r 1 ; that displays the copyright message on boot
000000r 1 ; and checks for the RPi status to be ready before
000000r 1 ; attempting to boot
000000r 1
000000r 1 ;ProDOS Zero Page
000000r 1 Command = $42 ;ProDOS Command
000000r 1 Unit = $43 ;ProDOS unit (SDDD0000)
000000r 1 BufferLo = $44
000000r 1 BufferHi = $45
000000r 1 BlockLo = $46
000000r 1 BlockHi = $47
000000r 1
000000r 1 ; ProDOS Error Codes
000000r 1 IOError = $27
000000r 1 NoDevice = $28
000000r 1 WriteProtect = $2B
000000r 1
000000r 1 InputByte = $c08e+SLOT*$10
000000r 1 OutputByte = $c08d+SLOT*$10
000000r 1 InputFlags = $c08b+SLOT*$10
000000r 1 OutputFlags = $c087+SLOT*$10
000000r 1
000000r 1 ResetCommand = $00
000000r 1 ReadBlockCommand = $01
000000r 1 WriteBlockCommand = $02
000000r 1 GetTimeCommand = $03
000000r 1 ChangeDriveCommand = $04
000000r 1 ExecCommand = $05
000000r 1 LoadFileCommand = $06
000000r 1 SaveFileCommand = $07
000000r 1 MenuCommand = $08
000000r 1
000000r 1 Wait = $fca8
000000r 1 PrintChar = $fded
000000r 1 Home = $fc58
000000r 1 ReadChar = $fd0c
000000r 1 BasCalc = $fbc1
000000r 1 htab = $24
000000r 1 vtab = $25
000000r 1 BasL = $28
000000r 1 htab80 = $057b
000000r 1
000000r 1 .org SLOT*$100 + $C000
00C700 1 ;ID bytes for booting and drive detection
00C700 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the
00C702 1 E0 00 cpx #$00 ; Apple Autostart ROM
00C704 1 E0 03 cpx #$03 ;
00C706 1
00C706 1 A2 70 ldx #SLOT*$10
00C708 1 86 2B stx $2b
00C70A 1 86 43 stx Unit
00C70C 1
00C70C 1 ;force EPROM to second page on boot
00C70C 1 A9 3F lda #$3f ;set all flags high and page 1 of EPROMi
00C70E 1 PageJump:
00C70E 1 8D F7 C0 sta OutputFlags
00C711 1 4C 19 C7 jmp Start
00C714 1
00C714 1 ;entry points for ProDOS
00C714 1 DriverEntry:
00C714 1 A9 0F lda #$0f ;set all flags high and page 0 of EPROM
00C716 1 8D F7 C0 sta OutputFlags
00C719 1 ;since the firmware page changes to 0, this falls through to the driver
00C719 1
00C719 1 Start:
00C719 1 A9 F0 lda #$f0 ;restore COUT after PR# called
00C71B 1 85 36 sta $36
00C71D 1 A9 FD lda #$fd
00C71F 1 85 37 sta $37
00C721 1 ;jsr Home ;clear screen and show menu options
00C721 1 A9 10 lda #$10
00C723 1 85 25 sta vtab
00C725 1 20 C1 FB jsr BasCalc
00C728 1 A0 00 ldy #$00
00C72A 1 PrintString:
00C72A 1 B9 B4 C7 lda Text,y
00C72D 1 F0 08 beq WaitForRPi
00C72F 1 09 80 ora #$80
00C731 1 20 ED FD jsr PrintChar
00C734 1 C8 iny
00C735 1 D0 F3 bne PrintString
00C737 1
00C737 1 WaitForRPi:
00C737 1 AD FB C0 lda InputFlags
00C73A 1 2A rol
00C73B 1 B0 0D bcs Reset
00C73D 1 A9 FF lda #$ff
00C73F 1 20 A8 FC jsr Wait
00C742 1 A9 AE lda #'.'+$80
00C744 1 20 ED FD jsr PrintChar
00C747 1 4C 37 C7 jmp WaitForRPi
00C74A 1
00C74A 1 Reset:
00C74A 1 A9 DF lda #'_'|$80
00C74C 1 20 ED FD jsr PrintChar
00C74F 1 A9 00 lda #ResetCommand
00C751 1 20 7A C7 jsr SendByte
00C754 1 A9 88 lda #$88
00C756 1 20 ED FD jsr PrintChar
00C759 1 A9 AE lda #'.'|$80
00C75B 1 20 ED FD jsr PrintChar
00C75E 1 20 98 C7 jsr GetByte
00C761 1 F0 03 beq Ok
00C763 1 4C 4A C7 jmp Reset
00C766 1
00C766 1 Ok:
00C766 1 A9 8D lda #$8D
00C768 1 20 ED FD jsr PrintChar
00C76B 1 A9 CF lda #'O'|$80
00C76D 1 20 ED FD jsr PrintChar
00C770 1 A9 CB lda #'K'|$80
00C772 1 20 ED FD jsr PrintChar
00C775 1
00C775 1 Boot:
00C775 1 A9 0F lda #$0f
00C777 1 4C 0E C7 jmp PageJump
00C77A 1
00C77A 1 SendByte:
00C77A 1 48 pha
00C77B 1 waitWrite:
00C77B 1 AD FB C0 lda InputFlags
00C77E 1 2A rol
00C77F 1 2A rol
00C780 1 B0 F9 bcs waitWrite
00C782 1 68 pla
00C783 1 8D FD C0 sta OutputByte
00C786 1 A9 3E lda #$3e ; set bit 0 low to indicate write started
00C788 1 8D F7 C0 sta OutputFlags
00C78B 1 finishWrite:
00C78B 1 AD FB C0 lda InputFlags
00C78E 1 2A rol
00C78F 1 2A rol
00C790 1 90 F9 bcc finishWrite
00C792 1 A9 3F lda #$3f
00C794 1 8D F7 C0 sta OutputFlags
00C797 1 60 rts
00C798 1
00C798 1 GetByte:
00C798 1 A9 3D lda #$3d ;set read flag low
00C79A 1 8D F7 C0 sta OutputFlags
00C79D 1 waitRead:
00C79D 1 AD FB C0 lda InputFlags
00C7A0 1 2A rol
00C7A1 1 B0 FA bcs waitRead
00C7A3 1 AD FE C0 lda InputByte
00C7A6 1 48 pha
00C7A7 1 A9 3F lda #$3f ;set all flags high
00C7A9 1 8D F7 C0 sta OutputFlags
00C7AC 1 finishRead:
00C7AC 1 AD FB C0 lda InputFlags
00C7AF 1 2A rol
00C7B0 1 90 FA bcc finishRead
00C7B2 1 68 pla
00C7B3 1 end:
00C7B3 1 60 rts
00C7B4 1
00C7B4 1 ; NOTE: The text below exactly fills the remaining 256 bytes of firmware
00C7B4 1 Text:
00C7B4 1 41 70 70 6C .byte "Apple2-IO-RPi",$8d
00C7B8 1 65 32 2D 49
00C7BC 1 4F 2D 52 50
00C7C0 1 69 8D
00C7C2 1 28 63 29 32 .byte "(c)2020-2024 Terence J. Boldt",$8d
00C7C6 1 30 32 30 2D
00C7CA 1 32 30 32 34
00C7CE 1 20 54 65 72
00C7D2 1 65 6E 63 65
00C7D6 1 20 4A 2E 20
00C7DA 1 42 6F 6C 64
00C7DE 1 74 8D
00C7E0 1 8D .byte $8d
00C7E1 1 57 61 69 74 .byte "Waiting for RPi FW:000F...",$00
00C7E5 1 69 6E 67 20
00C7E9 1 66 6F 72 20
00C7ED 1 52 50 69 20
00C7F1 1 46 57 3A 30
00C7F5 1 30 30 46 2E
00C7F9 1 2E 2E 00
00C7FC 1
00C7FC 1 00 00 .byte 0,0 ;0000 blocks = check status
00C7FE 1 07 .byte 7 ;bit set(0=status 1=read 2=write) unset(3=format, 4/5=number of volumes, 6=interruptable, 7=removable)
00C7FF 1 14 .byte DriverEntry&$00FF ;low byte of entry
00C800 1
00C800 1

View File

@ -33,6 +33,7 @@ MenuCommand = $08
InputString = $fd67
PrintChar = $fded
PrintHex = $fde3
Keyboard = $c000
ClearKeyboard = $c010
Wait = $fca8
@ -50,53 +51,68 @@ ESC = $9b
.endmacro
.org $2000
ldx #$07 ; start at slot 7
DetectSlot:
; Find Apple2-IO-RPi card
ldx #$06
ldy #$09
CheckIdBytes:
lda $C700,y ; !! Self modifying code
cmp IdBytes,y
bne NextCard
dey
bne CheckIdBytes
jmp FoundCard
NextCard:
dec CheckIdBytes+2
ldy #$09
dex
bne CheckIdBytes
CardNotFound:
ldy #$00
lda #$fc
sta SlotL
PrintCardNotFound:
lda TextCardNotFound,y
beq Failed
jsr PrintChar
iny
bne PrintCardNotFound
Failed:
rts
FoundCard:
ldy #$00
PrintCardFound:
lda TextCardFound,y
beq PrintCardNumber
jsr PrintChar
iny
bne PrintCardFound
PrintCardNumber:
inx
txa
ora #$c0
sta SlotH
lda (SlotL),y
bne nextSlot
iny
lda (SlotL),y
bne nextSlot
iny
lda (SlotL),y
cmp #$17
bne nextSlot
iny
lda (SlotL),y
cmp #$14
bne nextSlot
jsr PrintHex
lda #$8D
jsr PrintChar
SetOffsetForCard:
txa
asl
asl
asl
asl
tax
clc
bcc Start
nextSlot:
dex
bne DetectSlot
rts
Start:
stx slotx + $1e01 ;set the slot for the driver
ldy #$00
ldy #$00
PrintString:
lda Text,y
beq copyDriver
ora #$80
jsr PrintChar
iny
bne PrintString
copyDriver:
ldy #$00
copyDriverByte:
lda $2100,y
lda $2200,y
sta $0300,y
iny
cpy #$e6
@ -140,10 +156,26 @@ a2help:
.byte "a2help", $00
Text:
aschi "RPI command version: 000E"
.byte $8d
.if HW_TYPE = 0
aschi "RPI command version: 000F (classic)"
.else
aschi "RPI command version: 800F (pico)"
.endif
.byte $8d
.byte $00
IdBytes:
.byte $E0,$20,$E0,$00,$E0,$03,$E0,$3C,$A9,$3F
TextCardFound:
aschi "Found Apple2-IO-RPi in slot "
.byte $00
TextCardNotFound:
aschi "Apple2-IO-RPi not found"
.byte $8D
end:
.byte $00
.byte $00
.repeat 255-<end
.byte 0
@ -222,6 +254,7 @@ waitWrite:
bcs waitWrite
pla
sta OutputByte,x
.if HW_TYPE = 0
lda #$1e ; set bit 0 low to indicate write started
sta OutputFlags,x
finishWrite:
@ -231,17 +264,21 @@ finishWrite:
bcc finishWrite
lda #$1f
sta OutputFlags,x
.endif
rts
GetByte:
.if HW_TYPE = 0
lda #$1d ;set read flag low
sta OutputFlags,x
.endif
waitRead:
lda InputFlags,x
rol
bcs waitRead
readByte:
lda InputByte,x
.if HW_TYPE = 0
pha
lda #$1f ;set all flags high
sta OutputFlags,x
@ -250,6 +287,7 @@ finishRead:
rol
bcc finishRead
pla
.endif
clc ;success
rts

View File

@ -1,274 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : RPi.Command.asm
Current file: RPi.Command.asm
000000r 1 ; Copyright Terence J. Boldt (c)2021-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the RPI.COMMAND
000000r 1 ; application that runs on the Apple II and extends
000000r 1 ; ProDOS BASIC.SYSTEM to add the RPI command which
000000r 1 ; allows commands to be executed on the Raspberry Pi
000000r 1
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 = $c08e
000300 1 OutputByte = $c08d
000300 1 InputFlags = $c08b
000300 1 OutputFlags = $c087
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 LastChar = $06
000300 1 SlotL = $fe
000300 1 SlotH = $ff
000300 1 ESC = $9b
000300 1
000300 1 ;macro for string with high-bit set
000300 1 .macro aschi str
000300 1 .repeat .strlen (str), c
000300 1 .byte .strat (str, c) | $80
000300 1 .endrep
000300 1 .endmacro
000300 1
000300 1 .org $2000
002000 1 A2 07 ldx #$07 ; start at slot 7
002002 1 DetectSlot:
002002 1 A0 00 ldy #$00
002004 1 A9 FC lda #$fc
002006 1 85 FE sta SlotL
002008 1 8A txa
002009 1 09 C0 ora #$c0
00200B 1 85 FF sta SlotH
00200D 1 B1 FE lda (SlotL),y
00200F 1 D0 1C bne nextSlot
002011 1 C8 iny
002012 1 B1 FE lda (SlotL),y
002014 1 D0 17 bne nextSlot
002016 1 C8 iny
002017 1 B1 FE lda (SlotL),y
002019 1 C9 17 cmp #$17
00201B 1 D0 10 bne nextSlot
00201D 1 C8 iny
00201E 1 B1 FE lda (SlotL),y
002020 1 C9 14 cmp #$14
002022 1 D0 09 bne nextSlot
002024 1 8A txa
002025 1 0A asl
002026 1 0A asl
002027 1 0A asl
002028 1 0A asl
002029 1 AA tax
00202A 1 18 clc
00202B 1 90 04 bcc Start
00202D 1 nextSlot:
00202D 1 CA dex
00202E 1 D0 D2 bne DetectSlot
002030 1 60 rts
002031 1 Start:
002031 1 8E 31 21 stx slotx + $1e01 ;set the slot for the driver
002034 1 A0 00 ldy #$00
002036 1 PrintString:
002036 1 B9 93 20 lda Text,y
002039 1 F0 08 beq copyDriver
00203B 1 09 80 ora #$80
00203D 1 20 ED FD jsr PrintChar
002040 1 C8 iny
002041 1 D0 F3 bne PrintString
002043 1 copyDriver:
002043 1 A0 00 ldy #$00
002045 1 copyDriverByte:
002045 1 B9 00 21 lda $2100,y
002048 1 99 00 03 sta $0300,y
00204B 1 C8 iny
00204C 1 C0 E6 cpy #$e6
00204E 1 D0 F5 bne copyDriverByte
002050 1 ;
002050 1 ; FIRST SAVE THE EXTERNAL COMMAND ADDRESS SO YOU WON'T
002050 1 ; DISCONNECT ANY PREVIOUSLY CONNECTED COMMAND.
002050 1 ;
002050 1 AD 07 BE LDA EXTRNCMD+1
002053 1 8D AD 03 STA NXTCMD
002056 1 AD 08 BE LDA EXTRNCMD+2
002059 1 8D AE 03 STA NXTCMD+1
00205C 1 ;
00205C 1 A9 00 LDA #<RPI ;Install the address of our
00205E 1 8D 07 BE STA EXTRNCMD+1 ; command handler in the
002061 1 A9 03 LDA #>RPI ; external command JMP
002063 1 8D 08 BE STA EXTRNCMD+2 ; vector.
002066 1
002066 1 A9 05 lda #ExecCommand
002068 1 20 6F 03 jsr SendByte
00206B 1 A0 00 ldy #$00
00206D 1 nextCommandByte:
00206D 1 B9 8C 20 lda a2help, y
002070 1 F0 07 beq finishCommand
002072 1 20 6F 03 jsr SendByte
002075 1 C8 iny
002076 1 4C 6D 20 jmp nextCommandByte
002079 1 finishCommand:
002079 1 A9 00 lda #$00
00207B 1 20 6F 03 jsr SendByte
00207E 1 showVersion:
00207E 1 20 8D 03 jsr GetByte
002081 1 C9 00 cmp #$00
002083 1 F0 06 beq FinishDriver
002085 1 20 ED FD jsr PrintChar
002088 1 4C 7E 20 jmp showVersion
00208B 1 FinishDriver:
00208B 1 60 rts
00208C 1
00208C 1 a2help:
00208C 1 61 32 68 65 .byte "a2help", $00
002090 1 6C 70 00
002093 1
002093 1 Text:
002093 1 D2 D0 C9 A0 aschi "RPI command version: 000E"
002097 1 E3 EF ED ED
00209B 1 E1 EE E4 A0
0020AC 1 8D .byte $8d
0020AD 1 end:
0020AD 1 00 .byte $00
0020AE 1
0020AE 1 00 00 00 00 .repeat 255-<end
0020B2 1 00 00 00 00
0020B6 1 00 00 00 00
002100 1 .byte 0
002100 1 .endrepeat
002100 1
002100 1 .org $0300
000300 1 A2 00 RPI: LDX #0 ;Check for our command.
000302 1 BD 00 02 NXTCHR: LDA INBUF,X ;Get first character.
000305 1 09 20 ora #$20 ;Make it lower case
000307 1 DD AA 03 CMP CMD,X ;Does it match?
00030A 1 D0 29 BNE NOTOURS ;No, back to CI.
00030C 1 E8 INX ;Next character
00030D 1 E0 03 CPX #CMDLEN ;All characters yet?
00030F 1 D0 F1 BNE NXTCHR ;No, read next one.
000311 1 ;
000311 1 A9 02 LDA #CMDLEN-1 ;Our cmd! Put cmd length-1
000313 1 ;lda #$8d
000313 1 ;sta $02ff
000313 1 ;lda #$fe
000313 1 8D 52 BE STA XLEN ; in CI global XLEN.
000316 1 A9 58 LDA #<XRETURN ;Point XTRNADDR to a known
000318 1 8D 50 BE STA XTRNADDR ; RTS since we'll handle
00031B 1 A9 FF LDA #>XRETURN ; at the time we intercept
00031D 1
00031D 1 8D 51 BE STA XTRNADDR+1 ; our command.
000320 1 A9 00 LDA #0 ;Mark the cmd number as
000322 1 8D 53 BE STA XCNUM ; zero (external).
000325 1 8D 54 BE STA PBITS ;And indicate no parameters
000328 1 8D 55 BE STA PBITS+1 ; to be parsed.
00032B 1 A9 8D lda #$8d
00032D 1 20 ED FD jsr $fded
000330 1 A2 70 slotx: ldx #$70 ; set x to slot # in high nibble
000332 1 18 clc
000333 1 90 04 bcc SendCommand
000335 1 ;
000335 1 38 NOTOURS: SEC ; ALWAYS SET CARRY IF NOT YOUR
000336 1 6C AD 03 JMP (NXTCMD) ; CMD AND LET NEXT COMMAND TRY
000339 1 ; ; TO CLAIM IT.
000339 1
000339 1 SendCommand:
000339 1 2C 10 C0 bit ClearKeyboard
00033C 1 A9 05 lda #$05 ;send command 5 = exec
00033E 1 20 6F 03 jsr SendByte
000341 1 A0 03 ldy #$03 ;skip over "RPI"
000343 1 getInput:
000343 1 B9 00 02 lda $0200,y
000346 1 C9 8D cmp #$8d
000348 1 F0 08 beq sendNullTerminator
00034A 1 29 7F and #$7f
00034C 1 20 6F 03 jsr SendByte
00034F 1 C8 iny
000350 1 D0 F1 bne getInput
000352 1 sendNullTerminator:
000352 1 A9 00 lda #$00
000354 1 20 6F 03 jsr SendByte
000357 1 DumpOutput:
000357 1 20 8D 03 jsr GetByte
00035A 1 C9 00 cmp #$00
00035C 1 F0 06 beq endOutput
00035E 1 20 ED FD jsr PrintChar
000361 1 18 clc
000362 1 90 F3 bcc DumpOutput
000364 1 endOutput:
000364 1 18 clc
000365 1 6C AD 03 jmp (NXTCMD)
000368 1
000368 1 HelpCommand:
000368 1 61 32 68 65 .byte "a2help",$00
00036C 1 6C 70 00
00036F 1
00036F 1 SendByte:
00036F 1 48 pha
000370 1 waitWrite:
000370 1 BD 8B C0 lda InputFlags,x
000373 1 2A rol
000374 1 2A rol
000375 1 B0 F9 bcs waitWrite
000377 1 68 pla
000378 1 9D 8D C0 sta OutputByte,x
00037B 1 A9 1E lda #$1e ; set bit 0 low to indicate write started
00037D 1 9D 87 C0 sta OutputFlags,x
000380 1 finishWrite:
000380 1 BD 8B C0 lda InputFlags,x
000383 1 2A rol
000384 1 2A rol
000385 1 90 F9 bcc finishWrite
000387 1 A9 1F lda #$1f
000389 1 9D 87 C0 sta OutputFlags,x
00038C 1 60 rts
00038D 1
00038D 1 GetByte:
00038D 1 A9 1D lda #$1d ;set read flag low
00038F 1 9D 87 C0 sta OutputFlags,x
000392 1 waitRead:
000392 1 BD 8B C0 lda InputFlags,x
000395 1 2A rol
000396 1 B0 FA bcs waitRead
000398 1 readByte:
000398 1 BD 8E C0 lda InputByte,x
00039B 1 48 pha
00039C 1 A9 1F lda #$1f ;set all flags high
00039E 1 9D 87 C0 sta OutputFlags,x
0003A1 1 finishRead:
0003A1 1 BD 8B C0 lda InputFlags,x
0003A4 1 2A rol
0003A5 1 90 FA bcc finishRead
0003A7 1 68 pla
0003A8 1 18 clc ;success
0003A9 1 60 rts
0003AA 1
0003AA 1
0003AA 1 F2 F0 E9 CMD: aschi "rpi"
0003AD 1 CMDLEN = 3 ;Our command length
0003AD 1 ;
0003AD 1 00 00 NXTCMD: .byte 0,0 ; STORE THE NEXT EXT CMD'S
0003AF 1 ; ADDRESS HERE.
0003AF 1
0003AF 1
0003AF 1

View File

@ -38,6 +38,9 @@ ShellCommand = $09
InputString = $fd6a
StringBuffer = $0200
PrintChar = $fded
PrintHex = $FDE3
PrintByte = $FDDA
Keyboard = $c000
ClearKeyboard = $c010
Home = $fc58
@ -59,39 +62,55 @@ SlotH = $ff
ESC = $9b
.org $2000
ldx #$07 ; start at slot 7
DetectSlot:
; Find Apple2-IO-RPi card
ldx #$06
ldy #$09
CheckIdBytes:
lda $C700,y ; !! Self modifying code
cmp IdBytes,y
bne NextCard
dey
bne CheckIdBytes
jmp FoundCard
NextCard:
dec CheckIdBytes+2
ldy #$09
dex
bne CheckIdBytes
CardNotFound:
ldy #$00
lda #$fc
sta SlotL
PrintCardNotFound:
lda TextCardNotFound,y
beq Failed
ora #$80
jsr PrintChar
iny
bne PrintCardNotFound
Failed:
rts
FoundCard:
ldy #$00
PrintCardFound:
lda TextCardFound,y
beq PrintCardNumber
ora #$80
jsr PrintChar
iny
bne PrintCardFound
PrintCardNumber:
inx
txa
ora #$c0
sta SlotH
lda (SlotL),y
bne nextSlot
iny
lda (SlotL),y
bne nextSlot
iny
lda (SlotL),y
cmp #$17
bne nextSlot
iny
lda (SlotL),y
cmp #$14
bne nextSlot
jsr PrintHex
lda #$8D
jsr PrintChar
SetOffsetForCard:
txa
asl
asl
asl
asl
tax
clc
bcc Init
nextSlot:
dex
bne DetectSlot
rts
Init:
lda #$8d
@ -110,8 +129,8 @@ Start:
lda LastChar
pha
bit ClearKeyboard
lda #ResetCommand
jsr SendByte
; lda #ResetCommand
; jsr SendByte
lda #ShellCommand
jsr SendByte
jsr DumpOutput
@ -183,6 +202,7 @@ waitWrite:
bcs waitWrite
pla
sta OutputByte,x
.if HW_TYPE = 0
lda #$1e ; set bit 0 low to indicate write started
sta OutputFlags,x
finishWrite:
@ -192,11 +212,14 @@ finishWrite:
bcc finishWrite
lda #$1f
sta OutputFlags,x
.endif
rts
GetByte:
.if HW_TYPE = 0
lda #$1d ;set read flag low
sta OutputFlags,x
.endif
waitRead:
lda InputFlags,x
rol
@ -204,10 +227,15 @@ waitRead:
bit Keyboard ;keypress will abort waiting to read
bpl waitRead
keyPressed:
lda InputFlags,x
rol
rol
bcs keyPressed
lda Keyboard ;send keypress to RPi
and #$7f
sta OutputByte,x
bit ClearKeyboard
.if HW_TYPE = 0
lda #$1c ;set write flag low too
sta OutputFlags,x
finishKeyPress:
@ -217,9 +245,11 @@ finishKeyPress:
bcc finishKeyPress
lda #$1d ;set flags back for reading
sta OutputFlags,x
.endif
jmp waitRead
readByte:
lda InputByte,x
.if HW_TYPE = 0
pha
lda #$1f ;set all flags high
sta OutputFlags,x
@ -228,6 +258,7 @@ finishRead:
rol
bcc finishRead
pla
.endif
clc ;success
end:
rts
@ -278,7 +309,20 @@ restoreChar:
rts
Text:
.byte "Apple2-IO-RPi Shell Version 000E",$8d
.if HW_TYPE = 0
.byte "Apple2-IO-RPi Shell Version 0010 (classic)",$8d
.else
.byte "Apple2-IO-RPi Shell Version 8010 (pico)",$8d
.endif
.byte "(c)2020-2024 Terence J. Boldt",$8d
.byte $8d
.byte $00
IdBytes:
.byte $E0,$20,$E0,$00,$E0,$03,$E0,$3C,$A9,$3F
TextCardFound:
.byte "Found Apple2-IO-RPi in slot ",$00
TextCardNotFound:
.byte "Apple2-IO-RPi not found",$8D,$00

View File

@ -1,293 +0,0 @@
ca65 V2.18 - Debian 2.19-1
Main file : Shell.asm
Current file: Shell.asm
000000r 1 ; Copyright Terence J. Boldt (c)2021-2024
000000r 1 ; Use of this source code is governed by an MIT
000000r 1 ; license that can be found in the LICENSE file.
000000r 1
000000r 1 ; This file contains the source for the SHELL
000000r 1 ; application that runs on the Apple II to talk
000000r 1 ; to the Raspberry Pi
000000r 1
000000r 1 ;ProDOS Zero Page
000000r 1 Command = $42 ;ProDOS Command
000000r 1 Unit = $43 ;ProDOS unit (SDDD0000)
000000r 1 BufferLo = $44
000000r 1 BufferHi = $45
000000r 1 BlockLo = $46
000000r 1 BlockHi = $47
000000r 1
000000r 1 ; ProDOS Error Codes
000000r 1 IOError = $27
000000r 1 NoDevice = $28
000000r 1 WriteProtect = $2B
000000r 1
000000r 1 InputByte = $c08e
000000r 1 OutputByte = $c08d
000000r 1 InputFlags = $c08b
000000r 1 OutputFlags = $c087
000000r 1
000000r 1 ResetCommand = $00
000000r 1 ReadBlockCommand = $01
000000r 1 WriteBlockCommand = $02
000000r 1 GetTimeCommand = $03
000000r 1 ChangeDriveCommand = $04
000000r 1 ExecCommand = $05
000000r 1 LoadFileCommand = $06
000000r 1 SaveFileCommand = $07
000000r 1 MenuCommand = $08
000000r 1 ShellCommand = $09
000000r 1
000000r 1 InputString = $fd6a
000000r 1 StringBuffer = $0200
000000r 1 PrintChar = $fded
000000r 1 Keyboard = $c000
000000r 1 ClearKeyboard = $c010
000000r 1 Home = $fc58
000000r 1 Wait = $fca8
000000r 1 PromptChar = $33
000000r 1 Read80Col = $c01f
000000r 1 TextPage1 = $c054
000000r 1 TextPage2 = $c055
000000r 1
000000r 1 htab = $24
000000r 1 vtab = $25
000000r 1 BasL = $28
000000r 1 htab80 = $057b
000000r 1 BasCalc = $fbc1
000000r 1
000000r 1 LastChar = $06
000000r 1 SlotL = $fe
000000r 1 SlotH = $ff
000000r 1 ESC = $9b
000000r 1
000000r 1 .org $2000
002000 1 A2 07 ldx #$07 ; start at slot 7
002002 1 DetectSlot:
002002 1 A0 00 ldy #$00
002004 1 A9 FC lda #$fc
002006 1 85 FE sta SlotL
002008 1 8A txa
002009 1 09 C0 ora #$c0
00200B 1 85 FF sta SlotH
00200D 1 B1 FE lda (SlotL),y
00200F 1 D0 1C bne nextSlot
002011 1 C8 iny
002012 1 B1 FE lda (SlotL),y
002014 1 D0 17 bne nextSlot
002016 1 C8 iny
002017 1 B1 FE lda (SlotL),y
002019 1 C9 17 cmp #$17
00201B 1 D0 10 bne nextSlot
00201D 1 C8 iny
00201E 1 B1 FE lda (SlotL),y
002020 1 C9 14 cmp #$14
002022 1 D0 09 bne nextSlot
002024 1 8A txa
002025 1 0A asl
002026 1 0A asl
002027 1 0A asl
002028 1 0A asl
002029 1 AA tax
00202A 1 18 clc
00202B 1 90 04 bcc Init
00202D 1 nextSlot:
00202D 1 CA dex
00202E 1 D0 D2 bne DetectSlot
002030 1 60 rts
002031 1
002031 1 Init:
002031 1 A9 8D lda #$8d
002033 1 20 00 C3 jsr $c300 ; force 80 columns
002036 1
002036 1 A0 00 ldy #$00
002038 1 PrintString:
002038 1 B9 71 21 lda Text,y
00203B 1 F0 08 beq Start
00203D 1 09 80 ora #$80
00203F 1 20 ED FD jsr PrintChar
002042 1 C8 iny
002043 1 D0 F3 bne PrintString
002045 1
002045 1 Start:
002045 1 A5 06 lda LastChar
002047 1 48 pha
002048 1 2C 10 C0 bit ClearKeyboard
00204B 1 A9 00 lda #ResetCommand
00204D 1 20 CC 20 jsr SendByte
002050 1 A9 09 lda #ShellCommand
002052 1 20 CC 20 jsr SendByte
002055 1 20 5C 20 jsr DumpOutput
002058 1 68 pla
002059 1 85 06 sta LastChar
00205B 1 60 rts
00205C 1
00205C 1 DumpOutput:
00205C 1 20 EA 20 jsr GetByte
00205F 1 C9 00 cmp #$00
002061 1 F0 26 beq endOutput
002063 1 48 pha
002064 1 20 5C 21 jsr ClearCursor
002067 1 68 pla
002068 1 C9 48 cmp #'H'
00206A 1 F0 27 beq setColumn
00206C 1 C9 56 cmp #'V'
00206E 1 F0 31 beq setRow
002070 1 C9 43 cmp #'C'
002072 1 F0 16 beq clearScreen
002074 1 C9 54 cmp #'T'
002076 1 F0 37 beq setTop
002078 1 C9 42 cmp #'B'
00207A 1 F0 3B beq setBottom
00207C 1 C9 55 cmp #'U'
00207E 1 F0 3F beq moveUp
002080 1 20 ED FD jsr PrintChar
002083 1 20 2B 21 jsr SetCursor
002086 1 4C 5C 20 jmp DumpOutput
002089 1 endOutput:
002089 1 60 rts
00208A 1 clearScreen:
00208A 1 20 58 FC jsr Home
00208D 1 20 2B 21 jsr SetCursor
002090 1 4C 5C 20 jmp DumpOutput
002093 1 setColumn:
002093 1 20 EA 20 jsr GetByte
002096 1 85 24 sta htab
002098 1 8D 7B 05 sta htab80
00209B 1 20 2B 21 jsr SetCursor
00209E 1 4C 5C 20 jmp DumpOutput
0020A1 1 setRow:
0020A1 1 20 EA 20 jsr GetByte
0020A4 1 85 25 sta vtab
0020A6 1 20 C1 FB jsr BasCalc
0020A9 1 20 2B 21 jsr SetCursor
0020AC 1 4C 5C 20 jmp DumpOutput
0020AF 1 setTop:
0020AF 1 20 EA 20 jsr GetByte
0020B2 1 85 22 sta $22
0020B4 1 4C 5C 20 jmp DumpOutput
0020B7 1 setBottom:
0020B7 1 20 EA 20 jsr GetByte
0020BA 1 85 23 sta $23
0020BC 1 4C 5C 20 jmp DumpOutput
0020BF 1 moveUp:
0020BF 1 C6 25 dec vtab
0020C1 1 A5 25 lda vtab
0020C3 1 20 C1 FB jsr BasCalc
0020C6 1 20 2B 21 jsr SetCursor
0020C9 1 4C 5C 20 jmp DumpOutput
0020CC 1
0020CC 1 SendByte:
0020CC 1 48 pha
0020CD 1 waitWrite:
0020CD 1 BD 8B C0 lda InputFlags,x
0020D0 1 2A rol
0020D1 1 2A rol
0020D2 1 B0 F9 bcs waitWrite
0020D4 1 68 pla
0020D5 1 9D 8D C0 sta OutputByte,x
0020D8 1 A9 1E lda #$1e ; set bit 0 low to indicate write started
0020DA 1 9D 87 C0 sta OutputFlags,x
0020DD 1 finishWrite:
0020DD 1 BD 8B C0 lda InputFlags,x
0020E0 1 2A rol
0020E1 1 2A rol
0020E2 1 90 F9 bcc finishWrite
0020E4 1 A9 1F lda #$1f
0020E6 1 9D 87 C0 sta OutputFlags,x
0020E9 1 60 rts
0020EA 1
0020EA 1 GetByte:
0020EA 1 A9 1D lda #$1d ;set read flag low
0020EC 1 9D 87 C0 sta OutputFlags,x
0020EF 1 waitRead:
0020EF 1 BD 8B C0 lda InputFlags,x
0020F2 1 2A rol
0020F3 1 90 24 bcc readByte
0020F5 1 2C 00 C0 bit Keyboard ;keypress will abort waiting to read
0020F8 1 10 F5 bpl waitRead
0020FA 1 keyPressed:
0020FA 1 AD 00 C0 lda Keyboard ;send keypress to RPi
0020FD 1 29 7F and #$7f
0020FF 1 9D 8D C0 sta OutputByte,x
002102 1 2C 10 C0 bit ClearKeyboard
002105 1 A9 1C lda #$1c ;set write flag low too
002107 1 9D 87 C0 sta OutputFlags,x
00210A 1 finishKeyPress:
00210A 1 BD 8B C0 lda InputFlags,x
00210D 1 2A rol
00210E 1 2A rol
00210F 1 90 F9 bcc finishKeyPress
002111 1 A9 1D lda #$1d ;set flags back for reading
002113 1 9D 87 C0 sta OutputFlags,x
002116 1 4C EF 20 jmp waitRead
002119 1 readByte:
002119 1 BD 8E C0 lda InputByte,x
00211C 1 48 pha
00211D 1 A9 1F lda #$1f ;set all flags high
00211F 1 9D 87 C0 sta OutputFlags,x
002122 1 finishRead:
002122 1 BD 8B C0 lda InputFlags,x
002125 1 2A rol
002126 1 90 FA bcc finishRead
002128 1 68 pla
002129 1 18 clc ;success
00212A 1 end:
00212A 1 60 rts
00212B 1
00212B 1 SetCursor:
00212B 1 AD 7B 05 lda htab80 ;get horizontal location / 2
00212E 1 4A lsr
00212F 1 A8 tay
002130 1 AD 55 C0 lda TextPage2
002133 1 90 03 bcc setChar
002135 1 AD 54 C0 lda TextPage1
002138 1 setChar:
002138 1 B1 28 lda (BasL),y
00213A 1 85 06 sta LastChar ; save so ClearCursor will pick it up
00213C 1 C9 E0 cmp #$e0
00213E 1 10 0C bpl lowerCase
002140 1 C9 C0 cmp #$c0
002142 1 10 0D bpl upperCase
002144 1 C9 A0 cmp #$a0
002146 1 10 04 bpl symbol
002148 1 C9 80 cmp #$80
00214A 1 10 0A bpl noop
00214C 1 symbol:
00214C 1 lowerCase:
00214C 1 invert:
00214C 1 49 80 eor #$80
00214E 1 4C 56 21 jmp storeChar
002151 1 upperCase:
002151 1 29 1F and #$1f
002153 1 4C 56 21 jmp storeChar
002156 1 noop:
002156 1 storeChar:
002156 1 91 28 sta (BasL),y
002158 1 AD 54 C0 lda TextPage1
00215B 1 60 rts
00215C 1
00215C 1 ClearCursor:
00215C 1 AD 7B 05 lda htab80 ;get horizontal location / 2
00215F 1 4A lsr
002160 1 A8 tay
002161 1 AD 55 C0 lda TextPage2
002164 1 90 03 bcc restoreChar
002166 1 AD 54 C0 lda TextPage1
002169 1 restoreChar:
002169 1 A5 06 lda LastChar
00216B 1 91 28 sta (BasL),y
00216D 1 AD 54 C0 lda TextPage1
002170 1 60 rts
002171 1
002171 1 Text:
002171 1 41 70 70 6C .byte "Apple2-IO-RPi Shell Version 000E",$8d
002175 1 65 32 2D 49
002179 1 4F 2D 52 50
002192 1 28 63 29 32 .byte "(c)2020-2024 Terence J. Boldt",$8d
002196 1 30 32 30 2D
00219A 1 32 30 32 34
0021B0 1 8D .byte $8d
0021B1 1 00 .byte $00
0021B1 1

View File

@ -9,6 +9,5 @@
18 PRINT "To start a shell to the RPi, type:"
19 PRINT "-shell"
20 PRINT
21 PRINT "To add RPI command to ProDOS, type:"
22 PRINT "-rpi.command"
23 PRINT
21 PRINT CHR$ (4)"-clock.driver"
22 PRINT CHR$ (4)"-rpi.command"

110
Apple2/assemble.cmd Normal file
View File

@ -0,0 +1,110 @@
@if "%1" == "" (set HW_TYPE=0) else (set HW_TYPE=%1)
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=0 -o DriveSlot0.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=1 -o DriveSlot1.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=2 -o DriveSlot2.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=3 -o DriveSlot3.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=4 -o DriveSlot4.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=5 -o DriveSlot5.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=6 -o DriveSlot6.o
@if errorlevel 1 goto exit
ca65 DriveFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=7 -o DriveSlot7.o --listing DriveFirmware.lst --list-bytes 255
@if errorlevel 1 goto exit
ld65 DriveSlot0.o DriveSlot1.o DriveSlot2.o DriveSlot3.o DriveSlot4.o DriveSlot5.o DriveSlot6.o DriveSlot7.o -o DriveFirmware.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=0 -o MenuSlot0.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=1 -o MenuSlot1.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=2 -o MenuSlot2.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=3 -o MenuSlot3.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=4 -o MenuSlot4.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=5 -o MenuSlot5.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=6 -o MenuSlot6.o
@if errorlevel 1 goto exit
ca65 MenuFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=7 -o MenuSlot7.o --listing MenuFirmware.lst --list-bytes 255
@if errorlevel 1 goto exit
ld65 MenuSlot0.o MenuSlot1.o MenuSlot2.o MenuSlot3.o MenuSlot4.o MenuSlot5.o MenuSlot6.o MenuSlot7.o -o MenuFirmware.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=0 -o CommandSlot0.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=1 -o CommandSlot1.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=2 -o CommandSlot2.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=3 -o CommandSlot3.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=4 -o CommandSlot4.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=5 -o CommandSlot5.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=6 -o CommandSlot6.o
@if errorlevel 1 goto exit
ca65 CommandFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=7 -o CommandSlot7.o --listing CommandFirmware.lst --list-bytes 255
@if errorlevel 1 goto exit
ld65 CommandSlot0.o CommandSlot1.o CommandSlot2.o CommandSlot3.o CommandSlot4.o CommandSlot5.o CommandSlot6.o CommandSlot7.o -o CommandFirmware.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=0 -o FileAccessSlot0.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=1 -o FileAccessSlot1.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=2 -o FileAccessSlot2.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=3 -o FileAccessSlot3.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=4 -o FileAccessSlot4.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=5 -o FileAccessSlot5.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=6 -o FileAccessSlot6.o
@if errorlevel 1 goto exit
ca65 FileAccessFirmware.asm -D HW_TYPE=%HW_TYPE% -D SLOT=7 -o FileAccessSlot7.o --listing FileAccessFirmware.lst --list-bytes 255
@if errorlevel 1 goto exit
ld65 FileAccessSlot0.o FileAccessSlot1.o FileAccessSlot2.o FileAccessSlot3.o FileAccessSlot4.o FileAccessSlot5.o FileAccessSlot6.o FileAccessSlot7.o -o FileAccessFirmware.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
copy /b DriveFirmware.bin + CommandFirmware.bin + FileAccessFirmware.bin + MenuFirmware.bin AT28C64B.bin
ca65 Shell.asm -D HW_TYPE=%HW_TYPE% -o Shell.o --listing Shell.lst
@if errorlevel 1 goto exit
ld65 Shell.o -o Shell.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
ca65 RPi.Command.asm -D HW_TYPE=%HW_TYPE% -o RPi.Command.o --listing RPi.Command.lst
@if errorlevel 1 goto exit
ld65 RPi.Command.o -o RPi.Command.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
ca65 Clock.Driver.asm -D HW_TYPE=%HW_TYPE% -o Clock.Driver.o --listing Clock.Driver.lst
@if errorlevel 1 goto exit
ld65 Clock.Driver.o -o Clock.Driver.bin -C ../.cicd/none.cfg
@if errorlevel 1 goto exit
cdel *.o
del DriveFirmware.bin
del MenuFirmware.bin
del CommandFirmware.bin
del FileAccessFirmware.bin
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i AT28C64B.bin -p /APPLE2.IO.RPI/AT28C64B.BIN
@if errorlevel 1 goto exit
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i Shell.bin -p /APPLE2.IO.RPI/SHELL
@if errorlevel 1 goto exit
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c put -i RPi.Command.bin -p /APPLE2.IO.RPI/RPI.COMMAND -a 0x2000
@if errorlevel 1 goto exit
ProDOS-Utilities -d ../RaspberryPi/Apple2-IO-RPi.hdv -c ls
:exit

View File

@ -1,54 +1,59 @@
#!/bin/sh
ca65 DriveFirmware.asm -D SLOT=0 -o DriveSlot0.o || exit 1
ca65 DriveFirmware.asm -D SLOT=1 -o DriveSlot1.o || exit 1
ca65 DriveFirmware.asm -D SLOT=2 -o DriveSlot2.o || exit 1
ca65 DriveFirmware.asm -D SLOT=3 -o DriveSlot3.o || exit 1
ca65 DriveFirmware.asm -D SLOT=4 -o DriveSlot4.o || exit 1
ca65 DriveFirmware.asm -D SLOT=5 -o DriveSlot5.o || exit 1
ca65 DriveFirmware.asm -D SLOT=6 -o DriveSlot6.o || exit 1
ca65 DriveFirmware.asm -D SLOT=7 -o DriveSlot7.o --listing DriveFirmware.lst --list-bytes 255 || exit 1
HW_TYPE=${1-0}
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o DriveSlot0.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o DriveSlot1.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o DriveSlot2.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o DriveSlot3.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o DriveSlot4.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o DriveSlot5.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o DriveSlot6.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o DriveSlot7.o --listing DriveFirmware.lst --list-bytes 255 || exit 1
ld65 DriveSlot0.o DriveSlot1.o DriveSlot2.o DriveSlot3.o DriveSlot4.o DriveSlot5.o DriveSlot6.o DriveSlot7.o -o DriveFirmware.bin -C ../.cicd/none.cfg || exit 1
ca65 MenuFirmware.asm -D SLOT=0 -o MenuSlot0.o || exit 1
ca65 MenuFirmware.asm -D SLOT=1 -o MenuSlot1.o || exit 1
ca65 MenuFirmware.asm -D SLOT=2 -o MenuSlot2.o || exit 1
ca65 MenuFirmware.asm -D SLOT=3 -o MenuSlot3.o || exit 1
ca65 MenuFirmware.asm -D SLOT=4 -o MenuSlot4.o || exit 1
ca65 MenuFirmware.asm -D SLOT=5 -o MenuSlot5.o || exit 1
ca65 MenuFirmware.asm -D SLOT=6 -o MenuSlot6.o || exit 1
ca65 MenuFirmware.asm -D SLOT=7 -o MenuSlot7.o --listing MenuFirmware.lst --list-bytes 255 || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o MenuSlot0.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o MenuSlot1.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o MenuSlot2.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o MenuSlot3.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o MenuSlot4.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o MenuSlot5.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o MenuSlot6.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o MenuSlot7.o --listing MenuFirmware.lst --list-bytes 255 || exit 1
ld65 MenuSlot0.o MenuSlot1.o MenuSlot2.o MenuSlot3.o MenuSlot4.o MenuSlot5.o MenuSlot6.o MenuSlot7.o -o MenuFirmware.bin -C ../.cicd/none.cfg || exit 1
ca65 CommandFirmware.asm -D SLOT=0 -o CommandSlot0.o || exit 1
ca65 CommandFirmware.asm -D SLOT=1 -o CommandSlot1.o || exit 1
ca65 CommandFirmware.asm -D SLOT=2 -o CommandSlot2.o || exit 1
ca65 CommandFirmware.asm -D SLOT=3 -o CommandSlot3.o || exit 1
ca65 CommandFirmware.asm -D SLOT=4 -o CommandSlot4.o || exit 1
ca65 CommandFirmware.asm -D SLOT=5 -o CommandSlot5.o || exit 1
ca65 CommandFirmware.asm -D SLOT=6 -o CommandSlot6.o || exit 1
ca65 CommandFirmware.asm -D SLOT=7 -o CommandSlot7.o --listing CommandFirmware.lst --list-bytes 255 || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o CommandSlot0.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o CommandSlot1.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o CommandSlot2.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o CommandSlot3.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o CommandSlot4.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o CommandSlot5.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o CommandSlot6.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o CommandSlot7.o --listing CommandFirmware.lst --list-bytes 255 || exit 1
ld65 CommandSlot0.o CommandSlot1.o CommandSlot2.o CommandSlot3.o CommandSlot4.o CommandSlot5.o CommandSlot6.o CommandSlot7.o -o CommandFirmware.bin -C ../.cicd/none.cfg || exit 1
ca65 FileAccessFirmware.asm -D SLOT=0 -o FileAccessSlot0.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=1 -o FileAccessSlot1.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=2 -o FileAccessSlot2.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=3 -o FileAccessSlot3.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=4 -o FileAccessSlot4.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=5 -o FileAccessSlot5.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=6 -o FileAccessSlot6.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=7 -o FileAccessSlot7.o --listing FileAccessFirmware.lst --list-bytes 255 || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o FileAccessSlot0.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o FileAccessSlot1.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o FileAccessSlot2.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o FileAccessSlot3.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o FileAccessSlot4.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o FileAccessSlot5.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o FileAccessSlot6.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o FileAccessSlot7.o --listing FileAccessFirmware.lst --list-bytes 255 || exit 1
ld65 FileAccessSlot0.o FileAccessSlot1.o FileAccessSlot2.o FileAccessSlot3.o FileAccessSlot4.o FileAccessSlot5.o FileAccessSlot6.o FileAccessSlot7.o -o FileAccessFirmware.bin -C ../.cicd/none.cfg || exit 1
cat \
DriveFirmware.bin CommandFirmware.bin FileAccessFirmware.bin MenuFirmware.bin \
> ../RaspberryPi/driveimage/AT28C64B.bin
ca65 Shell.asm -o Shell.o --listing Shell.lst || exit 1
ca65 Shell.asm -D HW_TYPE=$HW_TYPE -o Shell.o --listing Shell.lst || exit 1
ld65 Shell.o -o ../RaspberryPi/driveimage/Shell.bin -C ../.cicd/none.cfg || exit 1
ca65 RPi.Command.asm -o RPi.Command.o --listing RPi.Command.lst || exit 1
ca65 RPi.Command.asm -D HW_TYPE=$HW_TYPE -o RPi.Command.o --listing RPi.Command.lst || exit 1
ld65 RPi.Command.o -o ../RaspberryPi/driveimage/RPi.Command.bin -C ../.cicd/none.cfg || exit 1
ca65 Clock.Driver.asm -D HW_TYPE=$HW_TYPE -o Clock.Driver.o --listing Clock.Driver.lst || exit 1
ld65 Clock.Driver.o -o ../RaspberryPi/driveimage/Clock.Driver.bin -C ../.cicd/none.cfg || exit 1
rm ./*.o
rm DriveFirmware.bin
rm MenuFirmware.bin

View File

@ -1,52 +1,54 @@
#!/bin/sh
ca65 DriveFirmware.asm -D SLOT=0 -o DriveSlot0.o || exit 1
ca65 DriveFirmware.asm -D SLOT=1 -o DriveSlot1.o || exit 1
ca65 DriveFirmware.asm -D SLOT=2 -o DriveSlot2.o || exit 1
ca65 DriveFirmware.asm -D SLOT=3 -o DriveSlot3.o || exit 1
ca65 DriveFirmware.asm -D SLOT=4 -o DriveSlot4.o || exit 1
ca65 DriveFirmware.asm -D SLOT=5 -o DriveSlot5.o || exit 1
ca65 DriveFirmware.asm -D SLOT=6 -o DriveSlot6.o || exit 1
ca65 DriveFirmware.asm -D SLOT=7 -o DriveSlot7.o --listing DriveFirmware.lst.new --list-bytes 255 || exit 1
HW_TYPE=${1-0}
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o DriveSlot0.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o DriveSlot1.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o DriveSlot2.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o DriveSlot3.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o DriveSlot4.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o DriveSlot5.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o DriveSlot6.o || exit 1
ca65 DriveFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o DriveSlot7.o --listing DriveFirmware.lst.new --list-bytes 255 || exit 1
ld65 DriveSlot0.o DriveSlot1.o DriveSlot2.o DriveSlot3.o DriveSlot4.o DriveSlot5.o DriveSlot6.o DriveSlot7.o -o DriveFirmware.bin.new -C ../.cicd/none.cfg || exit 1
ca65 MenuFirmware.asm -D SLOT=0 -o MenuSlot0.o || exit 1
ca65 MenuFirmware.asm -D SLOT=1 -o MenuSlot1.o || exit 1
ca65 MenuFirmware.asm -D SLOT=2 -o MenuSlot2.o || exit 1
ca65 MenuFirmware.asm -D SLOT=3 -o MenuSlot3.o || exit 1
ca65 MenuFirmware.asm -D SLOT=4 -o MenuSlot4.o || exit 1
ca65 MenuFirmware.asm -D SLOT=5 -o MenuSlot5.o || exit 1
ca65 MenuFirmware.asm -D SLOT=6 -o MenuSlot6.o || exit 1
ca65 MenuFirmware.asm -D SLOT=7 -o MenuSlot7.o --listing MenuFirmware.lst.new --list-bytes 255 || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o MenuSlot0.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o MenuSlot1.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o MenuSlot2.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o MenuSlot3.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o MenuSlot4.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o MenuSlot5.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o MenuSlot6.o || exit 1
ca65 MenuFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o MenuSlot7.o --listing MenuFirmware.lst.new --list-bytes 255 || exit 1
ld65 MenuSlot0.o MenuSlot1.o MenuSlot2.o MenuSlot3.o MenuSlot4.o MenuSlot5.o MenuSlot6.o MenuSlot7.o -o MenuFirmware.bin.new -C ../.cicd/none.cfg || exit 1
ca65 CommandFirmware.asm -D SLOT=0 -o CommandSlot0.o || exit 1
ca65 CommandFirmware.asm -D SLOT=1 -o CommandSlot1.o || exit 1
ca65 CommandFirmware.asm -D SLOT=2 -o CommandSlot2.o || exit 1
ca65 CommandFirmware.asm -D SLOT=3 -o CommandSlot3.o || exit 1
ca65 CommandFirmware.asm -D SLOT=4 -o CommandSlot4.o || exit 1
ca65 CommandFirmware.asm -D SLOT=5 -o CommandSlot5.o || exit 1
ca65 CommandFirmware.asm -D SLOT=6 -o CommandSlot6.o || exit 1
ca65 CommandFirmware.asm -D SLOT=7 -o CommandSlot7.o --listing CommandFirmware.lst.new --list-bytes 255 || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o CommandSlot0.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o CommandSlot1.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o CommandSlot2.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o CommandSlot3.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o CommandSlot4.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o CommandSlot5.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o CommandSlot6.o || exit 1
ca65 CommandFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o CommandSlot7.o --listing CommandFirmware.lst.new --list-bytes 255 || exit 1
ld65 CommandSlot0.o CommandSlot1.o CommandSlot2.o CommandSlot3.o CommandSlot4.o CommandSlot5.o CommandSlot6.o CommandSlot7.o -o CommandFirmware.bin.new -C ../.cicd/none.cfg || exit 1
ca65 FileAccessFirmware.asm -D SLOT=0 -o FileAccessSlot0.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=1 -o FileAccessSlot1.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=2 -o FileAccessSlot2.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=3 -o FileAccessSlot3.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=4 -o FileAccessSlot4.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=5 -o FileAccessSlot5.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=6 -o FileAccessSlot6.o || exit 1
ca65 FileAccessFirmware.asm -D SLOT=7 -o FileAccessSlot7.o --listing FileAccessFirmware.lst.new --list-bytes 255 || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=0 -o FileAccessSlot0.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=1 -o FileAccessSlot1.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=2 -o FileAccessSlot2.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=3 -o FileAccessSlot3.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=4 -o FileAccessSlot4.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=5 -o FileAccessSlot5.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=6 -o FileAccessSlot6.o || exit 1
ca65 FileAccessFirmware.asm -D HW_TYPE=$HW_TYPE -D SLOT=7 -o FileAccessSlot7.o --listing FileAccessFirmware.lst.new --list-bytes 255 || exit 1
ld65 FileAccessSlot0.o FileAccessSlot1.o FileAccessSlot2.o FileAccessSlot3.o FileAccessSlot4.o FileAccessSlot5.o FileAccessSlot6.o FileAccessSlot7.o -o FileAccessFirmware.bin.new -C ../.cicd/none.cfg || exit 1
cat \
DriveFirmware.bin.new CommandFirmware.bin.new FileAccessFirmware.bin.new MenuFirmware.bin.new \
> AT28C64B.bin.new
ca65 Shell.asm -o Shell.o --listing Shell.lst.new || exit 1
ca65 Shell.asm -D HW_TYPE=$HW_TYPE -o Shell.o --listing Shell.lst.new || exit 1
ld65 Shell.o -o Shell.bin.new -C ../.cicd/none.cfg || exit 1
ca65 RPi.Command.asm -o RPi.Command.o --listing RPi.Command.lst.new || exit 1
ca65 RPi.Command.asm -D HW_TYPE=$HW_TYPE -o RPi.Command.o --listing RPi.Command.lst.new || exit 1
ld65 RPi.Command.o -o RPi.Command.bin.new -C ../.cicd/none.cfg || exit 1
rm ./*.o

27
ClassicSetup.md Normal file
View File

@ -0,0 +1,27 @@
## Setup starting from scratch
1. Have PCBs made from [PCBWay](https://www.pcbway.com/project/shareproject/Apple2_IO_RPi_v6_bfa4be82.html) or 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
3. If you have an EPROM programmer, it is preferred to pre-populate the EEPROM with the contents of AT28C68B.bin
4. Attach Raspberry Pi Zero 2 W facing outward from the card
5. Install [Raspberry Pi OS](https://www.raspberrypi.org/software/) on microSD card using a modern computer
1. Use Raspberry Pi Imager
2. Click "Choose OS"
3. Select Other => "Raspberry Pi OS Lite (64 bit)" for the Zero 2 W
4. Click on the gear icon in the bottom right
5. Enable ssh
6. Set password
7. Configure wifi
8. Set locale settings
6. Put microSD card in the RPi
7. Install the expansion card into the Apple II
8. Power on the Apple II
9. Only if you didn't have an EPROM programmer in step 3, install firmware with utility (can be found on Apple2-IO-RPi.hdv drive image in the release on GitHub)
10. Use `ssh` to connect to the RPi using the password you configured
11. `wget --no-cache -O - https://raw.githubusercontent.com/tjboldt/Apple2-IO-RPi/main/RaspberryPi/setup.sh | bash`
## Options
You can support two drives and change their drive images.
1. Modify the `ExecStart` line in `/etc/systemd/system/apple2driver.service` and make it something like the following: `ExecStart=/home/pi/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver -d1 /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.hdv -d2 /home/pi/Apple2-IO-RPi/RaspberryPi/TotalReplay401.hdv`
2. `sudo systemctl daemon-reload`
3. `sudo systemctl restart apple2driver.service`

23
PicoSetup.md Normal file
View File

@ -0,0 +1,23 @@
## Setup starting from scratch
1. DIY instructions and PCB coming but it is recommended to buy a board from Ralle Palaveev
2. Attach Raspberry Pi Zero 2 W with a micro USB OTG cable
3. Install [Raspberry Pi OS](https://www.raspberrypi.org/software/) on microSD card using a modern computer
1. Use Raspberry Pi Imager
2. Click "Choose OS"
3. Select Other => "Raspberry Pi OS Lite (64 bit)" for the Zero 2 W
4. Click on the gear icon in the bottom right
5. Enable ssh
6. Set password
7. Configure wifi
8. Set locale settings
6. Put microSD card in the RPi
7. Install the expansion card into the Apple II
8. Power on the Apple II
9. Use `ssh` to connect to the RPi using the password you configured
10. `wget --no-cache -O - https://raw.githubusercontent.com/tjboldt/Apple2-IO-RPi/main/RaspberryPi/setup.sh 1 | bash`
## Options
You can support two drives and change their drive images.
1. Modify the `ExecStart` line in `/etc/systemd/system/apple2driver.service` and make it something like the following: `ExecStart=/home/pi/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver -cdc=true -d1 /home/pi/Apple2-IO-RPi/RaspberryPi/Apple2-IO-RPi.hdv -d2 /home/pi/Apple2-IO-RPi/RaspberryPi/TotalReplay401.hdv`
2. `sudo systemctl daemon-reload`
3. `sudo systemctl restart apple2driver.service`

View File

@ -4,7 +4,7 @@ Apple II expansion card using a Raspberry Pi for I/O
![Image of Board](/Hardware/Apple2IORPi.jpg)
## Purpose
The purpose of this project is to provide I/O for an Apple II series 8 bit computer via a Raspberry Pi Zero W which is powered by the Apple II expansion bus. This includes using the attached RPi Zero W for it's storage, network and processor to provide new functionality for the Apple II.
The purpose of this project is to provide I/O for an Apple II series 8 bit computer via a Raspberry Pi Zero 2 W which is powered by the Apple II expansion bus. This includes using the attached RPi Zero 2 W for it's storage, network and processor to provide new functionality for the Apple II.
## Features
1. Boot message which waits for RPi to be ready
@ -16,22 +16,28 @@ The purpose of this project is to provide I/O for an Apple II series 8 bit compu
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 /"`
## Project Status
### Classic Hardware
So far, this is still a project and not a finished product. The current prototype is on the sixth revision. I have sold about 60 boards including previous prototypes. There are more than 100 in the wild between self made and ones purchased in places like eBay that were made by others. The sixth prototype is functionally equivalent to the fifth, other than a new jumper to select internal/external power.
The card enables the Apple II to boot from and write to virtual hard drive images stored on the RPi in any slot (except slot 3), execute Linux commands from Applesoft BASIC and run a bash shell with VT100 emulation. The code has very few tests and is incomplete. Note that currently the firmware assumes an 80 column card is in slot 3 and than you have lowercase support. Most development has been done with an enhanced Apple //e with the card in slot 7. If you have other drive controllers earlier in the boot cycle, you can still boot from the Apple2-IO-RPi. For example, if the card was in slot 4, you could type `PR#4` from the BASIC prompt to boot the card. Note that the Raspberry Pi Zero W (and W 2) consume 170 - 250 mA and there is only 500 mA available to all expansion slots according to Apple. It is not recommended to have a lot of other cards in the system at the same time. With the sixth revision of the prototype, it is possible to remove the power jumper and run the RPi on an external USB power source. If configured for external power, note that the card's firmware will hang on boot without USB power on as the latch chips are powered by the 3.3V output of the RPi.
If you have a problem or idea for enhancement, log an issue [here](https://github.com/tjboldt/Apple2-IO-RPi/issues) or start a [discussion](https://github.com/tjboldt/Apple2-IO-RPi/discussions/categories/general). I recommend starring/watching the project for updates on GitHub. You are welcome to fork the project and submit pull requests which I will review. The latest version has an in-memory virtual drive representing current working directory in Linux for ease of copying files between Linux and ProDOS when the drive 1 is not specified as a file.
### Pico Hardware
Ralle Palaveev has a version of the hardware that uses a RPi Pico to handle firmware and communications to the host over USB. This uses Oliver Schmidt's PIO code.
## Roadmap
See [List of issues tagged roadmap](https://github.com/tjboldt/Apple2-IO-RPi/issues?q=is%3Aissue+is%3Aopen+label%3Aroadmap+author%3Atjboldt)
## Setup
[Setup card from scratch](https://github.com/tjboldt/Apple2-IO-RPi/discussions/63)
[Setup if you received a complete board from me](https://github.com/tjboldt/Apple2-IO-RPi/discussions/64)
## Setup on classic hardware
[Setup card from scratch](/ClassicSetup.md)
[Update to latest](https://github.com/tjboldt/Apple2-IO-RPi/discussions/65)
## Setup on Pico based hardware
[Setup card with Pico hardware](/PicoSetup.md)
## Contributions/Thanks
- Hans Hübner ([@hanshuebner](https://github.com/hanshuebner)) for help cleaning up schematics
- Scott ([@figital](https://github.com/figital)) for assembling early prototypes and recommending the AT28C64B chip
@ -41,6 +47,8 @@ See [List of issues tagged roadmap](https://github.com/tjboldt/Apple2-IO-RPi/iss
- ([@Abysmal](https://github.com/Abysmal)) for shell and rpi.command testing
- ([@bfranske](https://github.com/bfranske)) for suggesting adding the 5V jumper
- Tim Boldt ([@timboldt](https://github.com/timboldt)) for recommending removing sysfs based GPIO code
- Oliver Schmidt ([@oliverschmidt](https://github.com/oliverschmidt/apple2-io-rpi/)) for writing the Pico PIO and firmware
- Ralle Palaveev ([@rallepalaveev](https://github.com/rallepalaveev/a2pico)) for Pico hardware design
## Similar Project
If you prefer having Apple II peripherals control a Raspberry Pi rather than simply using the Raspberry Pi to provide storage, network access and processing to the Apple II, have a look at David Schmenk's excellent [Apple2Pi](https://github.com/dschmenk/apple2pi) project. I am often asked about differences between these two projects. They are similar in some ways but essentially opposite. The Apple2Pi is meant for the primary machine to be the RPi, using the Apple II for it's peripherals. The Apple2-IO-RPi is meant to have the Apple II as the primary machine and just use the RPi for its processing, storage and network.

View File

@ -0,0 +1,151 @@
// Copyright Terence J. Boldt (c)2020-2022
// Use of this source code is governed by an MIT
// license that can be found in the LICENSE file.
// This file is used for communicating with the Apple II data bus via the
// GPIO ports on the Raspberry Pi
package a2io
import (
"bytes"
"errors"
"fmt"
"strings"
"time"
"go.bug.st/serial"
"go.bug.st/serial/enumerator"
)
var port serial.Port
// CDCio is a live implementation of A2Io interface
type CDCio struct {
}
// Init initializes the CDC driver on the Raspberry Pi
func (a2 CDCio) Init() {
name := ""
for {
portInfos, err := enumerator.GetDetailedPortsList()
if err == nil {
for _, portInfo := range portInfos {
if portInfo.IsUSB &&
strings.ToUpper(portInfo.VID) == "2E8A" &&
strings.ToUpper(portInfo.PID) == "000A" {
name = portInfo.Name
fmt.Printf("Found CDC port %s\n", name)
break
}
}
if name != "" {
break
}
}
time.Sleep(time.Millisecond)
}
for {
var err error
port, err = serial.Open(name, &serial.Mode{})
if err == nil {
break
}
var portErr *serial.PortError
if !errors.As(err, &portErr) ||
portErr.Code() != serial.PortNotFound &&
portErr.Code() != serial.PermissionDenied {
panic(err)
}
time.Sleep(time.Millisecond)
}
err := port.SetReadTimeout(time.Second)
if err != nil {
panic(err)
}
}
// ReadByte reads a byte from the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) ReadByte(noDelay ...bool) (byte, error) {
var data [1]byte
n, err := port.Read(data[:])
if err != nil {
return 0, err
}
if n == 0 {
return 0, errors.New("timed out reading byte")
}
return data[0], nil
}
// WriteByte writes a byte to the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) WriteByte(data byte) error {
_, err := port.Write([]byte{data})
return err
}
// ReadString reads a string from the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) ReadString() (string, error) {
var inBytes bytes.Buffer
for {
inByte, err := a2.ReadByte()
if err != nil {
return "", err
}
if inByte == 0 {
break
}
inBytes.WriteByte(inByte)
}
return inBytes.String(), nil
}
// WriteString writes a string to the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) WriteString(outString string) error {
for _, character := range outString {
err := a2.WriteByte(byte(character) | 128)
if err != nil {
fmt.Printf("Failed to write string\n")
return err
}
}
a2.WriteByte(0)
return nil
}
// WriteBlock writes 512 bytes to the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) WriteBlock(buffer []byte) error {
_, err := port.Write(buffer)
return err
}
// ReadBlock reads 512 bytes from the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) ReadBlock(buffer []byte) error {
var err error
for i := 0; i < 512; i++ {
buffer[i], err = a2.ReadByte()
if err != nil {
return err
}
}
return nil
}
// WriteBuffer writes a buffer of bytes to the Apple II via Raspberry Pi's CDC driver
func (a2 CDCio) WriteBuffer(buffer []byte) error {
_, err := port.Write(buffer)
return err
}
// SendCharacter is a pass-through to vt100 implementation
func (a2 CDCio) SendCharacter(character byte) {
sendCharacter(a2, character)
}
// ReadCharacter is a pass-through to vt100 implementation
func (a2 CDCio) ReadCharacter() (string, error) {
return readCharacter(a2)
}

View File

@ -9,12 +9,15 @@
package main
import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"time"
"go.bug.st/serial"
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/a2io"
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/drive"
"github.com/tjboldt/Apple2-IO-RPi/RaspberryPi/apple2driver/handlers"
@ -34,7 +37,7 @@ const menuCommand = 8
const shellCommand = 9
func main() {
drive1Name, drive2Name := getFlags()
drive1Name, drive2Name, cdc := getFlags()
drive1, drive2 := getDriveFiles(drive1Name, drive2Name)
driveImageDir, err := drive.GetDriveImageDirectory()
@ -44,7 +47,14 @@ func main() {
fmt.Printf("Starting Apple II RPi v%s...\n", info.Version)
comm := a2io.A2Gpio{}
var comm a2io.A2Io
if cdc {
comm = a2io.CDCio{}
fmt.Printf("Starting communications via serial port...\n")
} else {
comm = a2io.A2Gpio{}
fmt.Printf("Starting communications via GPIO ports...\n")
}
handlers.SetCommunication(comm)
comm.Init()
@ -73,6 +83,13 @@ func main() {
case shellCommand:
handlers.ShellCommand()
}
// the A2Io interface should be extended in one way or another
// to encapsulate this, e.g. by a ReadByte variant / parameter
} else if cdc {
var portErr *serial.PortError
if errors.As(err, &portErr) && portErr.Code() == serial.PortClosed {
comm.Init()
}
// temporary workaround for busy wait loop heating up the RPi
} else {
time.Sleep(time.Millisecond * 200)
@ -80,9 +97,10 @@ func main() {
}
}
func getFlags() (string, string) {
func getFlags() (string, string, bool) {
var drive1Name string
var drive2Name string
var cdc bool
execName, _ := os.Executable()
path := filepath.Dir(execName)
@ -91,9 +109,10 @@ func getFlags() (string, string) {
flag.StringVar(&drive1Name, "d1", "", "A ProDOS format drive image for drive 1")
flag.StringVar(&drive2Name, "d2", "", "A ProDOS format drive image for drive 2 and will be used for drive 1 if drive 1 empty")
flag.BoolVar(&cdc, "cdc", false, "Use ACM CDC serial device")
flag.Parse()
return drive1Name, drive2Name
return drive1Name, drive2Name, cdc
}
func getDriveFiles(drive1Name string, drive2Name string) (prodos.ReaderWriterAt, prodos.ReaderWriterAt) {

View File

@ -5,6 +5,7 @@ go 1.16
require (
github.com/creack/pty v1.1.21
github.com/stianeikeland/go-rpio/v4 v4.6.0
github.com/tjboldt/ProDOS-Utilities v0.4.8
golang.org/x/image v0.14.0 // indirect
github.com/tjboldt/ProDOS-Utilities v0.4.9
go.bug.st/serial v1.6.1
golang.org/x/sys v0.16.0 // indirect
)

View File

@ -1,15 +1,25 @@
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stianeikeland/go-rpio/v4 v4.6.0 h1:eAJgtw3jTtvn/CqwbC82ntcS+dtzUTgo5qlZKe677EY=
github.com/stianeikeland/go-rpio/v4 v4.6.0/go.mod h1:A3GvHxC1Om5zaId+HqB3HKqx4K/AqeckxB7qRjxMK7o=
github.com/tjboldt/ProDOS-Utilities v0.4.8 h1:hW4gHliqTjKCep6jXX4Z59pkVhB+OyVJPWM5X3N+ybs=
github.com/tjboldt/ProDOS-Utilities v0.4.8/go.mod h1:tk5Cd5WSoogNF+XRMjEPuWeU1vVuqdJexn23s5ev/fU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tjboldt/ProDOS-Utilities v0.4.9 h1:TkrXrm6EMcB9GDHoBtfpr0/h5G6xUQf4NVX6d1YLYvg=
github.com/tjboldt/ProDOS-Utilities v0.4.9/go.mod h1:TS0/NXtEofuAaDOhRzlrHrbGAzrJXlk9IltkLswShsc=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.bug.st/serial v1.6.1 h1:VSSWmUxlj1T/YlRo2J104Zv3wJFrjHIl/T3NeruWAHY=
go.bug.st/serial v1.6.1/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -24,7 +34,10 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -32,10 +45,12 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -49,12 +49,13 @@ func ShellCommand() {
ptmx.Close()
cmd.Wait()
comm.WriteByte(0)
return
// return
break
case <-userCancelled:
fmt.Printf("User cancelled, killing process\n")
ptmx.Close()
cmd.Process.Kill()
comm.WriteByte(0)
// comm.WriteByte(0)
return
case <-inputComplete:
fmt.Printf("Shell input complete\n")

View File

@ -8,4 +8,4 @@ package info
// Version is the hexadecimal version number that
// should be incremented with each driver update
const Version = "002C"
const Version = "002D"

Binary file not shown.

Binary file not shown.

View File

@ -21,19 +21,24 @@ if [ ! -d "ProDOS-Utilities" ]; then
git clone https://github.com/tjboldt/ProDOS-Utilities.git
fi
cd ProDOS-Utilities || exit
go mod tidy
go build
cd ~ || exit
if [ -L "/usr/bin/ProDOS-Utilities" ]; then
sudo rm /usr/bin/ProDOS-Utilities
fi
sudo ln -s /home/pi/ProDOS-Utilities/ProDOS-Utilities /usr/bin/ProDOS-Utilities
sudo ln -s $HOME/ProDOS-Utilities/ProDOS-Utilities /usr/bin/ProDOS-Utilities
if [ ! -d "Apple2-IO-RPi" ]; then
git clone https://github.com/tjboldt/Apple2-IO-RPi.git
fi
cd Apple2-IO-RPi/RaspberryPi/apple2driver || exit
go mod tidy
go build
sudo apt install cc65 vim -y
cd ~ || exit
cd Apple2-IO-RPi/Apple2 || exit
./assemble.sh $1
cd ~ || exit
sudo bash -c 'cat > /boot/config.txt << EOF
disable_splash=1
@ -41,22 +46,41 @@ dtoverlay=disable-bt
boot_delay=0
EOF'
sudo bash -c 'echo " quiet" >> /boot/cmdline.txt'
bash -c 'cat > apple2driver.service << EOF
if [ "$1" = '1' ]; then
sudo --preserve-env=HOME --preserve-env=USER bash -c 'cat > apple2driver.service << EOF
[Unit]
Description=Apple2-IO-RPi Driver
Description=Apple2-IO-RPi Driver (Pico edition)
[Service]
ExecStart=/home/$USER/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver
ExecStart=$HOME/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver -cdc=true
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=apple2driver
User=$USER
Group=$USER
WorkingDirectory=/home/$USER/Apple2-IO-RPi/RaspberryPi/apple2driver
WorkingDirectory=$HOME/Apple2-IO-RPi/RaspberryPi/apple2driver
[Install]
WantedBy=basic.target
EOF'
else
sudo --preserve-env=HOME --preserve-env=USER bash -c 'cat > apple2driver.service << EOF
[Unit]
Description=Apple2-IO-RPi Driver (Classic edition)
[Service]
ExecStart=$HOME/Apple2-IO-RPi/RaspberryPi/apple2driver/apple2driver
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=apple2driver
User=$USER
Group=$USER
WorkingDirectory=$HOME/Apple2-IO-RPi/RaspberryPi/apple2driver
[Install]
WantedBy=basic.target
EOF'
fi
sudo mv apple2driver.service /etc/systemd/system/apple2driver.service
sudo chown root:root /etc/systemd/system/apple2driver.service
sudo systemctl start apple2driver

View File

@ -0,0 +1,39 @@
set(PROJECT_NAME Apple2-IO-RPi)
cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(${PROJECT_NAME} C CXX ASM)
pico_sdk_init()
add_executable(${PROJECT_NAME})
pico_add_extra_outputs(${PROJECT_NAME})
pico_enable_stdio_uart(${PROJECT_NAME} 0)
pico_enable_stdio_usb(${PROJECT_NAME} 1)
include(FetchContent)
FetchContent_Declare(a2pico
GIT_REPOSITORY https://github.com/oliverschmidt/a2pico.git
GIT_TAG main
)
FetchContent_MakeAvailable(a2pico)
set_source_files_properties(incbin.S OBJECT_DEPENDS ../RaspberryPi/driveimage/AT28C64B.bin)
add_custom_command(
WORKING_DIRECTORY ../Apple2
COMMAND ./assemble.sh 1
OUTPUT ../RaspberryPi/driveimage/AT28C64B.bin
VERBATIM
)
target_sources(${PROJECT_NAME} PRIVATE
main.c
board.c
incbin.S
)
target_link_libraries(${PROJECT_NAME} PRIVATE
pico_stdlib
pico_multicore
a2pico
)

21
RaspberryPiPico/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1 @@
The setup.sh and build.sh are here for convenience of building the Pico code directly on the RPi Zero 2 W attached to the Apple II.

78
RaspberryPiPico/board.c Normal file
View File

@ -0,0 +1,78 @@
/*
MIT License
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pico/multicore.h>
#include <a2pico.h>
#include "board.h"
extern const __attribute__((aligned(4))) uint8_t firmware[];
static uint32_t page;
void __time_critical_func(board)(void) {
a2pico_init(pio0);
while (true) {
uint32_t pico = a2pico_getaddr(pio0);
uint32_t addr = pico & 0x0FFF;
uint32_t io = pico & 0x0F00; // IOSTRB or IOSEL
uint32_t strb = pico & 0x0800; // IOSTRB
uint32_t read = pico & 0x1000; // R/W
if (read) {
if (!io) { // DEVSEL
switch (addr & 0xF) {
case 0xB:
a2pico_putdata(pio0, !multicore_fifo_rvalid() << 7 |
!multicore_fifo_wready() << 6);
break;
case 0xE:
a2pico_putdata(pio0, sio_hw->fifo_rd);
break;
}
} else {
if (!strb) {
a2pico_putdata(pio0, firmware[page | addr]);
}
}
} else {
uint32_t data = a2pico_getdata(pio0);
if (!io) { // DEVSEL
switch (addr & 0xF) {
case 0x7:
page = (data & 0x30) << 7;
break;
case 0xD:
sio_hw->fifo_wr = data;
break;
}
}
}
}
}

32
RaspberryPiPico/board.h Normal file
View File

@ -0,0 +1,32 @@
/*
MIT License
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _BOARD_H
#define _BOARD_H
void board(void);
#endif

4
RaspberryPiPico/build.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
PICO_SDK_PATH=~/pico-sdk/ cmake .
make

6
RaspberryPiPico/incbin.S Normal file
View File

@ -0,0 +1,6 @@
.section .time_critical.firmware
.global firmware
.type firmware, %object
.balign 4
firmware:
.incbin "../RaspberryPi/driveimage/AT28C64B.bin"

92
RaspberryPiPico/main.c Normal file
View File

@ -0,0 +1,92 @@
/*
MIT License
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <stdio.h>
#include <pico/printf.h>
#include <pico/stdlib.h>
#include <pico/multicore.h>
#include "board.h"
#ifdef TRACE
void uart_printf(uart_inst_t *uart, const char *format, ...) {
static char buffer[0x100];
va_list va;
va_start(va, format);
vsnprintf(buffer, sizeof(buffer), format, va);
va_end(va);
buffer[0xFF] = '\0';
uart_puts(uart, buffer);
}
#endif
void main(void) {
multicore_launch_core1(board);
stdio_init_all();
stdio_set_translate_crlf(&stdio_usb, false);
#ifdef PICO_DEFAULT_LED_PIN
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
#endif
#ifdef TRACE
uart_init(uart0, 115200);
uart_set_translate_crlf(uart0, true);
gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART);
#endif
while (true) {
bool conn = stdio_usb_connected();
if (conn) {
if (multicore_fifo_rvalid()) {
uint32_t data = multicore_fifo_pop_blocking();
putchar(data);
#ifdef TRACE
uart_printf(uart0, "> %02X\n", data);
#endif
}
}
if (multicore_fifo_wready()) {
int data = getchar_timeout_us(0);
if (data != PICO_ERROR_TIMEOUT) {
multicore_fifo_push_blocking(data);
#ifdef TRACE
uart_printf(uart0, "< %02X\n", data);
#endif
}
}
#ifdef PICO_DEFAULT_LED_PIN
gpio_put(PICO_DEFAULT_LED_PIN, conn);
#endif
}
}

View File

@ -0,0 +1,73 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})

7
RaspberryPiPico/setup.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib -y
cd ~
git clone https://github.com/raspberrypi/pico-sdk.git
cd ~/pico-sdk/
git submodule update --init