TITLE 'Module START'›SUBTTL 'File START.AMA'›;›; This module resets flags, accepts user inputs, and›; initializes tables and pointers as required›; preparatory to execution.›;›;›;›;›; Here we clear the "accessed" flag on all›; of the system labels.›;›STARTLDX #0›:CLRL1LDA PAGTAB,X;Page addr (lo)›STA SYSBAS›INX›LDA PAGTAB,X;Page addr (hi)›STA SYSBAS+1›INX›INX›LDA PAGTAB,X;Page top›STA ADRBUF›INX›:CLRL2JSR ADRSYS›LDY #0›LDA (SYSACC),Y;Get first byte of label›AND #$7F;Clear high bit›STA (SYSACC),Y;and put it back.›DEC ADRBUF›BPL :CLRL2›INX›CPX #[PTBEND-PAGTAB]›BCC :CLRL1›;›; Initialize this and that›;›LDA #LOW LABBAS›STA LABTOP›LDA #HIGH LABBAS›STA LABTOP+1›LDA #0›STA LABCNT›STA LABCNT+1›STA FILSZ›STA FILSZ+1›LDX #3›:CLRHDSTA HEADER,X›DEX›BPL :CLRHD›STA I2OPEN›STA PROPEN›STA PROPT›STA FREEZE›LDA #$FF›STA DSKOPT›LDX #5 ;Init line numbers›LDA #' '›STA NUMBUF,X›DEX›LDA #'0'›:CLRLNSTA NUMBUF,X›DEX›BPL :CLRLN›JSR CLRLAB;Clear the external reference map›;›; Assume no disk present in drive›;›LDA #$FF›STA DISKID›;›; Display the opening logo›;›:ST1LDX #0;Select IOCB 0›STX CRSINH›LDA #PUTCHR›STA ICCOM,X›LDA LOGOL›STA ICBLL,X›STX ICBLH;Only works with IOCB 0›STX TWODR;Assume one disk drive›LDA #LOW LOGO›STA ICBAL,X›LDA #HIGH LOGO›STA ICBAH,X›JSR CIOV;Display it›JSR GETMSG;Get reply›LDA KBBUF;Nr of drives›CMP #'1'›BEQ :ST2›CMP #'2'›BNE :ST1;Bad input, try again›LDA #1;Indicate 2 drives›STA TWODR›:ST2LDX #0 ;Ask for input source›LDA #PUTCHR›STA ICCOM,X›LDA MSG1L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG1›STA ICBAL,X›LDA #HIGH MSG1›STA ICBAH,X›JSR CIOV;Display msg›LDA #0›STA CRSINH›JSR GETMSG;Get reply›LDA KBBUF;Source ID›STA SRCTYP›CMP #'F';File input?›BNE :ST5›LDA #LOW GBFIL;Set pointer for GETBYT›STA GBPTR›LDA #HIGH GBFIL›STA GBPTR+1›;›; Get input file name›;›:ST3LDX #0;IOCB 0›LDA #PUTCHR›STA ICCOM,X›LDA MSG2L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG2›STA ICBAL,X›LDA #HIGH MSG2›STA ICBAH,X›JSR CIOV›LDA #0›STA CRSINH›LDA #GETREC›STA ICCOM,X›LDA #$10›STA ICBLL,X›STX ICBLH›LDA #LOW INFLBF›STA ICBAL,X›LDA #HIGH INFLBF›STA ICBAH,X›JSR CIOV›;›; Now the input file name is in INFLBF.›;›JMP :ST60›:ST5CMP #'S';Sector input?›BEQ :ST6;Yes›JMP :ST40;No, try memory›:ST6LDA #LOW GBSEC;Set GETBYT pointer›STA GBPTR›LDA #HIGH GBSEC›STA GBPTR+1›JSR CLRSEC ;Get sector list› LDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG4L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG4›STA ICBAL,X›LDA #HIGH MSG4›STA ICBAH,X›JSR CIOV›LDA #0›STA CRSINH›:SCINPJSR GETMSG;Get a sector input›LDX #0›STX SECS;Clear sector ID›STX SECS+1›STX SECE›STX SECE+1›LDA KBBUF,X;Get first reply byte›CMP #EOL›BNE :ST10;End of list›JMP :SCEND›:ST10JSR ASCNIB;Convert to hex›BCC :ST12›JMP :SCERR;Garbage, get out›:ST12LDA KBBUF,X›JSR ASCNIB›BCS :ST14›STA KBBUF,X›INX›CPX #5›BNE :ST12›JMP :SCERR›:ST14LDY #0›STY SEQ›CMP #','›BNE :ST16›LDY #$FF›STA SEQ›JMP :ST18›:ST16CMP #EOL›BEQ :ST18›JMP :SCERR›:ST18INX›STX TEMP›DEX›DEX›LDA KBBUF,X›STA SECS›DEX›BMI :ST1A›LDA KBBUF,X›ASL A›ASL A›ASL A›ASL A›ORA SECS›STA SECS›DEX›BMI :ST1A›LDA KBBUF,X›STA SECS+1›DEX›BMI :ST1A›LDA KBBUF,X›BEQ :ST19›JMP :SCERR›:ST19DEX›BMI :ST1A›JMP :SCERR›:ST1ASEC›LDA SECS;Range check SECS›SBC #$D1;>$2D0?›LDA SECS+1›SBC #2›BCC :ST20›JMP :SCERR;Yes, error›;›; Now we have one sector number in SECS. If it's an›; individual sector we flag it in SECMAP.›;›:ST20LDA SEQ ;Sector sequence?›BNE :ST22;Yes, go get end sector›LDX SECS;No, process this one›LDY SECS+1›JSR MAPACC›LDA SECMAP,X›ORA MASK,Y›STA SECMAP,X›JMP :SCOK›;›; This is a sequence, so we get the end sector.›;›:ST22LDX TEMP›LDA KBBUF,X›JSR ASCNIB›BCC :ST24›JMP :SCERR›:ST24LDA KBBUF,X;Find end of second field›JSR ASCNIB›BCS :ST26›STA KBBUF,X›INX›CPX #$10›BNE :ST24›JMP :SCERR›:ST26CMP #EOL›BEQ :ST27›JMP :SCERR›:ST27DEX›LDA KBBUF,X›STA SECE›DEX›CPX TEMP›BCC :ST28›LDA KBBUF,X›ASL A›ASL A›ASL A›ASL A›ORA SECE›STA SECE›DEX›CPX TEMP›BCC :ST28›LDA KBBUF,X›STA SECE+1›DEX›CPX TEMP›BCC :ST28›LDA KBBUF,X›BEQ :ST27A›JMP :SCERR›:ST27ADEX›CPX TEMP›BCC :ST28›JMP :SCERR›;›; Now we have an end sector in SECE. Next we range check.›;›:ST28SEC›LDA SECE;SECE>=SECS?›SBC SECS›LDA SECE+1›SBC SECS+1›BCS :ST29;No, error›JMP :SCERR›:ST29LDA SECE;SECE<=$2D0?›SBC #$D1›LDA SECE+1›SBC #2›BCC :ST30›JMP :SCERR;No, error›;›; We have a valid sequence, so flag the sectors in SECMAP.›;›:ST30LDX SECS›LDY SECS+1›JSR MAPACC›LDA SECMAP,X›ORA MASK,Y›STA SECMAP,X›INC SECS›BNE :ST32›INC SECS+1›:ST32SEC›LDA SECE;Done?›SBC SECS›LDA SECE+1›SBC SECS+1›BCS :ST30;No, do another›;›; Sector input accepted, so say so›;›:SCOKLDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG7L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG7›STA ICBAL,X›LDA #HIGH MSG7›STA ICBAH,X›JSR CIOV›JMP :SCINP;Go back for another input›;›; Input invalid, display error msg›;›:SCERRLDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG8L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG8›STA ICBAL,X›LDA #HIGH MSG8›STA ICBAH,X›JSR CIOV›JMP :SCINP;Try again›;›; Sector list is complete, so get start address›;›:SCENDLDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG5L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG5›STA ICBAL,X›LDA #HIGH MSG5›STA ICBAH,X›JSR CIOV›LDA #0›STA CRSINH›JSR GETMSG›;›; Now we interpret the KB message as a 2-byte address.›;›:ST36STX STARST;Clear location counter init value›STX STARST+1›LDX ICBLL;Get msg size›CPX #6›BCS :SCER2;Too long, error›DEX›DEX›BMI :SCER2;EOL only, error›LDA KBBUF,X›JSR ASCNIB›BCS :SCER2;Garbage, error›STA STARST›DEX›BMI :ST38›LDA KBBUF,X›JSR ASCNIB›BCS :SCER2›ASL A›ASL A›ASL A›ASL A›ORA STARST›STA STARST›DEX›BMI :ST38›LDA KBBUF,X›JSR ASCNIB›BCS :SCER2›STA STARST+1›DEX›BMI :ST38›LDA KBBUF,X›JSR ASCNIB›BCS :SCER2›ASL A›ASL A›ASL A›ASL A›ORA STARST+1›STA STARST+1›:ST38JMP :ST60;Sector input done, move on›;›; Start address invalid, so display error msg›;›:SCER2LDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG8L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG8›STA ICBAL,X›LDA #HIGH MSG8›STA ICBAH,X›JSR CIOV›JMP :ST36;Try again›;›; Not file or sector input, try memory›;›:ST40CMP #'M';Memory?›BEQ :ST42;Yes, get inputs›JMP :ST2;Input invalid, try again›:ST42LDA #LOW GBMEM;Set GETBYT pointer›STA GBPTR›LDA #HIGH GBMEM›STA GBPTR+1›LDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG6L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG6›STA ICBAL,X›LDA #HIGH MSG6›STA ICBAH,X›JSR CIOV›LDA #0›STA CRSINH›:ST44 JSR GETMSG;Clear the addresses›LDX #0›STX OBJPTR›STX OBJPTR+1›STX BUFTOP›STX BUFTOP+1›LDA KBBUF,X;Check for valid start char›JSR ASCNIB›BCC :ST46›JMP :MERR›:ST46LDA KBBUF,X;Convert to hex›JSR ASCNIB›BCS :ST47;Found the comma?›STA KBBUF,X›INX›CPX #6›BNE :ST46›JMP :MERR;Too many characters›:ST47CMP #','›BNE :MERR›;›; We now have the start address in KBBUF in hex nibbles›;›STX TEMP;Save the comma location›LDY #0›:ST48DEX›BMI :ST49›LDA KBBUF,X›STA STARST,Y;Right nibble›DEX›BMI :ST49›LDA KBBUF,X;Left nibble›ASL A›ASL A›ASL A›ASL A›ORA STARST,Y;Merge it›STA STARST,Y›INY›CPY #2›BCC :ST48;Do it twice›;›; Now we have the memory start address in STARST.›;›:ST49LDX TEMP;Recover the comma location›LDY #0;Excessive length counter›INX›LDA KBBUF,X›JSR ASCNIB›BCS :MERR›:ST50LDA KBBUF,X›JSR ASCNIB›BCS :ST51;Found the EOL?›STA KBBUF,X›INX›INY›CPY #6›BNE :ST50›:ST51CMP #EOL;Verify EOL›BNE :MERR;Found garbage›LDY #0›:ST52DEX›CPX TEMP›BEQ :MEMOK;Finished›LDA KBBUF,X›STA BUFTOP,Y›DEX›CPX TEMP›BEQ :MEMOK›LDA KBBUF,X›ASL A›ASL A›ASL A›ASL A›ORA BUFTOP,Y›STA BUFTOP,Y›INY›CPY #2›BCC :ST52›;›; Now we have the memory end address in BUFTOP.›;›:MEMOKJMP :ST60;Done with input processing›:MERRLDX #0 ;Output error msg›LDA #PUTCHR›STA ICCOM,X›LDA MSG8L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG8›STA ICBAL,X›LDA #HIGH MSG8›STA ICBAH,X›JSR CIOV›JMP :ST44›;›; Next ask for the output file name.›;›:ST60LDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG3L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG3›STA ICBAL,X›LDA #HIGH MSG3›STA ICBAH,X›JSR CIOV›LDA #0›STA CRSINH›;›; Now get the name of the output file,append '.000'›; to it,and put it in OUTFBF.›;›:ST62JSR GETMSG;Get output file name›BMI :ST60›LDX #0›LDA KBBUF,X›CMP #EOL›BNE :ST62A›LDA #0 ;No file, turn off disk option›STA DSKOPT›JMP :ST80›:ST62ACMP #'D'›BNE :ST60›STA OUTFBF,X›INX›LDA KBBUF,X›CMP #':'›BNE :ST63›LDA TWODR›BNE :ST60›LDA KBBUF,X›STA OUTFBF,X›JMP :ST64›:ST63CLC›LDA TWODR›ADC #'1'›CMP KBBUF,X›BNE :ST60›STA OUTFBF,X›INX›LDA KBBUF,X›CMP #':'›BNE :ST60›STA OUTFBF,X›:ST64LDY #8›:ST65INX›DEY›BMI :ST66›LDA KBBUF,X›STA OUTFBF,X›CMP #EOL›BNE :ST65›:ST66LDA #'.'›STA OUTFBF,X›LDA #'0'›LDY #3›:ST67INX›STA OUTFBF,X›DEY›BNE :ST67›INX›LDA #EOL›STA OUTFBF,X›LDA #0›STA I2OPEN›LDA #1›STA NUMFIL›;›; If this is a 2-drive run, we now get the disks inserted.›;›:ST70LDA TWODR›BEQ :ST80›LDX #0›LDA #PUTCHR›STA ICCOM,X›LDA MSG12L›STA ICBLL,X›STX ICBLH›LDA #LOW MSG12›STA ICBAL,X›LDA #HIGH MSG12›STA ICBAH,X›LDA #1›STA CRSINH›JSR CIOV›JSR GETMSG›:ST80RTS›;›;›;*********************›;›; ASCNIB›;›;*********************›;›; Subroutine to convert an ASCII character to›; a hex nibble with validity check.›;›; Enter A=character›;›; Exit A=hex nibble (if valid)›; unchanged (if invalid)›;Carry=clear (if valid)›; set (if invalid)›;›PROC›ASCNIBCMP #$47›BCS :BAD›CMP #$2F›BCC :BAD›CMP #$3A›BCC :CONV›CMP #$41›BCC :BAD›:CONVSEC›SBC #'0'›CMP #$A›BCC :GOOD›SBC #7›:GOODCLC›RTS›:BADSEC›RTS›;›››