From 08f6a7017b18d35666013b712ddb2a6fc2549fdc Mon Sep 17 00:00:00 2001 From: Zane Kaminski Date: Wed, 22 Jul 2020 00:47:25 -0400 Subject: [PATCH] Added RAM2GS functionality --- Makefile | 38 ++++-- bin/RAM2Eutil.dbg.po | Bin 143360 -> 143360 bytes bin/RAM2Eutil.po | Bin 143360 -> 143360 bytes main.c | 32 +++++ ram2e.c | 90 ++----------- ram2e.h | 6 + ram2gs.c | 173 ++++++++++++++++++++++++ ram2gs.h | 6 + ram2gs_asm.h | 8 ++ ram2gs_asm.s | 306 +++++++++++++++++++++++++++++++++++++++++++ util.c | 52 ++++++++ util.h | 12 ++ 12 files changed, 634 insertions(+), 89 deletions(-) create mode 100644 main.c create mode 100644 ram2e.h create mode 100644 ram2gs.c create mode 100644 ram2gs.h create mode 100644 ram2gs_asm.h create mode 100644 ram2gs_asm.s create mode 100644 util.c create mode 100644 util.h diff --git a/Makefile b/Makefile index 3952ec4..430ca4e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ all: RAM2Eutil.po RAM2Eutil.dbg.po -.PHONY: clean - obj: @mkdir obj bin: @mkdir bin -ram2e.c: +obj/main.o: obj main.c + cc65 main.c -O --cpu 6502 -t apple2enh -o obj/main.s + ca65 obj/main.s -o obj/main.o obj/ram2e.o: obj ram2e.c cc65 ram2e.c -O --cpu 6502 -t apple2enh -o obj/ram2e.s @@ -18,19 +18,35 @@ obj/ram2e.dbg.o: obj ram2e.c cc65 ram2e.c -O --cpu 6502 -t apple2enh -o obj/ram2e.dbg.s -DSKIP_RAM2E_DETECT ca65 obj/ram2e.dbg.s -o obj/ram2e.dbg.o -bin/ram2e.sys: bin obj/ram2e.o - ld65 -o bin/ram2e.sys obj/ram2e.o -C apple2enh-system.cfg --lib apple2enh.lib -D __EXEHDR__=0 +obj/ram2gs_asm.o: obj ram2gs_asm.s + ca65 ram2gs_asm.s -o obj/ram2gs_asm.o -bin/ram2e.dbg.sys: bin obj/ram2e.dbg.o - ld65 -o bin/ram2e.dbg.sys obj/ram2e.dbg.o -C apple2enh-system.cfg --lib apple2enh.lib -D __EXEHDR__=0 +obj/ram2gs.o: obj ram2gs.c + cc65 ram2gs.c -O --cpu 6502 -t apple2enh -o obj/ram2gs.s + ca65 obj/ram2gs.s -o obj/ram2gs.o -RAM2Eutil.po: bin/ram2e.sys +obj/ram2gs.dbg.o: obj ram2gs.c + cc65 ram2gs.c -O --cpu 6502 -t apple2enh -o obj/ram2gs.dbg.s -DSKIP_RAM2GS_DETECT + ca65 obj/ram2gs.dbg.s -o obj/ram2gs.dbg.o + +obj/util.o: obj util.c + cc65 util.c -O --cpu 6502 -t apple2enh -o obj/util.s + ca65 obj/util.s -o obj/util.o + +bin/main.sys: bin obj/main.o obj/ram2e.o obj/ram2gs.o obj/ram2gs_asm.o obj/util.o + ld65 -o bin/main.sys obj/main.o obj/ram2gs.o obj/ram2e.o obj/ram2gs_asm.o obj/util.o -C apple2enh-system.cfg --lib apple2enh.lib -D __EXEHDR__=0 + +bin/main.dbg.sys: bin obj/main.o obj/ram2e.dbg.o obj/ram2gs.dbg.o obj/ram2gs_asm.o obj/util.o + ld65 -o bin/main.dbg.sys obj/main.o obj/ram2gs.dbg.o obj/ram2e.dbg.o obj/ram2gs_asm.o obj/util.o -C apple2enh-system.cfg --lib apple2enh.lib -D __EXEHDR__=0 + +RAM2Eutil.po: bin/main.sys cp prodos140.po bin/RAM2Eutil.po - cat bin/ram2e.sys | java -jar ./AppleCommander-ac-1.6.0.jar -p bin/RAM2Eutil.po ram2e.system sys 0x2000 + cat bin/main.sys | java -jar ./AppleCommander-ac-1.6.0.jar -p bin/RAM2Eutil.po gwram.system sys 0x2000 -RAM2Eutil.dbg.po: bin/ram2e.dbg.sys +RAM2Eutil.dbg.po: bin/main.dbg.sys cp prodos140.po bin/RAM2Eutil.dbg.po - cat bin/ram2e.dbg.sys | java -jar ./AppleCommander-ac-1.6.0.jar -p bin/RAM2Eutil.dbg.po ram2e.system sys 0x2000 + cat bin/main.dbg.sys | java -jar ./AppleCommander-ac-1.6.0.jar -p bin/RAM2Eutil.dbg.po gwram.system sys 0x2000 +.PHONY: clean clean: rm -fr bin obj diff --git a/bin/RAM2Eutil.dbg.po b/bin/RAM2Eutil.dbg.po index 2f2c9cbf0f56a7ffcffc7b549ac616f5afcc5d3c..4500fbb5cb78586f6e934eb3744b30abe92b74ab 100644 GIT binary patch delta 4884 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 delta 3513 zcmZu!eRLGn6`%dgw=9q}NdxueV>j+s5;6~6K2$t5u))a(35ZpJ0g`4D2*HA1jqOen zHr*_lF<}4~mE$_HDU*{)6VbLgm9jl*%VL3P|L8eAZO_T6=R~LiBkF;QHob3_Xtdq4 z=f3-XbKkx9-Fx4=Gu(7KH=RDwY_>N&P*+`3(fotvjWu-?Ma{aXY^o-YO5WwkrKqS{KgE4G)-DdD>sql0W zKEj=|-IQiuWZt8Rz?CmOT!JOsBVWvMWjZHO%8o?N_JosTQL8s*nB@2sI1F?p9$$gS zR$`gr_a)#j&k{oMV%z2tW4Bv8xcNcjy;xK?FAd&{&#D@qo)A`Jm?l zhn5!;KE(!gK64(P`OV3nU-R-u9z8cqYn`3_R1FGqyatZmYr^o zx1zGjysVnWkfzTJ!8Ot{w9rMOn50w-gfVHHu*eo>Nr`MG%S>ch2?%w2V3SrOR6Rk zx|u};cu%VQ3dkkE+bO%cL>>WNnNyG!NA8DFXV93hp2c*Db7%reP=Qhj*TO@b&< zNP*HI%B9MQJf$#^Iq|t}F-A>t1?>iAQz`0p&rLFdrKr=LdhqX(dD0|#O)hjFLL1yp zEm@_N$P@{6I@!=CsU7M-CIQBzWlWr_C`7=9v5EnBZ+DRe$6N zw7?PAOOC)H*hDISy6-EU+d->G5vod`ijTCw(%_!1-gmbYJw!L(!AQz1ASzkV!ebpT>^p! zZouJZ1UFjZL)B1Rod`)fS6U<@puPe!1#eM z`m-D5IpSf);F&jB^=e+2D!hmQ8YK!#}lF_~I)ayWVx{*zHY zMicrfE$-h+8@IVcc`FLOLZhecqiU99IlTrSISiLPo3yJLlSc_f-F6hRGshh=C1o97 zhtJtQhX-EOBCNw&VbTqZAHy+3z|>+bEm^8&2Egx*cQnS#8B`lCg z*^@ifJ0SLaGwCfGG4s}4$rjC=Y*)R|jKD9WgcR`8D7l3V82!S2qOU4zYyf59zFb)Z?56P$E~M zEJq-gep|_2HAkX^MtlhZAwQ#*C-;NqLetUXMR&$4Ub}d8GqSScP^x z*nxctgRivXQKb$O)Fe}*wX=L3jsRt_vJR^z?s*KJc^zj&_rO7=K&5Y2jA8mFAk~vy#GE>W|<P+j}YH{(7)puW{HDduQ zr}|@)m()rR`%eKt~kRy99H8*3z0=_6`)`7Eh29^XrZ^DwIpOmegv$zdS`jI!wG=~ zVg(|0?OYvfa>Y#XzF{sL?*$SW<^qQ}HZ(-eeWd?jXt1A0MP4$48;M1i-6MS`h7y_T zJ@H=4fF-OhoaWS=Sk~0a>fuP(c9VJ96R{P^-b0a@2qf@eJUlXh6gP=G^PmTo%alKc zWXc+L3^;lneJ;_}l4EpLiz`}6j745?ON;9}Z+rR&PJ~B<{_p`Imd>2_gamLwJl^8l zSx0Lb=gz4&wI(c>?Z+KO`{Jq4XT z+K#(FTsLpCtadPQGrT^7`(zLx2Ai9@YLK0N}=ZWq57lNJ0E zSojf+M@A0v`>?PdN1-sT(L?4Wqh>-sP@cr&Phpk`*v0o-m*KirV9S7N zUCA%TYEC>{(76}`8|lo&d@hE}`{BR=l#5BXF7qjT1 zcVgSugnOO3D`9g|YHFc4Wy~q6BI}(W>6rRNVQ&@Di zmDpyzavHPE4jYwMgu*fwA8T7`G?~Thj>b~7(O=t)8k-u{!Pf+8s@brqwyCBWJy4Gx zXl!I^P;G6E_>&I180@f$J35w%M*}6I)KOy5zdgj?29}7c+L3rG;1-*9y&_6&`J%SV zC*HGrfq8ia@|{|>J7RG4&j}}7T%=!-_XKaba-lZmVY-jyh9KEfflcI zddp2%=)%ecTFZ;q`{NCMIOtRt9u0&V0-^c{D;s<)MZHlW8jK|!F)Lgy_e;yk<-#vW zcpgr$QsJB2@gitmH{qk^y6O0GU~i03XA+E>uXLSB8dRHnx8&mgNDJp_=yYdPb9~>( z{t(ySBW3HKL}&%}^d#Uf*Tj~GUOMnH8O4ix%E~U#tPkD!pNX_+2FLp_E6rXyoxl98 pYgqgEuhcE=`Xyk+{H~4G8hj4_68AmP^{Xek49_P{aa|tke*xRXDL?=K diff --git a/bin/RAM2Eutil.po b/bin/RAM2Eutil.po index d86b29dd2e2dd26d6e7851d407725089c75b1cde..7d74161507c0ea0b9366563e4893d59e144ad5c2 100644 GIT binary patch delta 4922 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 Sl`XHWY%z_G57o8ow)_W=*^6cX diff --git a/main.c b/main.c new file mode 100644 index 0000000..aca4bfe --- /dev/null +++ b/main.c @@ -0,0 +1,32 @@ +#include +#include +#include + +#include "ram2e.h" +#include "ram2gs.h" + +int main(void) +{ + // First clear screen + clrscr(); + + // Check machine type + switch ((get_ostype() & 0xF0)) { + case APPLE_IIE: + ram2e_main(); + break; + case APPLE_IIGS: + ram2gs_main(); + break; + default: + // If not on IIe or IIgs, show an error message and quit + gotoxy(0, 8); + cputs(" THIS PROGRAM REQUIRES APPLE IIE OR IIGS"); + gotoxy(0, 10); + cputs(" PRESS ANY KEY TO QUIT."); + cgetc(); // Wait for key + clrscr(); // Clear screen before quitting + return EXIT_SUCCESS; + break; + } +} diff --git a/ram2e.c b/ram2e.c index 5268dc7..efefeb6 100644 --- a/ram2e.c +++ b/ram2e.c @@ -5,20 +5,10 @@ #include #include -#define true 1 -#define false 0 +#include "util.h" - -#define VBL ((signed char*)0xC019) -const uint8_t SPIN_HALFCYCLES = 3; -const uint8_t SPIN_FRAMESPERCHAR = 4; - -#define PB0 ((char*)0xC061) -#define PB1 ((char*)0xC062) -static char read_applekey(void) { return (*PB0 | *PB1) & 0x80; } - -char _cmd; -char _arg; +static char _cmd; +static char _arg; /* ram2e_cmd(...) issues a coded command+argument sequence to the RAM2E */ static void ram2e_cmd(char cmd, char arg) { // Load operation and data bytes into X and Y registers @@ -100,7 +90,7 @@ static char auxram_detect() { } /* ram2e_detect() returns true if a RAM2E II has been detected */ -uint8_t _detect; +static uint8_t _detect; static char ram2e_detect() { #ifdef SKIP_RAM2E_DETECT return true; @@ -148,8 +138,8 @@ static char ram2e_detect() { } /* ramworks_getsize() returns the number of banks of RAM2E aux memory */ -uint8_t _rwsize; -uint8_t _rwnot16mb; +static uint8_t _rwsize; +static uint8_t _rwnot16mb; static uint16_t ramworks_getsize() { _rwnot16mb = 1; // Set "not 16 mb" flag @@ -169,11 +159,11 @@ static uint16_t ramworks_getsize() { CountLoop: __asm__("sty $C073"); // Set bank __asm__("cpy $00"); // Is bank num stored at address 0? - __asm__("bne %g", NotMem); // If not, skip increment + __asm__("bne %g", AfterInc); // If not, skip increment __asm__("inx"); // If so, increment bank count - __asm__("bne %g", NotMem); // Skip next if x!=0 + __asm__("bne %g", AfterInc); // Skip next if x!=0 __asm__("stx %v", _rwnot16mb); // Othwerwise rolled over so clear rwnot16mb - NotMem: + AfterInc: __asm__("iny"); // Move to next bank __asm__("bne %g", CountLoop); // Repeat if not on bank 0 @@ -250,67 +240,12 @@ static void menu(void) cputs("Press [Q] to quit without saving."); } -static void spin(uint8_t x, uint8_t y) { - char i; - - // Sync to frame before starting - while (*VBL >= 0); - - // Wait and animate spinner. - // Spin_half - for (i = 0; i < SPIN_HALFCYCLES; i++) { - char j; - for (j = 0; j < 4; j++) { - char spinchar; - char k; - - // Assign spinner char based on j - switch (j) { - case 0: spinchar = '\\'; break; - case 1: spinchar = '|'; break; - case 2: spinchar = '/'; break; - case 3: spinchar = '-'; break; - default: spinchar = '-'; break; - } - - // Write it to screen - gotoxy(x, y); - putchar(spinchar); - - // Wait specificed number of frames - for (k = 0; k < SPIN_FRAMESPERCHAR; k++) { - while (*VBL < 0); - while (*VBL >= 0); - } - } - } - - // Wait a frame when finished - while (*VBL < 0); - while (*VBL >= 0); -} - -int main(void) +int ram2e_main(void) { char mask; char nvm; int reset_count; - // First clear screen - clrscr(); - - // Make sure we are running on an Apple IIe - if((get_ostype() & 0xF0) != APPLE_IIE) { - // If not on Apple IIe, show an error message and quit - gotoxy(0, 8); - cputs(" THIS PROGRAM REQUIRES AN APPLE IIE."); - gotoxy(0, 10); - cputs(" PRESS ANY KEY TO QUIT."); - cgetc(); // Wait for key - clrscr(); // Clear screen before quitting - return EXIT_SUCCESS; - } - // Check for RAM2E if(!auxram_detect() || !ram2e_detect()) { // If no RAM2E, show an error message and quit @@ -331,7 +266,7 @@ int main(void) reset_count = 0; while (true) { // Set capacity mask or quit according to keypress. - switch (toupper(cgetc())) { + switch (toupper(cgetc() & 0x7F)) { case 'Q' : { clrscr(); return EXIT_SUCCESS; @@ -366,8 +301,7 @@ int main(void) } default: continue; } - // Check if pressed with apple key. - // If so, save to nonvolatile memory. + // Check if pressed with apple key. If so, save to nonvolatile memory. if (read_applekey()) { nvm = true; } break; } diff --git a/ram2e.h b/ram2e.h new file mode 100644 index 0000000..a8da674 --- /dev/null +++ b/ram2e.h @@ -0,0 +1,6 @@ +#ifndef RAM2E_H +#define RAM2E_H + +int ram2e_main(void); + +#endif /* RAM2E_H */ diff --git a/ram2gs.c b/ram2gs.c new file mode 100644 index 0000000..065f244 --- /dev/null +++ b/ram2gs.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "ram2gs_asm.h" + +static void ram2gs_erase() { ram2gs_cmd(0x28); } +static void ram2gs_program() { ram2gs_cmd(0x24); } +static void ram2gs_set4mb() { ram2gs_cmd(0x10); } +static void ram2gs_set8mb() { ram2gs_cmd(0x11); } +static void ram2gs_setnvm(char en8meg) { + char i; + // Clock in 0 to enable this setting entry + ram2gs_cmd(0x20); + ram2gs_cmd(0x22); + + if (en8meg) { + // Clock in 1 to enable 8mb + ram2gs_cmd(0x21); + ram2gs_cmd(0x23); + } else { + // Clock in 0 to disable 8mb + ram2gs_cmd(0x20); + ram2gs_cmd(0x22); + } + + // Clock in 14 dummy "1"s + for (i = 0; i < 14; i++) { + ram2gs_cmd(0x21); + ram2gs_cmd(0x23); + } + + ram2gs_program(); +} + +static void menu(void) +{ + uint8_t bankcount = ram2gs_getsize(); + gotoxy(5, 1); + cputs("-- RAM2GS Capacity Settings --"); + gotoxy(4, 3); + printf("Current RAM2GS capacity: %d kB", bankcount * 64); + + gotoxy(1, 6); + cputs("Select desired memory capacity:"); + + gotoxy(4, 8); + cputs("1. 4 megabytes"); + gotoxy(4, 10); + cputs("2. 8 megabytes"); + + gotoxy(1, 18); + cputs("Capacity will be saved until power-off."); + + gotoxy(1, 20); + cputs("To remember capacity setting in"); + gotoxy(1, 21); + cputs("nonvolatile memory, press Apple+number."); + + gotoxy(1, 23); + cputs("Press [Q] to quit without saving."); +} + +int ram2gs_main(void) +{ + char en8meg; + char nvm; + int reset_count; + + // Check for RAM2GS + #ifndef SKIP_RAM2GS_DETECT + if(!ram2gs_detect()) { + // If no RAM2GS, show an error message and quit + gotoxy(0, 8); + cputs(" No RAM2GS II detected."); + gotoxy(0, 10); + cputs(" Press any key to quit."); + cgetc(); // Wait for key + clrscr(); // Clear screen before quitting + return EXIT_SUCCESS; + } + #endif + + menu(); // Print menu + + // Get user choice from menu + en8meg = 0; + nvm = 0; + reset_count = 0; + while (true) { + // Set capacity or quit according to keypress. + switch (toupper(cgetc() & 0x7F)) { + case 'Q' : { + clrscr(); + return EXIT_SUCCESS; + } + case '!': nvm = true; + case '1': en8meg = 0; ram2gs_set4mb(); break; + case '@': nvm = true; + case '2': en8meg = 1; ram2gs_set8mb(); break; + case 'R': { + reset_count++; + if (reset_count >= 100) { + // Show message about saving. + clrscr(); // Clear screen + gotoxy(1, 8); + cputs("Resetting RAM2GS settings."); + gotoxy(1, 9); + cputs("Do not turn off your Apple."); + + ram2gs_erase(); // Erase RAM2GS settings memory + ram2gs_set8mb(); // Enable 8 megabytes now + + // Wait for >= 500ms on even the fastest systems. + spin(32, 8); + + // Show success message and quit + clrscr(); // Clear screen + gotoxy(1, 8); + cputs("RAM2GS settings reset successfully."); + goto end; + } + } default: continue; + } + + // Check if pressed with apple key. If so, save to nonvolatile memory. + if (read_applekey()) { nvm = true; } + break; + } + + // Clear screen in preparation to show saving or success message. + clrscr(); + + if (nvm) { // Save in NVM if requested. + // Show message about saving. + gotoxy(1, 8); + cputs("Saving RAM2GS capacity setting."); + gotoxy(1, 9); + cputs("Do not turn off your Apple."); + // Save capacity in nonvolatile memory. + ram2gs_setnvm(en8meg); + // Wait for >= 500ms on even the fastest systems. + spin(33, 8); + // Print success message + clrscr(); // Clear screen + gotoxy(1, 8); + cputs("RAM2GS capacity saved successfully."); + } else { // Print success message if not saving in NVM. + gotoxy(1, 8); + cputs("RAM2GS capacity set successfully."); + } + + end: + if (nvm) { // Show end message for nonvolatile save + gotoxy(1, 10); + cputs("You may now turn off your Apple."); + gotoxy(1, 12); + cputs("You may also reset your Apple for"); + gotoxy(1, 13); + cputs("the setting change to take effect."); + } else { // Show end message for volatile save + gotoxy(1, 10); + cputs("Please reset your Apple for"); + gotoxy(1, 11); + cputs("the setting change to take effect."); + } + // Don't quit. Instead leave prompt asking user to reset. + while(1) { cgetc(); } +} diff --git a/ram2gs.h b/ram2gs.h new file mode 100644 index 0000000..fd1221e --- /dev/null +++ b/ram2gs.h @@ -0,0 +1,6 @@ +#ifndef RAM2GS_H +#define RAM2GS_H + +int ram2gs_main(void); + +#endif /* RAM2GS_H */ diff --git a/ram2gs_asm.h b/ram2gs_asm.h new file mode 100644 index 0000000..fa3e6ec --- /dev/null +++ b/ram2gs_asm.h @@ -0,0 +1,8 @@ +#ifndef RAM2GS_ASM_H +#define RAM2GS_ASM_H + +uint8_t __fastcall__ ram2gs_getsize(void); +uint8_t __fastcall__ ram2gs_detect(void); +uint8_t __fastcall__ ram2gs_cmd(char cmd); + +#endif /* RAM2GS_ASM_H */ diff --git a/ram2gs_asm.s b/ram2gs_asm.s new file mode 100644 index 0000000..45f95f1 --- /dev/null +++ b/ram2gs_asm.s @@ -0,0 +1,306 @@ +.setcpu "65816" +.autoimport on +.importzp sp + +.export _ram2gs_getsize +.export _ram2gs_detect +.export _ram2gs_cmd + +.macro A8 + sep #$20 ; put the 65C816 in 8-bit accumulator mode + .A8 +.endmacro + +.macro I8 + sep #$10 ; put the 65C816 in 8-bit index register mode + .I8 +.endmacro + +.macro AI8 + sep #$30 ; put the 65C816 in 8-bit accumulator and index register mode + .A8 + .I8 +.endmacro + +.macro A16 + rep #$20 ; put the 65C816 in 8-bit accumulator mode + .A16 +.endmacro + +.macro I16 + rep #$10 ; put the 65C816 in 8-bit index register mode + .I16 +.endmacro + +.macro AI16 + rep #$30 ; put the 65C816 in 8-bit accumulator and index register mode + .A16 + .I16 +.endmacro + +.segment "CODE" + +.proc _gsram_getsize: near +.A8 +.I8 + ; Preamble + sei ; Disable interrupts + clc ; Clear carry + xce ; Clear emulation bit + php ; Push status + phb ; Push bank + AI8 + + ; Store bank number at address 0xFFFF in each bank + ldy #$7F ; Start at bank 0x7F + BankSetLoop: + phy ; Push future bank + plb ; Pull bank + lda $8000 ; Get address 0xFFFF in this bank + pha ; Save old address 0xFFFF contents + tya ; A = Y + eor #$FF ; Flip all bits + tay ; Y = A + sty $8000 ; Overwrite address 0xFFFF with bank number + eor #$FF ; Flip all bits back + tay ; Y = A + dey ; Decrement bank number + cpy #$FF ; Have we wrapped around? + bne BankSetLoop ; If not, repeat + + ; Count banks with matching bank number + ldy #$00 ; Y is bank + ldx #$00 ; X is count + CountLoop: + phy ; Push future bank + plb ; Pull bank + tya ; A = Y + eor #$FF ; Flip all bits + tay ; Y = A + cpy $8000 ; Is bank num stored at address 0xFFFF? + bne AfterInc ; If not, skip increment + inx ; If so, increment bank count + AfterInc: + eor #$FF ; Flip all bits back + tay ; Y = A + pla ; Get contents to restore + sta $8000 ; Restore address 0xFFFF in this bank + iny ; Move to next bank + cpy #$80 ; Are we at bank 0x80 yet? + bne CountLoop ; If not, repeat + + ; Postamble + plb ; Restore bank + plp ; Restore status + xce ; Restore emulation bit + cli ; Enable interrupts + txa ; Transfer bank count to A + rts +.endproc + +.proc _ram2gs_getsize: near +.A8 +.I8 + ; Preamble + sei ; Disable interrupts + clc ; Clear carry + xce ; Clear emulation bit + php ; Push status + phb ; Push bank + AI8 + + ; Go to bank 3F + ldy #$3F + phy + plb + ; Save 3F/3456 + ldx $3456 + + ; Go to bank 7F + ldy #$7F + phy + plb + ; Invert 7F/3456 + lda $3456 + eor #$FF + sta $3456 + + ; Go to bank 3F + ldy #$3F + phy + plb + ; Has 3F/3456 changed? + cpx $3456 + php + + ; Go to bank 7F + ldy #$7F + phy + plb + ; Restore 7F/3456 + eor #$FF + sta $3456 + + ; Check result + ldx #$80 + plp + beq _ram2gs_getsize_return + ldx #$40 + + ; Postamble + _ram2gs_getsize_return: + plb ; Restore bank + plp ; Restore status + xce ; Restore emulation bit + cli ; Enable interrupts + txa ; Transfer bank count to A + rts +.endproc + + +.proc _unswap: near +.A8 +.I8 + ; Save current bank and accumulator + phb + pha + ; Switch to bank 0xFB + lda #$FB + pha + plb + ; Submit C1AD + lda #$C1 + sta $FFFE + lda #$AD + sta $FFFF + ; Pull and submit command + lda #$00 + sta $FFFD + ; Restore accumulator and bank and return + pla + plb + rts +.endproc + +.proc _swap: near +.A8 +.I8 + ; Save current bank and accumulator + phb + pha + ; Switch to bank 0xFB + lda #$FB + pha + plb + ; Submit C1AD + lda #$C1 + sta $FFFE + lda #$AD + sta $FFFF + ; Pull and submit command + lda #$01 + sta $FFFD + ; Restore accumulator and bank and return + pla + plb + rts +.endproc + +.proc _ram2gs_detect: near +.A8 +.I8 + ; Preamble + sei ; Disable interrupts + clc ; Clear carry + xce ; Clear emulation bit + php ; Push status + phb ; Push bank + AI8 + + ; Switch to bank 0x3F + lda #$3F + pha + plb + + ; Unswap + jsr _unswap + ; Save unswapped 3F/8000 + lda $8000 + pha + ; Swap + jsr _swap + ; Save swapped 3F/8000 + lda $8000 + pha + + ; Store 0xFF in swapped + lda #$FF + sta $8000 + ; Verify 0xFF stored + lda $8000 + cmp #$FF + bne _ram2gs_detect_fail + + ; Unswap + jsr _unswap + ; Store 0x00 in unswapped + lda #$00 + sta $8000 + ; Verify 0x00 stored + lda $8000 + cmp #$00 + bne _ram2gs_detect_fail + + ; Swap + jsr _swap + ; Verify 0xFF stored + lda $8000 + cmp #$FF + bne _ram2gs_detect_fail + + ; Get success return value and jump to postamble + ldx #$01 ; Get success falue + bne _ram2gs_detect_return ; Jump to postamble + + ; Fail + _ram2gs_detect_fail: + ldx #$00 ; Get fail value + + ; Postamble + _ram2gs_detect_return: + jsr _swap ; Swap + pla ; Get value to restore to swapped bank 3F + sta $8000 ; Restore + jsr _unswap ; Unswap + pla ; Get value to restore to unswapped bank 3F + sta $8000 ; Restore + txa ; Put return value in accumulator + plb ; Restore bank + plp ; Restore status + xce ; Restore emulation bit + cli ; Enable interrupts + rts +.endproc + +.proc _ram2gs_cmd: near +.A8 +.I8 + ; Save current bank and command in accumulator + phb + pha + ; Switch to bank 0xFB + lda #$FB + pha + plb + ; Submit C1AD + lda #$C1 + sta $FFFE + lda #$AD + sta $FFFF + ; Pull and submit command + pla + sta $FFFD + ; Restore bank and return + plb + rts +.endproc diff --git a/util.c b/util.c new file mode 100644 index 0000000..a597700 --- /dev/null +++ b/util.c @@ -0,0 +1,52 @@ +#include "util.h" + +#include +#include +#include + +#define PB0 ((char*)0xC061) +#define PB1 ((char*)0xC062) +char read_applekey(void) { return ((*PB0) | (*PB1)) & 0x80; } + +#define VBL ((signed char*)0xC019) +#define SPIN_HALFCYCLES 3 +#define SPIN_FRAMESPERCHAR 4 +void spin(uint8_t x, uint8_t y) { + char i; + + // Sync to frame before starting + while (*VBL >= 0); + + // Wait and animate spinner. + // Spin_half + for (i = 0; i < SPIN_HALFCYCLES; i++) { + char j; + for (j = 0; j < 4; j++) { + char spinchar; + char k; + + // Assign spinner char based on j + switch (j) { + case 0: spinchar = '\\'; break; + case 1: spinchar = '|'; break; + case 2: spinchar = '/'; break; + case 3: spinchar = '-'; break; + default: spinchar = '-'; break; + } + + // Write it to screen + gotoxy(x, y); + putchar(spinchar); + + // Wait specificed number of frames + for (k = 0; k < SPIN_FRAMESPERCHAR; k++) { + while (*VBL < 0); + while (*VBL >= 0); + } + } + } + + // Wait a frame when finished + while (*VBL < 0); + while (*VBL >= 0); +} \ No newline at end of file diff --git a/util.h b/util.h new file mode 100644 index 0000000..a591b63 --- /dev/null +++ b/util.h @@ -0,0 +1,12 @@ +#include + +#ifndef UTIL_H +#define UTIL_H + +#define true 1 +#define false 0 + +char read_applekey(void); +void spin(uint8_t x, uint8_t y); + +#endif /* UTIL_H */ \ No newline at end of file