*-------------------------------- * APPLE DISK TRANSFER 1.22 * BY PAUL GUERTIN * PG@SFF.NET (ALL IN LOWER CASE) * OCTOBER 13TH, 1994 -- 1999 * DISTRIBUTE FREELY *-------------------------------- LST OFF * THIS PROGRAM TRANSFERS A 16-SECTOR DISK * TO A 140K MS-DOS FILE AND BACK. THE FILE * FORMAT IS COMPATIBLE WITH RANDY SPURLOCK'S * APL2EM EMULATOR. * SSC OR COMPATIBLE HARDWARE IS REQUIRED. * IIGS REQUIRES SSC OR COMPATIBLE CARD. * VERSION HISTORY: * VERSION 1.22 CHANGES "ABOUT" MSG * VERSION 1.21 FILLS UNREADABLE SECTORS WITH ZEROS * VERSION 1.20 * - HAS A CONFIGURATION MENU * - HAS A DIRECTORY FUNCTION * - ABORTS INSTANTLY IF USER PUSHES ESCAPE * - FIXES THE "256 RETRIES" BUG * - HAS MORE EFFICIENT CRC ROUTINES * VERSION 1.11 SETS IOBVOL TO 0 BEFORE CALLING RWTS * VERSION 1.10 ADDS THESE ENHANCEMENTS: * - DIFFERENTIAL RLE COMPRESSION TO SPEED UP TRANSFER * - 16-BIT CRC ERROR DETECTION * - AUTOMATIC RE-READS OF BAD SECTORS * VERSION 1.01 CORRECTS THE FOLLOWING BUGS: * - INITIALIZATION ROUTINE CRASHED WITH SOME CARDS * - FULL 8.3 MS-DOS FILENAMES NOW ACCEPTED * VERSION 1.00 - FIRST PUBLIC RELEASE * CONSTANTS ESC EQU $9B ;ESCAPE KEY ACK EQU $06 ;ACKNOWLEDGE NAK EQU $15 ;NEGATIVE ACKNOWLEDGE PARMNUM EQU 8 ;NUMBER OF CONFIGURABLE PARMS * ZERO PAGE LOCATIONS (ALL UNUSED BY DOS, BASIC & MONITOR) MSGPTR EQU $6 ;POINTER TO MESSAGE TEXT (2B) SECPTR EQU $8 ;POINTER TO SECTOR DATA (2B) TRKCNT EQU $1E ;COUNTS SEVEN TRACKS (1B) CRC EQU $EB ;TRACK CRC-16 (2B) PREV EQU $ED ;PREVIOUS BYTE FOR RLE (1B) YSAVE EQU $EE ;TEMP STORAGE (1B) * BIG FILES TRACKS EQU $2000 ;7 TRACKS AT 2000-8FFF (28KB) CRCTBLL EQU $9000 ;CRC LOW TABLE (256B) CRCTBLH EQU $9100 ;CRC HIGH TABLE (256B) * MONITOR STUFF CH EQU $24 ;CURSOR HORIZONTAL POSITION CV EQU $25 ;CURSOR VERTICAL POSITION BASL EQU $28 ;BASE LINE ADDRESS INVFLG EQU $32 ;INVERSE FLAG CLREOL EQU $FC9C ;CLEAR TO END OF LINE CLREOP EQU $FC42 ;CLEAR TO END OF SCREEN HOME EQU $FC58 ;CLEAR WHOLE SCREEN TABV EQU $FB5B ;SET BASL FROM A VTAB EQU $FC22 ;SET BASL FROM CV RDKEY EQU $FD0C ;CHARACTER INPUT NXTCHAR EQU $FD75 ;LINE INPUT COUT1 EQU $FDF0 ;CHARACTER OUTPUT CROUT EQU $FD8E ;OUTPUT RETURN * MESSAGES MTITLE EQU 0 ;TITLE SCREEN MCONFIG EQU 2 ;CONFIGURATION TOP OF SCREEN MCONFG2 EQU 4 ;CONFIGURATION BOTTOM OF SCREEN MPROMPT EQU 6 ;MAIN PROMPT MDIRCON EQU 8 ;CONTINUED DIRECTORY PROMPT MDIREND EQU 10 ;END OF DIRECTORY PROMPT MFRECV EQU 12 ;FILE TO RECEIVE:_ MFSEND EQU 14 ;FILE TO SEND:_ MRECV EQU 16 ;RECEIVING FILE_ (_ = SPACE) MSEND EQU 18 ;SENDING FILE_ MCONFUS EQU 20 ;NONSENSE FROM PC MNOT16 EQU 22 ;NOT A 16 SECTOR DISK MERROR EQU 24 ;ERROR: FILE_ MCANT EQU 26 ;|CAN'T BE OPENED. (| = CR) MEXISTS EQU 28 ;|ALREADY EXISTS. MNOT140 EQU 30 ;|IS NOT A 140K IMAGE. MFULL EQU 32 ;|DOESN'T FIT ON DISK. MANYKEY EQU 34 ;__ANY KEY:_ MDONT EQU 36 ;<- DO NOT CHANGE MABOUT EQU 38 ;ABOUT ADT... MTEST EQU 40 ;TESTING DISK FORMAT MPCANS EQU 42 ;AWAITING ANSWER FROM PC ********************************************************** ORG $803 JMP START ;SKIP DEFAULT PARAMETERS DEFAULT DFB 5,0,1,5,1,0,0,0 ;DEFAULT PARM VALUES *--------------------------------------------------------- * START - MAIN PROGRAM *--------------------------------------------------------- START CLD ;BINARY MODE JSR $FE84 ;NORMAL TEXT JSR $FB2F ;TEXT MODE, FULL WINDOW JSR $FE89 ;INPUT FROM KEYBOARD JSR $FE93 ;OUTPUT TO 40-COL SCREEN LDA #0 STA SECPTR ;SECPTR ALWAYS PAGE-ALIGNED STA STDDOS ;ASSUME STANDARD DOS INITIALLY LDA $B92E ;SAVE CONTENTS OF DOS STA DOSBYTE ;CHECKSUM BYTES CMP #$13 BEQ DOSOK1 ;AND DECREMENT STDDOS (MAKING DEC STDDOS ;IT NONZERO) IF THE CORRECT DOSOK1 LDA $B98A ;BYTES AREN'T THERE STA DOSBYTE+1 CMP #$B7 BEQ DOSOK2 DEC STDDOS DOSOK2 JSR MAKETBL ;MAKE CRC-16 TABLES JSR PARMDFT ;RESET PARAMETERS TO DEFAULTS JSR PARMINT ;INTERPRET PARAMETERS REDRAW JSR TITLE ;DRAW TITLE SCREEN MAINLUP LDY #MPROMPT ;SHOW MAIN PROMPT JSR SHOWMSG ;AT BOTTOM OF SCREEN JSR RDKEY ;GET ANSWER AND #$DF ;CONVERT TO UPPERCASE MOD0 BIT $C088 ;CLEAR SSC INPUT REGISTER CMP #"S" ;SEND? BNE KRECV ;NOPE, TRY RECEIVE JSR SEND ;YES, DO SEND ROUTINE JMP MAINLUP KRECV CMP #"R" ;RECEIVE? BNE KDIR ;NOPE, TRY DIR JSR RECEIVE ;YES, DO RECEIVE ROUTINE JMP MAINLUP KDIR CMP #"D" ;DIR? BNE KCONF ;NOPE, TRY CONFIGURE JSR DIR ;YES, DO DIR ROUTINE JMP REDRAW KCONF CMP #"C" ;CONFIGURE? BNE KABOUT ;NOPE, TRY ABOUT JSR CONFIG ;YES, DO CONFIGURE ROUTINE JSR PARMINT ;AND INTERPRET PARAMETERS JMP REDRAW KABOUT CMP #$9F ;ABOUT MESSAGE? ("?" KEY) BNE KQUIT ;NOPE, TRY QUIT LDY #MABOUT ;YES, SHOW MESSAGE, WAIT JSR SHOWMSG ;FOR KEY, AND RETURN JSR RDKEY JMP MAINLUP KQUIT CMP #"Q" ;QUIT? BNE MAINLUP ;NOPE, WAS A BAD KEY LDA DOSBYTE ;YES, RESTORE DOS CHECKSUM CODE STA $B92E LDA DOSBYTE+1 STA $B98A JMP $3D0 ;AND QUIT TO DOS *--------------------------------------------------------- * DIR - GET DIRECTORY FROM THE PC AND PRINT IT * PC SENDS 0,1 AFTER PAGES 1..N-1, 0,0 AFTER LAST PAGE *--------------------------------------------------------- DIR JSR HOME ;CLEAR SCREEN LDA #"D" ;SEND DIR COMMAND TO PC JSR PUTC DIRLOOP JSR GETC ;PRINT PC OUTPUT EXACTLY AS BEQ DIRSTOP ;IT ARRIVES (PC IS RESPONSIBLE ORA #$80 ;FOR FORMATTING), UNTIL 00 JSR COUT1 ;RECEIVED JMP DIRLOOP DIRSTOP JSR GETC ;GET CONTINUATION CHARACTER BNE DIRCONT ;NOT 00, THERE'S MORE LDY #MDIREND ;NO MORE FILES, WAIT FOR KEY JSR SHOWMSG ;AND RETURN JSR RDKEY RTS DIRCONT LDY #MDIRCON ;SPACE TO CONTINUE, ESC TO STOP JSR SHOWMSG JSR RDKEY EOR #ESC ;NOT ESCAPE, CONTINUE NORMALLY BNE DIR ;BY SENDING A "D" TO PC JMP PUTC ;ESCAPE, SEND 00 AND RETURN *--------------------------------------------------------- * CONFIG - ADT CONFIGURATION *--------------------------------------------------------- CONFIG JSR HOME ;CLEAR SCREEN LDY #MCONFIG ;SHOW CONFIGURATION SCREEN JSR SHOWM1 LDY #MCONFG2 JSR SHOWMSG ;IN 2 PARTS BECAUSE >256 CHARS LDY #PARMNUM-1 ;SAVE PREVIOUS PARAMETERS SAVPARM LDA PARMS,Y ;IN CASE OF ESCAPE STA OLDPARM,Y DEY BPL SAVPARM *--------------- FIRST PART: DISPLAY SCREEN -------------- REFRESH LDA #3 ;FIRST PARAMETER IS ON LINE 3 JSR TABV LDX #0 ;PARAMETER NUMBER LDY #$FF ;OFFSET INTO PARAMETER TEXT NXTLINE STX LINECNT ;SAVE CURRENT LINE LDA #15 STA CH CLC LDA PARMSIZ,X ;GET CURRENT VALUE (NEGATIVE: SBC PARMS,X ;LAST VALUE HAS CURVAL=0) STA CURVAL LDA PARMSIZ,X ;X WILL BE EACH POSSIBLE VALUE TAX ;STARTING WITH THE LAST ONE DEX VALLOOP CPX CURVAL ;X EQUAL TO CURRENT VALUE? BEQ PRINTIT ;YES, PRINT IT SKIPCHR INY ;NO, SKIP IT LDA PARMTXT,Y BNE SKIPCHR BEQ ENDVAL PRINTIT LDA LINECNT ;IF WE'RE ON THE ACTIVE LINE, CMP CURPARM ;THEN PRINT VALUE IN INVERSE BNE PRTVAL ;ELSE PRINT IT NORMALLY LDA #$3F STA INVFLG PRTVAL LDA #$A0 ;SPACE BEFORE & AFTER VALUE JSR COUT1 PRTLOOP INY ;PRINT VALUE LDA PARMTXT,Y BEQ ENDPRT JSR COUT1 JMP PRTLOOP ENDPRT LDA #$A0 JSR COUT1 LDA #$FF ;BACK TO NORMAL STA INVFLG ENDVAL DEX BPL VALLOOP ;PRINT REMAINING VALUES STY YSAVE ;CLREOL USES Y JSR CLREOL ;REMOVE GARBAGE AT EOL JSR CROUT LDY YSAVE LDX LINECNT ;INCREMENT CURRENT LINE INX CPX #PARMNUM BCC NXTLINE ;LOOP 8 TIMES LDA STDDOS ;IF NON-STANDARD DOS, WRITE BEQ GETCMD ;"DO NOT CHANGE" ON SCREEN LDA #9 ;NEXT TO THE CHECKSUMS OPTION JSR TABV LDY #23 STY CH LDY #MDONT JSR SHOWM1 *--------------- SECOND PART: CHANGE VALUES -------------- GETCMD LDA $C000 ;WAIT FOR NEXT COMMAND BPL GETCMD BIT $C010 LDX CURPARM ;CURRENT PARAMETER IN X CMP #$88 BNE NOTLEFT DEC PARMS,X ;LEFT ARROW PUSHED BPL LEFTOK ;DECREMENT CURRENT VALUE LDA PARMSIZ,X SBC #1 STA PARMS,X LEFTOK JMP REFRESH NOTLEFT CMP #$95 BNE NOTRGT LDA PARMS,X ;RIGHT ARROW PUSHED ADC #0 ;INCREMENT CURRENT VALUE CMP PARMSIZ,X BCC RIGHTOK LDA #0 RIGHTOK STA PARMS,X JMP REFRESH NOTRGT CMP #$8B BNE NOTUP DEX ;UP ARROW PUSHED BPL UPOK ;DECREMENT PARAMETER LDX #PARMNUM-1 UPOK STX CURPARM JMP REFRESH NOTUP CMP #$8A BEQ ISDOWN CMP #$A0 BNE NOTDOWN ISDOWN INX ;DOWN ARROW OR SPACE PUSHED CPX #PARMNUM ;INCREMENT PARAMETER BCC DOWNOK LDX #0 DOWNOK STX CURPARM JMP REFRESH NOTDOWN CMP #$84 BNE NOTCTLD JSR PARMDFT ;CTRL-D PUSHED, RESTORE DEFAULT NOTESC JMP REFRESH ;PARAMETERS NOTCTLD CMP #$8D BEQ ENDCFG ;RETURN PUSHED, STOP CONFIGURE CMP #ESC BNE NOTESC LDY #PARMNUM-1 ;ESCAPE PUSHED, RESTORE OLD PARMRST LDA OLDPARM,Y ;PARAMETERS AND STOP CONFIGURE STA PARMS,Y DEY BPL PARMRST ENDCFG RTS LINECNT HEX 00 ;CURRENT LINE NUMBER CURPARM HEX 00 ;ACTIVE PARAMETER CURVAL HEX 00 ;VALUE OF ACTIVE PARAMETER OLDPARM DS PARMNUM ;OLD PARAMETERS SAVED HERE *--------------------------------------------------------- * PARMINT - INTERPRET PARAMETERS *--------------------------------------------------------- PARMINT LDY PDSLOT ;GET SLOT# (0..6) INY ;NOW 1..7 TYA ORA #"0" ;CONVERT TO ASCII AND PUT STA MTSLT ;INTO TITLE SCREEN TYA ASL ASL ASL ASL ;NOW $S0 STA IOBSLT ;STORE IN IOB ADC #$89 ;NOW $89+S0 STA MOD5+1 ;SELF-MOD FOR "DRIVES ON" LDY PDRIVE ;GET DRIVE# (0..1) INY ;NOW 1..2 STY IOBDRV ;STORE IN IOB TYA ORA #"0" ;CONVERT TO ASCII AND PUT STA MTDRV ;INTO TITLE SCREEN LDY PSSC ;GET SSC SLOT# (0..6) INY ;NOW 1..7 TYA ORA #"0" ;CONVERT TO ASCII AND PUT STA MTSSC ;INTO TITLE SCREEN TYA ASL ASL ASL ASL ;NOW $S0 ADC #$88 TAX LDA #$0B ;COMMAND: NO PARITY, RTS ON, STA $C002,X ;DTR ON, NO INTERRUPTS LDY PSPEED ;CONTROL: 8 DATA BITS, 1 STOP LDA BPSCTRL,Y ;BIT, BAUD RATE DEPENDS ON STA $C003,X ;PSPEED STX MOD0+1 ;SELF-MODS FOR $C088+S0 STX MOD2+1 ;IN MAIN LOOP STX MOD4+1 ;AND IN GETC AND PUTC INX STX MOD1+1 ;SELF-MODS FOR $C089+S0 STX MOD3+1 ;IN GETC AND PUTC TYA ;GET SPEED (0..5) ASL ASL ADC PSPEED ;5*SPEED IN Y, NOW COPY TAY ;FIVE CHARACTERS INTO LDX #4 ;TITLE SCREEN PUTSPD LDA SPDTXT,Y STA MTSPD,X INY DEX BPL PUTSPD LDY #1 ;CONVERT RETRIES FROM 0..7 TRYLUP LDX PRETRY,Y ;TO 0..5,10,128 LDA TRYTBL,X STA REALTRY,Y DEY BPL TRYLUP LDX #0 ;IF PCKSUM IS 'NO', WE PATCH LDY #0 ;DOS TO IGNORE ADDRESS AND LDA PCKSUM ;DATA CHECKSUM ERRORS BNE RWTSMOD LDX DOSBYTE+1 LDY DOSBYTE RWTSMOD STX $B98A ;IS THERE AN APPLE II TODAY STY $B92E ;THAT DOESN'T HAVE >=48K RAM? RTS ;(YES) SPDTXT ASC " 003 0021 0042 0084 006900291" BPSCTRL DFB $16,$18,$1A,$1C,$1E,$1F TRYTBL DFB 0,1,2,3,4,5,10,99 *--------------------------------------------------------- * GETNAME - GET FILENAME AND SEND TO PC *--------------------------------------------------------- GETNAME STX DIRECTN ;TFR DIRECTION (0=RECV, 1=SEND) LDY PRMPTBL,X JSR SHOWMSG ;ASK FILENAME LDX #0 ;GET ANSWER AT $200 JSR NXTCHAR LDA #0 ;NULL-TERMINATE IT STA $200,X TXA BNE FNAMEOK JMP ABORT ;ABORT IF NO FILENAME FNAMEOK LDY #MTEST ;"TESTING THE DISK" JSR SHOWMSG LDA #/TRACKS ;READ TRACK 1 SECTOR 1 STA IOBBUF+1 ;TO SEE IF THERE'S A 16-SECTOR LDA #1 ;DISK IN THE DRIVE STA IOBCMD STA IOBTRK STA IOBSEC LDA #/IOB LDY #IOB JSR $3D9 BCC DISKOK ;READ SUCCESSFUL LDY #MNOT16 ;NOT 16-SECTOR DISK JSR SHOWMSG LDY #MANYKEY ;APPEND PROMPT JSR SHOWM1 JSR AWBEEP JSR RDKEY ;WAIT FOR KEY JMP ABORT ;AND ABORT DISKOK LDY #MPCANS ;"AWAITING ANSWER FROM PC" JSR SHOWMSG LDA #"R" ;LOAD ACC WITH "R" OR "S" ADC DIRECTN JSR PUTC ;AND SEND TO PC LDX #0 FNLOOP LDA $200,X ;SEND FILENAME TO PC JSR PUTC BEQ GETANS ;STOP AT NULL INX BNE FNLOOP GETANS JSR GETC ;ANSWER FROM PC SHOULD BE 0 BNE PCERROR ;THERE'S A PROBLEM JSR TITLE ;CLEAR STATUS LDX DIRECTN LDY TFRTBL,X JSR SHOWMSG ;SHOW TRANSFER MESSAGE SHOWFN LDA #2 ;AND ADD FILENAME STA MSGPTR+1 LDA #0 STA MSGPTR TAY JMP MSGLOOP ;AND RETURN THROUGH SHOWMSG PCERROR PHA ;SAVE ERROR NUMBER LDY #MERROR ;SHOW "ERROR: FILE " JSR SHOWMSG ;SHOW FILENAME JSR SHOWFN PLA TAY JSR SHOWM1 ;SHOW ERROR MESSAGE LDY #MANYKEY ;APPEND PROMPT JSR SHOWM1 JSR AWBEEP JSR RDKEY ;WAIT FOR KEY JMP ABORT ;AND RESTART DIRECTN HEX 00 PRMPTBL DFB MFRECV,MFSEND TFRTBL DFB MRECV,MSEND *--------------------------------------------------------- * RECEIVE - MAIN RECEIVE ROUTINE *--------------------------------------------------------- RECEIVE LDX #0 ;DIRECTION = PC-->APPLE JSR GETNAME ;ASK FOR FILENAME & SEND TO PC LDA #ACK ;1ST MESSAGE ALWAYS ACK STA MESSAGE LDA #0 ;START ON TRACK 0 STA IOBTRK STA ERRORS ;NO DISK ERRORS YET RECVLUP STA SAVTRK ;SAVE CURRENT TRACK LDX #1 JSR SR7TRK ;RECEIVE 7 TRACKS FROM PC LDX #2 JSR RW7TRK ;WRITE 7 TRACKS TO DISK LDA IOBTRK CMP #$23 ;REPEAT UNTIL TRACK $23 BCC RECVLUP LDA MESSAGE ;SEND LAST ACK JSR PUTC LDA ERRORS JSR PUTC ;SEND ERROR FLAG TO PC JMP AWBEEP ;BEEP AND END *--------------------------------------------------------- * SEND - MAIN SEND ROUTINE *--------------------------------------------------------- SEND LDX #1 ;DIRECTION = APPLE-->PC JSR GETNAME ;ASK FOR FILENAME & SEND TO PC LDA #ACK ;SEND INITIAL ACK JSR PUTC LDA #0 ;START ON TRACK 0 STA IOBTRK STA ERRORS ;NO DISK ERRORS YET SENDLUP STA SAVTRK ;SAVE CURRENT TRACK LDX #1 JSR RW7TRK ;READ 7 TRACKS FROM DISK LDX #0 JSR SR7TRK ;SEND 7 TRACKS TO PC LDA IOBTRK CMP #$23 ;REPEAT UNTIL TRACK $23 BCC SENDLUP LDA ERRORS JSR PUTC ;SEND ERROR FLAG TO PC JMP AWBEEP ;BEEP AND END *--------------------------------------------------------- * SR7TRK - SEND (X=0) OR RECEIVE (X=1) 7 TRACKS *--------------------------------------------------------- SR7TRK STX WHAT2DO ;X=0 FOR SEND, X=1 FOR RECEIVE LDA #7 ;DO 7 TRACKS STA TRKCNT LDA #/TRACKS ;STARTING HERE STA SECPTR+1 JSR HOMECUR ;RESET CURSOR POSITION S7TRK LDA #$F ;COUNT SECTORS FROM F TO 0 STA IOBSEC S7SEC LDX WHAT2DO ;PRINT STATUS CHARACTER LDA SRCHAR,X JSR CHROVER LDA WHAT2DO ;EXECUTE SEND OR RECEIVE BNE DORECV ;ROUTINE *------------------------ SENDING ------------------------ JSR SENDSEC ;SEND CURRENT SECTOR LDA CRC ;FOLLOWED BY CRC JSR PUTC LDA CRC+1 JSR PUTC JSR GETC ;GET RESPONSE FROM PC CMP #ACK ;IS IT ACK? BEQ SROKAY ;YES, ALL RIGHT CMP #NAK ;IS IT NAK? BEQ S7SEC ;YES, SEND AGAIN LDY #MCONFUS ;SOMETHING IS WRONG JSR SHOWMSG ;TELL BAD NEWS LDY #MANYKEY ;APPEND PROMPT JSR SHOWM1 JSR AWBEEP JSR RDKEY ;WAIT FOR KEY JMP ABORT ;AND ABORT *----------------------- RECEIVING ----------------------- DORECV LDY #0 ;CLEAR NEW SECTOR TYA CLRLOOP STA (SECPTR),Y INY BNE CLRLOOP LDA MESSAGE ;SEND RESULT OF PREV SECTOR JSR PUTC JSR RECVSEC ;RECEIVE SECTOR JSR GETC STA PCCRC ;AND CRC JSR GETC STA PCCRC+1 JSR UNDIFF ;UNCOMPRESS SECTOR LDA CRC ;CHECK RECEIVED CRC VS CMP PCCRC ;CALCULATED CRC BNE RECVERR LDA CRC+1 CMP PCCRC+1 BEQ SROKAY RECVERR LDA #NAK ;CRC ERROR, ASK FOR RESEND STA MESSAGE BNE S7SEC *------------------ BACK TO COMMON LOOP ------------------ SROKAY JSR CHRREST ;RESTORE PREVIOUS STATUS CHAR INC SECPTR+1 ;NEXT SECTOR DEC IOBSEC BPL S7SEC ;TRACK NOT FINISHED LDA TRKCNT CMP #2 ;STARTING LAST TRACK, TURN BNE NOTONE ;DRIVE ON, EXCEPT IN THE LAST LDA SAVTRK ;BLOCK CMP #$1C BEQ NOTONE MOD5 BIT $C089 NOTONE DEC TRKCNT BEQ SREND JMP S7TRK ;LOOP UNTIL 7 TRACKS DONE SREND RTS SRCHAR ASC "OI" ;STATUS CHARACTERS: OUT/IN WHAT2DO HEX 00 *--------------------------------------------------------- * SENDSEC - SEND CURRENT SECTOR WITH RLE * CRC IS COMPUTED BUT NOT SENT *--------------------------------------------------------- SENDSEC LDY #0 ;START AT FIRST BYTE STY CRC ;ZERO CRC STY CRC+1 STY PREV ;NO PREVIOUS CHARACTER SS1 LDA (SECPTR),Y ;GET BYTE TO SEND JSR UPDCRC ;UPDATE CRC TAX ;KEEP A COPY IN X SEC ;SUBTRACT FROM PREVIOUS SBC PREV STX PREV ;SAVE PREVIOUS BYTE JSR PUTC ;SEND DIFFERENCE BEQ SS3 ;WAS IT A ZERO? INY ;NO, DO NEXT BYTE BNE SS1 ;LOOP IF MORE TO DO RTS ;ELSE RETURN SS2 JSR UPDCRC SS3 INY ;ANY MORE BYTES? BEQ SS4 ;NO, IT WAS 00 UP TO END LDA (SECPTR),Y ;LOOK AT NEXT BYTE CMP PREV BEQ SS2 ;SAME AS BEFORE, CONTINUE SS4 TYA ;DIFFERENCE NOT A ZERO JSR PUTC ;SEND NEW ADDRESS BNE SS1 ;AND GO BACK TO MAIN LOOP RTS ;OR RETURN IF NO MORE BYTES *--------------------------------------------------------- * RECVSEC - RECEIVE SECTOR WITH RLE (NO TIME TO UNDIFF) *--------------------------------------------------------- RECVSEC LDY #0 ;START AT BEGINNING OF BUFFER RC1 JSR GETC ;GET DIFFERENCE BEQ RC2 ;IF ZERO, GET NEW INDEX STA (SECPTR),Y ;ELSE PUT CHAR IN BUFFER INY ;AND INCREMENT INDEX BNE RC1 ;LOOP IF NOT AT BUFFER END RTS ;ELSE RETURN RC2 JSR GETC ;GET NEW INDEX TAY ;IN Y REGISTER BNE RC1 ;LOOP IF INDEX <> 0 RTS ;ELSE RETURN *--------------------------------------------------------- * UNDIFF - FINISH RLE DECOMPRESSION AND UPDATE CRC *--------------------------------------------------------- UNDIFF LDY #0 STY CRC ;CLEAR CRC STY CRC+1 STY PREV ;INITIAL BASE IS ZERO UDLOOP LDA (SECPTR),Y ;GET NEW DIFFERENCE CLC ADC PREV ;ADD TO BASE JSR UPDCRC ;UPDATE CRC STA PREV ;THIS IS THE NEW BASE STA (SECPTR),Y ;STORE REAL BYTE INY BNE UDLOOP ;REPEAT 256 TIMES RTS *--------------------------------------------------------- * RW7TRK - READ (X=1) OR WRITE (X=2) 7 TRACKS * USES A,X,Y. IF ESCAPE, CALLS ABORT *--------------------------------------------------------- RW7TRK STX IOBCMD ;X=1 FOR READ, X=2 FOR WRITE LDA #7 ;COUNT 7 TRACKS STA TRKCNT LDA #/TRACKS ;START AT BEGINNING OF BUFFER STA IOBBUF+1 JSR HOMECUR ;RESET CURSOR POSITION NEXTTRK LDA #$F ;START AT SECTOR F (READ IS STA IOBSEC ;FASTER THIS WAY) NEXTSEC LDX IOBCMD ;GET MAX RETRIES FROM LDA REALTRY-1,X ;PARAMETER DATA STA RETRIES LDA RWCHAR-1,X ;PRINT STATUS CHARACTER JSR CHROVER RWAGAIN LDA $C000 ;CHECK KEYBOARD CMP #ESC ;ESCAPE PUSHED? BNE RWCONT ;NO, CONTINUE JMP SABORT ;YES, ABORT RWCONT LDA #/IOB ;GET IOB ADDRESS IN REGISTERS LDY #IOB JSR $3D9 ;CALL RWTS THROUGH VECTOR LDA #"." ;CARRY CLEAR MEANS NO ERROR BCC SECTOK ;NO ERROR: PUT . IN STATUS DEC RETRIES ;ERROR: SOME PATIENCE LEFT? BPL RWAGAIN ;YES, TRY AGAIN ROL ERRORS ;NO, SET ERRORS TO NONZERO JSR CLRSECT ;FILL SECTOR WITH ZEROS LDA #'*' ;AND PUT INVERSE * IN STATUS SECTOK JSR CHRADV ;PRINT SECTOR STATUS & ADVANCE INC IOBBUF+1 ;NEXT PAGE IN BUFFER DEC IOBSEC ;NEXT SECTOR BPL NEXTSEC ;LOOP UNTIL END OF TRACK INC IOBTRK ;NEXT TRACK DEC TRKCNT ;LOOP UNTIL 7 TRACKS DONE BNE NEXTTRK RTS RWCHAR ASC "RW" ;STATUS CHARACTERS: READ/WRITE RETRIES HEX 00 REALTRY HEX 00,00 ;REAL NUMBER OF RETRIES *--------------------------------------------------------- * CLRSECT - CLEAR CURRENT SECTOR *--------------------------------------------------------- CLRSECT LDA IOBBUF+1 ;POINT TO CORRECT SECTOR STA CSLOOP+2 LDY #0 ;AND FILL 256 ZEROS TYA CSLOOP STA $FF00,Y INY BNE CSLOOP RTS *--------------------------------------------------------- * HOMECUR - RESET CURSOR POSITION TO 1ST SECTOR * CHRREST - RESTORE PREVIOUS CONTENTS & ADVANCE CURSOR * CHRADV - WRITE NEW CONTENTS & ADVANCE CURSOR * ADVANCE - JUST ADVANCE CURSOR * CHROVER - JUST WRITE NEW CONTENTS *--------------------------------------------------------- HOMECUR LDY SAVTRK INY ;CURSOR ON 0TH COLUMN STY CH JSR TOPNEXT ;TOP OF 1ST COLUMN JMP CHRSAVE ;SAVE 1ST CHARACTER CHRREST LDA SAVCHR ;RESTORE OLD CHARACTER CHRADV JSR CHROVER ;OVERWRITE STATUS CHAR JSR ADVANCE ;ADVANCE CURSOR CHRSAVE LDY CH LDA (BASL),Y ;SAVE NEW CHARACTER STA SAVCHR RTS ADVANCE INC CV ;CURSOR DOWN LDA CV CMP #21 ;STILL IN DISPLAY? BCC NOWRAP ;YES, WE'RE DONE TOPNEXT INC CH ;NO, GO TO TOP OF NEXT LDA #5 ;COLUMN NOWRAP JMP TABV ;VALIDATE BASL,H CHROVER LDY CH STA (BASL),Y RTS *--------------------------------------------------------- * UPDCRC - UPDATE CRC WITH CONTENTS OF ACCUMULATOR *--------------------------------------------------------- UPDCRC PHA EOR CRC+1 TAX LDA CRC EOR CRCTBLH,X STA CRC+1 LDA CRCTBLL,X STA CRC PLA RTS *--------------------------------------------------------- * MAKETBL - MAKE CRC-16 TABLES *--------------------------------------------------------- MAKETBL LDX #0 LDY #0 CRCBYTE STX CRC ;LOW BYTE = 0 STY CRC+1 ;HIGH BYTE = INDEX LDX #8 ;FOR EACH BIT CRCBIT LDA CRC CRCBIT1 ASL ;SHIFT CRC LEFT ROL CRC+1 BCS CRCFLIP DEX ;HIGH BIT WAS CLEAR, DO NOTHING BNE CRCBIT1 BEQ CRCSAVE CRCFLIP EOR #$21 ;HIGH BIT WAS SET, FLIP BITS STA CRC ;0, 5, AND 12 LDA CRC+1 EOR #$10 STA CRC+1 DEX BNE CRCBIT LDA CRC ;STORE CRC IN TABLES CRCSAVE STA CRCTBLL,Y LDA CRC+1 STA CRCTBLH,Y INY BNE CRCBYTE ;DO NEXT BYTE RTS *--------------------------------------------------------- * PARMDFT - RESET PARAMETERS TO DEFAULT VALUES (USES AX) *--------------------------------------------------------- PARMDFT LDX #PARMNUM-1 DFTLOOP LDA DEFAULT,X STA PARMS,X DEX BPL DFTLOOP RTS *--------------------------------------------------------- * AWBEEP - CUTE TWO-TONE BEEP (USES AXY) *--------------------------------------------------------- AWBEEP LDA PSOUND ;IF SOUND OFF, RETURN NOW BNE NOBEEP LDA #$80 ;STRAIGHT FROM APPLE WRITER ][ JSR BEEP1 ;(CANNIBALISM IS THE SINCEREST LDA #$A0 ;FORM OF FLATTERY) BEEP1 LDY #$80 BEEP2 TAX BEEP3 DEX BNE BEEP3 BIT $C030 ;WHAP SPEAKER DEY BNE BEEP2 NOBEEP RTS *--------------------------------------------------------- * PUTC - SEND ACC OVER THE SERIAL LINE (AXY UNCHANGED) *--------------------------------------------------------- PUTC PHA PUTC1 LDA $C000 CMP #ESC ;ESCAPE = ABORT BEQ SABORT MOD1 LDA $C089 ;CHECK STATUS BITS AND #$70 CMP #$10 BNE PUTC1 ;OUTPUT REG FULL, LOOP PLA MOD2 STA $C088 ;PUT CHARACTER RTS *--------------------------------------------------------- * GETC - GET A CHARACTER FROM SERIAL LINE (XY UNCHANGED) *--------------------------------------------------------- GETC LDA $C000 CMP #ESC ;ESCAPE = ABORT BEQ SABORT MOD3 LDA $C089 ;CHECK STATUS BITS AND #$68 CMP #$8 BNE GETC ;INPUT REG EMPTY, LOOP MOD4 LDA $C088 ;GET CHARACTER RTS *--------------------------------------------------------- * ABORT - STOP EVERYTHING (CALL SABORT TO BEEP ALSO) *--------------------------------------------------------- SABORT JSR AWBEEP ;BEEP ABORT LDX #$FF ;POP GOES THE STACKPTR TXS BIT $C010 ;STROBE KEYBOARD JMP REDRAW ;AND RESTART *--------------------------------------------------------- * TITLE - SHOW TITLE SCREEN *--------------------------------------------------------- TITLE JSR HOME ;CLEAR SCREEN LDY #MTITLE JSR SHOWM1 ;SHOW TOP PART OF TITLE SCREEN LDX #15 ;SHOW SECTOR NUMBERS LDA #5 ;IN DECREASING ORDER STA CV ;FROM TOP TO BOTTOM SHOWSEC JSR VTAB LDA #$20 LDY #38 STA (BASL),Y LDY #0 STA (BASL),Y LDA HEXNUM,X INY STA (BASL),Y LDY #37 STA (BASL),Y INC CV DEX BPL SHOWSEC LDA #"_" ;SHOW LINE OF UNDERLINES LDX #38 ;ABOVE INVERSE TEXT SHOWUND STA $500,X DEX BPL SHOWUND RTS *--------------------------------------------------------- * SHOWMSG - SHOW NULL-TERMINATED MESSAGE #Y AT BOTTOM OF * SCREEN. CALL SHOWM1 TO SHOW ANYWHERE WITHOUT ERASING *--------------------------------------------------------- SHOWMSG STY YSAVE ;CLREOP USES Y LDA #0 STA CH ;COLUMN 0 LDA #22 ;LINE 22 JSR TABV JSR CLREOP ;CLEAR MESSAGE AREA LDY YSAVE SHOWM1 LDA MSGTBL,Y ;CALL HERE TO SHOW ANYWHERE STA MSGPTR LDA MSGTBL+1,Y STA MSGPTR+1 LDY #0 MSGLOOP LDA (MSGPTR),Y BEQ MSGEND JSR COUT1 INY BNE MSGLOOP MSGEND RTS *------------------------ MESSAGES ----------------------- MSGTBL DA MSG01,MSG02,MSG03,MSG04,MSG05,MSG06,MSG07 DA MSG08,MSG09,MSG10,MSG11,MSG12,MSG13,MSG14 DA MSG15,MSG16,MSG17,MSG18,MSG19,MSG20,MSG21 DA MSG22 MSG01 ASC "SSC:S" MTSSC ASC " ," MTSPD ASC " " INV " ADT 1.22 " ASC " DISK:S" MTSLT ASC " ,D" MTDRV ASC " ",8D,8D,8D INV " 00000000000000001111111111111111222 ",8D INV " " HEXNUM INV "0123456789ABCDEF0123456789ABCDEF012 ",8D,00 MSG02 INV " ADT CONFIGURATION ",8D,8D,8D ASC "DISK SLOT",8D ASC "DISK DRIVE",8D ASC "SSC SLOT",8D ASC "SSC SPEED",8D ASC "READ RETRIES",8D ASC "WRITE RETRIES",8D ASC "USE CHECKSUMS",8D ASC "ENABLE SOUND",00 MSG03 ASC "USE ARROWS AND SPACE TO CHANGE VALUES,",8D ASC "RETURN TO ACCEPT, CTRL-D FOR DEFAULTS.",00 MSG04 ASC "SEND, RECEIVE, DIR, CONFIGURE, QUIT? ",00 MSG05 ASC "SPACE TO CONTINUE, ESC TO STOP: ",00 MSG06 ASC "END OF DIRECTORY, TYPE SPACE: ",00 MSG07 ASC "FILE TO RECEIVE: ",00 MSG08 ASC "FILE TO SEND: ",00 MSG09 ASC "RECEIVING FILE ",00 MSG10 ASC "SENDING FILE ",00 MSG11 INV "ERROR:" ASC " NONSENSE FROM PC.",00 MSG12 INV "ERROR:" ASC " NOT A 16-SECTOR DISK.",00 MSG13 INV "ERROR:" ASC " FILE ",00 MSG14 HEX 8D ASC "CAN'T BE OPENED.",00 MSG15 HEX 8D ASC "ALREADY EXISTS.",00 MSG16 HEX 8D ASC "IS NOT A 140K IMAGE.",00 MSG17 HEX 8D ASC "DOESN'T FIT ON DISK.",00 MSG18 ASC " ANY KEY: ",00 MSG19 ASC "<- DO NOT CHANGE",00 MSG20 ASC "APPLE DISK TRANSFER 1.22 1994-10-13",8D ASC "PAUL GUERTIN (SSC COMPAT HDW REQUIRED.)",00 MSG21 ASC "TESTING DISK FORMAT.",00 MSG22 ASC "AWAITING ANSWER FROM PC.",00 *----------------------- PARAMETERS ---------------------- PARMSIZ DFB 7,2,7,6,8,8,2,2 ;#OPTIONS OF EACH PARM PARMTXT DFB "1,0,"2,0,"3,0,"4,0,"5,0,"6,0,"7,0 DFB "1,0,"2,0 DFB "1,0,"2,0,"3,0,"4,0,"5,0,"6,0,"7,0 DFB "3,"0,"0,0,"1,"2,"0,"0,0,"2,"4,"0,"0,0 DFB "4,"8,"0,"0,0,"9,"6,"0,"0,0,"1,"9,"2,"0,"0,0 DFB "0,0,"1,0,"2,0,"3,0,"4,0,"5,0,"1,"0,0,"9,"9,0 DFB "0,0,"1,0,"2,0,"3,0,"4,0,"5,0,"1,"0,0,"9,"9,0 DFB "Y,"E,"S,0,"N,"O,0 DFB "Y,"E,"S,0,"N,"O,0 PARMS PDSLOT DFB 5 ;DISK SLOT (6) PDRIVE DFB 0 ;DISK DRIVE (1) PSSC DFB 1 ;SSC SLOT (2) PSPEED DFB 5 ;SSC SPEED (19200) PRETRY DFB 1,0 ;READ/WRITE MAX RETRIES (1,0) PCKSUM DFB 0 ;USE RWTS CHECKSUMS? (Y) PSOUND DFB 0 ;SOUND AT END OF TRANSFER? (Y) *-------------------------- IOB -------------------------- IOB HEX 01 ;IOB TYPE IOBSLT HEX 60 ;SLOT*$10 IOBDRV HEX 01 ;DRIVE HEX 00 ;VOLUME IOBTRK HEX 00 ;TRACK IOBSEC HEX 00 ;SECTOR DA DCT ;DEVICE CHAR TABLE POINTER IOBBUF DA TRACKS ;SECTOR BUFFER POINTER HEX 00,00 ;UNUSED IOBCMD HEX 01 ;COMMAND (1=READ, 2=WRITE) HEX 00 ;ERROR CODE HEX FE ;ACTUAL VOLUME HEX 60 ;PREVIOUS SLOT HEX 01 ;PREVIOUS DRIVE DCT HEX 00,01,EF,D8 ;DEVICE CHARACTERISTICS TABLE *-------------------------- MISC ------------------------- DOSBYTE HEX 00,00 ;DOS BYTES CHANGED BY ADT STDDOS HEX 00 ;ZERO IF "STANDARD" DOS SAVTRK HEX 00 ;FIRST TRACK OF SEVEN SAVCHR HEX 00 ;CHAR OVERWRITTEN WITH STATUS MESSAGE HEX 00 ;SECTOR STATUS SENT TO PC PCCRC HEX 00,00 ;CRC RECEIVED FROM PC ERRORS HEX 00 ;NON0 IF AT LEAST 1 DISK ERROR