From 786617fb0334f0b88ab939561ba8fd5e2a5d33ae Mon Sep 17 00:00:00 2001 From: Terence Boldt Date: Sat, 27 Mar 2021 10:25:42 -0400 Subject: [PATCH] Update firmware to add menu --- Apple2/DriveFirmware.asm | 41 +++--- Apple2/DriveFirmware.lst | 195 ++++++++++++++++++++++++++++ Apple2/Firmware_27256_EPROM.bin | Bin 32768 -> 32768 bytes Apple2/Firmware_AT28C64B_EEPROM.bin | Bin 0 -> 8192 bytes Apple2/MenuFirmware.asm | 87 +++++++++++++ Apple2/MenuFirmware.lst | 101 ++++++++++++++ Apple2/assemble.sh | 47 ++++--- 7 files changed, 438 insertions(+), 33 deletions(-) create mode 100644 Apple2/DriveFirmware.lst create mode 100644 Apple2/Firmware_AT28C64B_EEPROM.bin create mode 100644 Apple2/MenuFirmware.asm create mode 100644 Apple2/MenuFirmware.lst diff --git a/Apple2/DriveFirmware.asm b/Apple2/DriveFirmware.asm index 873c8f8..1fd0892 100644 --- a/Apple2/DriveFirmware.asm +++ b/Apple2/DriveFirmware.asm @@ -15,34 +15,42 @@ InputByte = $c08e OutputByte = $c08d InputFlags = $c08b OutputFlags = $c087 + ReadBlockCommand = $01 WriteBlockCommand = $02 GetTimeCommand = $03 -NibbleStorage = $1d +ChangeDriveCommand = $04 +ExecCommand = $05 +LoadFileCommand = $06 +SaveFileCommand = $07 - .org STARTSLOT + .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 #$03 ; - cpx #$3C ;this one for older II's + + ldx #SLOT*$10 + stx $2b + stx Unit + +;force EPROM to second page on boot + lda #$1f ;set all flags high and page 1 of EPROM +PageJump: + sta OutputFlags,x + 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,x + jmp Driver ;load first two blocks and execute to boot -Boot: +Start: lda #$01 ;set read command sta Command - jsr $ff58 - tsx - lda $0100,x - asl - asl - asl - asl - sta $2b - sta Unit - tax - lda #$00 ;block 0 sta BlockLo sta BlockHi @@ -53,7 +61,6 @@ Boot: jmp $801 ;execute the block -;; ; ProDOS Driver code ; First check that this is the right drive Driver: @@ -177,5 +184,5 @@ 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 Driver&$00FF ;low byte of entry +.byte DriverEntry&$00FF ;low byte of entry diff --git a/Apple2/DriveFirmware.lst b/Apple2/DriveFirmware.lst new file mode 100644 index 0000000..471f8b1 --- /dev/null +++ b/Apple2/DriveFirmware.lst @@ -0,0 +1,195 @@ +ca65 V2.18 - N/A +Main file : DriveFirmware.asm +Current file: DriveFirmware.asm + +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 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 +000000r 1 .org SLOT*$100 + $C000 +00C500 1 ;ID bytes for booting and drive detection +00C500 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the +00C502 1 E0 00 cpx #$00 ; Apple Autostart ROM +00C504 1 E0 03 cpx #$03 ; +00C506 1 +00C506 1 A2 50 ldx #SLOT*$10 +00C508 1 86 2B stx $2b +00C50A 1 86 43 stx Unit +00C50C 1 +00C50C 1 ;force EPROM to second page on boot +00C50C 1 A9 1F lda #$1f ;set all flags high and page 1 of EPROM +00C50E 1 PageJump: +00C50E 1 9D 87 C0 sta OutputFlags,x +00C511 1 4C 1C C5 jmp Start ;this jump is only called if coming in from PageJump with A=$0f +00C514 1 +00C514 1 ;entry points for ProDOS +00C514 1 DriverEntry: +00C514 1 A9 0F lda #$0f ;set all flags high and page 0 of EPROM +00C516 1 9D 87 C0 sta OutputFlags,x +00C519 1 4C 32 C5 jmp Driver +00C51C 1 +00C51C 1 ;load first two blocks and execute to boot +00C51C 1 Start: +00C51C 1 A9 01 lda #$01 ;set read command +00C51E 1 85 42 sta Command +00C520 1 +00C520 1 A9 00 lda #$00 ;block 0 +00C522 1 85 46 sta BlockLo +00C524 1 85 47 sta BlockHi +00C526 1 85 44 sta BufferLo ;buffer at $800 +00C528 1 A9 08 lda #$08 +00C52A 1 85 45 sta BufferHi +00C52C 1 20 32 C5 jsr Driver ;get the block +00C52F 1 +00C52F 1 4C 01 08 jmp $801 ;execute the block +00C532 1 +00C532 1 ; ProDOS Driver code +00C532 1 ; First check that this is the right drive +00C532 1 Driver: +00C532 1 A6 43 ldx Unit +00C534 1 A5 42 lda Command; Check which command is being requested +00C536 1 F0 0C beq GetStatus ;0 = Status command +00C538 1 C9 01 cmp #ReadBlockCommand +00C53A 1 F0 10 beq ReadBlock +00C53C 1 C9 02 cmp #WriteBlockCommand +00C53E 1 F0 46 beq WriteBlock +00C540 1 38 sec ;set carry as we don't support any other commands +00C541 1 A9 53 lda #$53 ;Invalid parameter error +00C543 1 60 rts +00C544 1 +00C544 1 ; ProDOS Status Command Handler +00C544 1 GetStatus: +00C544 1 A2 FF ldx #$ff ;low byte number of blocks +00C546 1 A0 FF ldy #$ff ;high byte number of blocks +00C548 1 A9 00 lda #$0 ;zero accumulator and clear carry for success +00C54A 1 18 clc +00C54B 1 60 rts +00C54C 1 +00C54C 1 ; ProDOS Read Block Command +00C54C 1 ReadBlock: +00C54C 1 A0 00 ldy #$00 ;Get the current time on each block read for now +00C54E 1 A9 03 lda #GetTimeCommand +00C550 1 20 AE C5 jsr SendByte +00C553 1 getTimeByte: +00C553 1 20 CC C5 jsr GetByte +00C556 1 99 90 BF sta $bf90,y +00C559 1 C8 iny +00C55A 1 C0 04 cpy #$04 +00C55C 1 D0 F5 bne getTimeByte +00C55E 1 A9 01 lda #ReadBlockCommand ;read the block after setting the clock +00C560 1 20 AE C5 jsr SendByte +00C563 1 A5 46 lda BlockLo +00C565 1 20 AE C5 jsr SendByte +00C568 1 A5 47 lda BlockHi +00C56A 1 20 AE C5 jsr SendByte +00C56D 1 A0 00 ldy #$0 +00C56F 1 20 7D C5 jsr read256 +00C572 1 E6 45 inc BufferHi +00C574 1 20 7D C5 jsr read256 +00C577 1 C6 45 dec BufferHi +00C579 1 A9 00 lda #$0 ;zero accumulator and clear carry for success +00C57B 1 18 clc +00C57C 1 60 rts +00C57D 1 +00C57D 1 read256: +00C57D 1 20 CC C5 jsr GetByte +00C580 1 91 44 sta (BufferLo),y +00C582 1 C8 iny +00C583 1 D0 F8 bne read256 +00C585 1 60 rts +00C586 1 +00C586 1 ; ProDOS Write Block Command +00C586 1 WriteBlock: +00C586 1 A9 02 lda #WriteBlockCommand +00C588 1 20 AE C5 jsr SendByte +00C58B 1 A5 46 lda BlockLo +00C58D 1 20 AE C5 jsr SendByte +00C590 1 A5 47 lda BlockHi +00C592 1 20 AE C5 jsr SendByte +00C595 1 A0 00 ldy #$0 +00C597 1 20 A5 C5 jsr write256 +00C59A 1 E6 45 inc BufferHi +00C59C 1 20 A5 C5 jsr write256 +00C59F 1 C6 45 dec BufferHi +00C5A1 1 A9 00 lda #$0 ;zero accumulator and clear carry for success +00C5A3 1 18 clc +00C5A4 1 60 rts +00C5A5 1 +00C5A5 1 write256: +00C5A5 1 B1 44 lda (BufferLo),y +00C5A7 1 20 AE C5 jsr SendByte +00C5AA 1 C8 iny +00C5AB 1 D0 F8 bne write256 +00C5AD 1 60 rts +00C5AE 1 +00C5AE 1 SendByte: +00C5AE 1 48 pha +00C5AF 1 waitWrite: +00C5AF 1 BD 8B C0 lda InputFlags,x +00C5B2 1 2A rol +00C5B3 1 2A rol +00C5B4 1 B0 F9 bcs waitWrite +00C5B6 1 68 pla +00C5B7 1 9D 8D C0 sta OutputByte,x +00C5BA 1 A9 0E lda #$0e ; set bit 0 low to indicate write started +00C5BC 1 9D 87 C0 sta OutputFlags,x +00C5BF 1 finishWrite: +00C5BF 1 BD 8B C0 lda InputFlags,x +00C5C2 1 2A rol +00C5C3 1 2A rol +00C5C4 1 90 F9 bcc finishWrite +00C5C6 1 A9 0F lda #$0f +00C5C8 1 9D 87 C0 sta OutputFlags,x +00C5CB 1 60 rts +00C5CC 1 +00C5CC 1 GetByte: +00C5CC 1 A9 0D lda #$0d ;set read flag low +00C5CE 1 9D 87 C0 sta OutputFlags,x +00C5D1 1 waitRead: +00C5D1 1 BD 8B C0 lda InputFlags,x +00C5D4 1 2A rol +00C5D5 1 B0 FA bcs waitRead +00C5D7 1 BD 8E C0 lda InputByte,x +00C5DA 1 48 pha +00C5DB 1 A9 0F lda #$0f ;set all flags high +00C5DD 1 9D 87 C0 sta OutputFlags,x +00C5E0 1 finishRead: +00C5E0 1 BD 8B C0 lda InputFlags,x +00C5E3 1 2A rol +00C5E4 1 90 FA bcc finishRead +00C5E6 1 68 pla +00C5E7 1 end: +00C5E7 1 60 rts +00C5E8 1 +00C5E8 1 00 00 00 00 .repeat 251->vc; z6z)=V>>$10S0RIcLZ(88LZB3?RP23oPjb)o=8`N?b9pjE65n8ci_baF`&DDLL~U?8 zv2lMRqukqiuja;7Wt4uVRV7)PQWB+XX|^=243%bBTFoVgzGV1R{l-DEe(PYMo}EgUbx`|6d$KT6Vl&9n40>poQy?5+A^#(lD9=mT!#r|JE} zzjmc*|Kel5(eb-}N(swVSm#IF&*M*JG_YfXO5=MTnlisK@V__dz$ zGl^dp{Cb#Q?}A@vRbA%SiC-svo%nU)*PHyh&mWBA6vssz@#{V1e<1N2g5L=98(r`l ztZK;o2JsujZxFvh{6>@C@cDyroZ`5MBYvZ&{7)r*Q}CN%ezOaHlT}Tb-z0vM_)X$B ziQjDUn?8Rqj#C^Lal~)-l>fQJZwY=Y%x`tUZ?UQ+^IODk5x+(J7V%q6e#_?%#&L?{ zB98d2p7Q4v4!^5k zWxr1L4}Y_}CzC&Sue*=o(cFmoaDq)0i|gg|1e-6cv&?dF;dS}Z1j`gxR$i{YV!5T& zLizCo%PuV!*t3O&!rEFnLWbLF^Lf14PXAM${tJFBieHNrzoh>uPyYqK9>uT6ieJ+I zl&AlK--zNjV#P1%f6CK;!EZ+Ko3Y}T^gre4zu>o`_^nv+OZuPk^k4AXQT%qS_$B>M zdHOH-ohW`MR{WCwozFkW|0Dk|pMQdR zedPboBd_1>-$4Ff)ITEs->QE_{=aelMgG50|AhR1MEw`?|8c5+L;k<@|9=ei|6czG z{QuDX7yf_e`!D=|`2X_#7yf^L)&Il)hyM@%AO3$D{ePkJANv0~pa0PR*Wdkr(0}MZ z^dI^U{SWtlL;s=wo#x-5{~!JTeK-FA`Tth_2l;>G|K0O1`u`jC59t4osDD8JKj#0n zoqve=f0+L#=RbpU{V@NJ`kyfWPs~5X{J+-x*I=Ch=Ko#P{6F~r@c-fe!~ci>5C8w{ z{CCX%?VSJUcmE&y5B-P!L;s=w(0}NEaQ_YF|6~5Y*nfce|8eSn#r%K2{sHs+FAF{~z}M$@LGxy?)sLNA(Zb|0n7nu>Y@B{}7xLcyasx X;Qzz_hyM@%AO1i5fB64#_y7L`d5ap6 literal 32768 zcmeI5J!=#}9Ea}`!63esmRm%6tVsz+oXuEG+^VA;PALtq|Pz-E{c~ zS6QbKOq#gAFgG_N$X+?ZbH$Ro{8KzdZl0O{%gmD5Xtp|gnU1HM$(!5n=cDn1{xy9* z-8xN2)7|ObbUR&}?j#%8tMS^`t&`2GhZp0krxz<%yD!q$lP|Z&x9RBFCZ}1_ zWuFg!blJVjU+K7if3mB`UjH~AC2zBzJN={C(I51YpSHWp-;;FZ?>M74W8=PU_rF%$ z{`vcCef{kE;OIk^K0bPv-Mv4&PM`EYPtr&Ble3%ikJbFT`JnzYu>h=Pwrg zVVqH%v2o%rV&E^A;4hP|^!ZEim*OwQUy8q+^Op<$FwQ8>*f{Z*G4NMQ@K;G!`TUjm zEAdz2uf$)?`Ktwg7-tk`Y@GP382IZY`0J#reg0bfwfJlC*W$0|{PluAj5CTeHctF? z4E)U!{7up|K7S+rM*NNV8}T=D{${}+#u>#K8z=rI2L5&l{x<1apT8AY|Bv;O=4|KYmM`mgUl)_=SIVf}aeKh}TW6IlP{KkWbS zz9-~=?EfP;|6%_>?7!^)+5h|g8?Ni@|Jna@{?GZp-T!d@@Ag08IRWSY@_)|%o&R(G zAA$dK{y*&hpJy+@?Yxztp8H~=lnP96EM{O_x?xyzwi>uRkNSV=|9$@p z>-wqxm;c$iKKlRY|8xEq<_YNk)A=9$f6o7^82X>+{~Pun`v2(v^Zh5>*VF$m|DpcR zo_|sQ=lqBIzdrx#<^<6HFaM+e-}xW?{}G)3(f>c}zx4mp|L^;6xUSRxFaM?g-}*28 z|IUBIK0)gLnF9QFg{%_d-sQ;t>&-Xv-|NOds`v2v>%>T3g%lu#Gzs&#b zzbD+BVDkU+fAas%|H=PH;Q!439rl0b|1$sI_y2HRXa2wZm-+wJf0_U9{FnLvz5lv< z0+|0V|7HHa^IzuwN8rEQ|1<2r-2cPpJ)U$bY&2$NDe#|2Y2*`vjT)FaKly zzwN(uKj!~4|KIn&u&$5%zx-9UKe_zH@~`t3z?pUVH6ugV4qCq#m@`_Jnp7T&@msQb&iv zQFw(c(vA+r3EL{QrYxgXZOyi(t)bQony_o7p-&Y&)w_03>Wv)?^s1BA ze0}@0b7~nk>m9=yM4xTs*&jE*?%S6Re_18}8du>o>z_IXdToE3@lSjPe&8oROz$85 zu3H2D<}l>2%|0(;|n@9a8u3OjTot@*o_x4=>CImK* z7wg8E$CVr1z(1z=9qD(HekX(9L7t=f9q>Egcfjv}-wFLrX&%n>X&q6whr_VAnDW%T1@|L`Zebu#&V_o{ykkJd))`(-rMY_7K_ z%4oi^jw;K|g_rFIWmIXdtUOV-uk^ne^uP3zG(RbnU+I4{=zr;V)BJ9s{7V0uLH|oXP4m-2`IY`RgZ`I( zmgZ-L@+ Firmware_27256_EPROM.bin -rm Slot*.o -rm DriveFirmware.bin +cat \ +DriveFirmware.bin MenuFirmware.bin DriveFirmware.bin DriveFirmware.bin \ +> Firmware_AT28C64B_EEPROM.bin ca65 Rpi.Command.asm -o Rpi.Command.o ld65 Rpi.Command.o -o Rpi.Command.bin -t none -rm Rpi.Command.o + +rm *.o +rm DriveFirmware.bin +rm MenuFirmware.bin