@L|}6CD l0C)HCC WhL/h `CmCDiD`  R@P1  Y0@R !L` D  C D     )16CS S)  C)D1 p p 0 C9DI pCDL~CiCDiD`TITLE 'Module BUILD'SUBTTL 'File BUILD.AMA';; This module;; (a) Flags all system locations ; referenced in the obje}ct program so; they can be transferred to the sys-; tem equate section of the output; file;; (b) Builds a table of lab}els for ; all non-system address references;;;;;;PROCBUILDLDA #1STA PASSJSR GETBYT ;Get a byte from object co}de.BCS :EXIT ;Bail out if nobyte.STA INSBUF;Save it.TAXLDA MODES,X;Get mode ID.CMP #NOP;Is it an opcode?BE}Q BUILD;No, try another one.AND #$60;Look at operand size field.BEQ BUILD;If none, forget it.JSR GETBYT;Get another }BCS :EXITSTA ADRBUF;Put in address lo byteLDX INSBUF;Look at opcode again.LDA MODES,XCMP #REL;Branch?BNE :NTRL }JSR RELADR;Yes, get the abs addrJMP BLLAB;and pass to BLLAB:NTRLCMP #IMM;Immediate mode?BEQ BUILD;Yes, try next i }nstruction;; If we get here the instruction is either absolute in; which case we need to move two operand bytes into; INS }BUF, or 0-page in which case we want one address; byte and a zero.;AND #$40;2 operand bytes?BNE :TWOBT;Yes, read anot }her.LDA #0;No, it's a 0P addressSTA ADRBUF+1JMP BLLAB:TWOBTJSR GETBYT;Get address hi byteBCS :EXITSTA ADRBUF+1};; Here we examine the address at; ADRBUF(2). If it's a system loca-; tion we flag it for equate use; if; it's a previous}ly referenced internal; address we ignore it; if it's a new internal; reference we insert the address in the ; label table}.;BLLABJSR GETSYS;System location?BCS :BLL1;No, try internalJSR FLGSYS;Yes, flag itJMP BUILD;and loop back.:BLL}1JSR GETLAB;Does a label already exist?BCC BUILD;Yes, get outJSR ENTERL;No, enter it;JSR LABMSG;Pacify the operato}rJMP BUILD;and loop back.:EXITRTS;Back to MAIN.EPROC;; (a) Flags all system locations ; referenced in the obje@TITLE 'Module START'SUBTTL 'File START.AMA';; This module resets flags, accepts user inputs, and; initializes tables an}d 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 SYSBASINXLDA PAGTAB,X;Page addr (hi)STA SYSBAS+1INXINXL}DA PAGTAB,X;Page topSTA ADRBUFINX:CLRL2JSR ADRSYSLDY #0LDA (SYSACC),Y;Get first byte of labelAND #$7F;Clear hi}gh bitSTA (SYSACC),Y;and put it back.DEC ADRBUFBPL :CLRL2INXCPX #[PTBEND-PAGTAB]BCC :CLRL1;; Initialize this a}nd that;LDA #LOW LABBASSTA LABTOPLDA #HIGH LABBASSTA LABTOP+1LDA #0STA LABCNTSTA LABCNT+1STA FILSZSTA FILS}Z+1LDX #3:CLRHDSTA HEADER,XDEXBPL :CLRHDSTA I2OPENSTA PROPENSTA PROPTSTA FREEZELDA #$FFSTA DSKOPTLDX #5} ;Init line numbersLDA #' 'STA NUMBUF,XDEXLDA #'0':CLRLNSTA NUMBUF,XDEXBPL :CLRLNJSR CLRLAB;Clear the exte}rnal reference map;; Assume no disk present in drive;LDA #$FFSTA DISKID;; Display the opening logo;:ST1LDX #0;Se}lect IOCB 0STX CRSINHLDA #PUTCHRSTA ICCOM,XLDA LOGOLSTA ICBLL,XSTX ICBLH;Only works with IOCB 0STX TWODR;Assu}me one disk driveLDA #LOW LOGOSTA ICBAL,XLDA #HIGH LOGOSTA ICBAH,XJSR CIOV;Display itJSR GETMSG;Get replyLDA }KBBUF;Nr of drivesCMP #'1'BEQ :ST2CMP #'2'BNE :ST1;Bad input, try againLDA #1;Indicate 2 drivesSTA TWODR:ST2}LDX #0 ;Ask for input sourceLDA #PUTCHRSTA ICCOM,XLDA MSG1LSTA ICBLL,XSTX ICBLHLDA #LOW MSG1STA ICBAL,XLDA # }HIGH MSG1STA ICBAH,XJSR CIOV;Display msgLDA #0STA CRSINHJSR GETMSG;Get replyLDA KBBUF;Source IDSTA SRCTYPC!}MP #'F';File input?BNE :ST5LDA #LOW GBFIL;Set pointer for GETBYTSTA GBPTRLDA #HIGH GBFILSTA GBPTR+1;; Get input"} file name;:ST3LDX #0;IOCB 0LDA #PUTCHRSTA ICCOM,XLDA MSG2LSTA ICBLL,XSTX ICBLHLDA #LOW MSG2STA ICBAL,XLD#}A #HIGH MSG2STA ICBAH,XJSR CIOVLDA #0STA CRSINHLDA #GETRECSTA ICCOM,XLDA #$10STA ICBLL,XSTX ICBLHLDA #LOW$} INFLBFSTA ICBAL,XLDA #HIGH INFLBFSTA ICBAH,XJSR CIOV;; Now the input file name is in INFLBF.;JMP :ST60:ST5CMP%} #'S';Sector input?BEQ :ST6;YesJMP :ST40;No, try memory:ST6LDA #LOW GBSEC;Set GETBYT pointerSTA GBPTRLDA #HIGH &}GBSECSTA GBPTR+1JSR CLRSEC ;Get sector list LDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG4LSTA ICBLL,XSTX ICBLHLD'}A #LOW MSG4STA ICBAL,XLDA #HIGH MSG4STA ICBAH,XJSR CIOVLDA #0STA CRSINH:SCINPJSR GETMSG;Get a sector inputLD(}X #0STX SECS;Clear sector IDSTX SECS+1STX SECESTX SECE+1LDA KBBUF,X;Get first reply byteCMP #EOLBNE :ST10;En)}d of listJMP :SCEND:ST10JSR ASCNIB;Convert to hexBCC :ST12JMP :SCERR;Garbage, get out:ST12LDA KBBUF,XJSR ASCNIB*}BCS :ST14STA KBBUF,XINXCPX #5BNE :ST12JMP :SCERR:ST14LDY #0STY SEQCMP #','BNE :ST16LDY #$FFSTA SEQJ+}MP :ST18:ST16CMP #EOLBEQ :ST18JMP :SCERR:ST18INXSTX TEMPDEXDEXLDA KBBUF,XSTA SECSDEXBMI :ST1ALDA KBBU,}F,XASL AASL AASL AASL AORA SECSSTA SECSDEXBMI :ST1ALDA KBBUF,XSTA SECS+1DEXBMI :ST1ALDA KBBUF,XBE-}Q :ST19JMP :SCERR:ST19DEXBMI :ST1AJMP :SCERR:ST1ASECLDA SECS;Range check SECSSBC #$D1;>$2D0?LDA SECS+1SBC.} #2BCC :ST20JMP :SCERR;Yes, error;; Now we have one sector number in SECS. If it's an; individual sector we flag it i/}n SECMAP.;:ST20LDA SEQ ;Sector sequence?BNE :ST22;Yes, go get end sectorLDX SECS;No, process this oneLDY SECS+10}JSR MAPACCLDA SECMAP,XORA MASK,YSTA SECMAP,XJMP :SCOK;; This is a sequence, so we get the end sector.;:ST22LDX 1}TEMPLDA KBBUF,XJSR ASCNIBBCC :ST24JMP :SCERR:ST24LDA KBBUF,X;Find end of second fieldJSR ASCNIBBCS :ST26STA 2}KBBUF,XINXCPX #$10BNE :ST24JMP :SCERR:ST26CMP #EOLBEQ :ST27JMP :SCERR:ST27DEXLDA KBBUF,XSTA SECEDEXCP3}X TEMPBCC :ST28LDA KBBUF,XASL AASL AASL AASL AORA SECESTA SECEDEXCPX TEMPBCC :ST28LDA KBBUF,XSTA SE4}CE+1DEXCPX TEMPBCC :ST28LDA KBBUF,XBEQ :ST27AJMP :SCERR:ST27ADEXCPX TEMPBCC :ST28JMP :SCERR;; Now we ha5}ve an end sector in SECE. Next we range check.;:ST28SECLDA SECE;SECE>=SECS?SBC SECSLDA SECE+1SBC SECS+1BCS :ST26}9;No, errorJMP :SCERR:ST29LDA SECE;SECE<=$2D0?SBC #$D1LDA SECE+1SBC #2BCC :ST30JMP :SCERR;No, error;; We h7}ave a valid sequence, so flag the sectors in SECMAP.;:ST30LDX SECSLDY SECS+1JSR MAPACCLDA SECMAP,XORA MASK,YSTA 8}SECMAP,XINC SECSBNE :ST32INC SECS+1:ST32SECLDA SECE;Done?SBC SECSLDA SECE+1SBC SECS+1BCS :ST30;No, do ano9}ther;; Sector input accepted, so say so;:SCOKLDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG7LSTA ICBLL,XSTX ICBLHLDA #L:}OW MSG7STA ICBAL,XLDA #HIGH MSG7STA ICBAH,XJSR CIOVJMP :SCINP;Go back for another input;; Input invalid, display;} error msg;:SCERRLDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG8LSTA ICBLL,XSTX ICBLHLDA #LOW MSG8STA ICBAL,XLDA #HIG<}H MSG8STA ICBAH,XJSR CIOVJMP :SCINP;Try again;; Sector list is complete, so get start address;:SCENDLDX #0LDA #=}PUTCHRSTA ICCOM,XLDA MSG5LSTA ICBLL,XSTX ICBLHLDA #LOW MSG5STA ICBAL,XLDA #HIGH MSG5STA ICBAH,XJSR CIOVLD>}A #0STA CRSINHJSR GETMSG;; Now we interpret the KB message as a 2-byte address.;:ST36STX STARST;Clear location coun?}ter init valueSTX STARST+1LDX ICBLL;Get msg sizeCPX #6BCS :SCER2;Too long, errorDEXDEXBMI :SCER2;EOL only, e@}rrorLDA KBBUF,XJSR ASCNIBBCS :SCER2;Garbage, errorSTA STARSTDEXBMI :ST38LDA KBBUF,XJSR ASCNIBBCS :SCER2AA}SL AASL AASL AASL AORA STARSTSTA STARSTDEXBMI :ST38LDA KBBUF,XJSR ASCNIBBCS :SCER2STA STARST+1DEXBMB}I :ST38LDA KBBUF,XJSR ASCNIBBCS :SCER2ASL AASL AASL AASL AORA STARST+1STA STARST+1:ST38JMP :ST60;Sector C}input done, move on;; Start address invalid, so display error msg;:SCER2LDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG8LSTAD} ICBLL,XSTX ICBLHLDA #LOW MSG8STA ICBAL,XLDA #HIGH MSG8STA ICBAH,XJSR CIOVJMP :ST36;Try again;; Not file or E}sector input, try memory;:ST40CMP #'M';Memory?BEQ :ST42;Yes, get inputsJMP :ST2;Input invalid, try again:ST42LDA F}#LOW GBMEM;Set GETBYT pointerSTA GBPTRLDA #HIGH GBMEMSTA GBPTR+1LDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG6LSTA ICBG}LL,XSTX ICBLHLDA #LOW MSG6STA ICBAL,XLDA #HIGH MSG6STA ICBAH,XJSR CIOVLDA #0STA CRSINH:ST44 JSR GETMSG;ClH}ear the addressesLDX #0STX OBJPTRSTX OBJPTR+1STX BUFTOPSTX BUFTOP+1LDA KBBUF,X;Check for valid start charJSR AI}SCNIBBCC :ST46JMP :MERR:ST46LDA KBBUF,X;Convert to hexJSR ASCNIBBCS :ST47;Found the comma?STA KBBUF,XINXCPXJ} #6BNE :ST46JMP :MERR;Too many characters:ST47CMP #','BNE :MERR;; We now have the start address in KBBUF in hex niK}bbles;STX TEMP;Save the comma locationLDY #0:ST48DEXBMI :ST49LDA KBBUF,XSTA STARST,Y;Right nibbleDEXBMI :SL}T49LDA KBBUF,X;Left nibbleASL AASL AASL AASL AORA STARST,Y;Merge itSTA STARST,YINYCPY #2BCC :ST48;Do iM}t twice;; Now we have the memory start address in STARST.;:ST49LDX TEMP;Recover the comma locationLDY #0;Excessive lN}ength counterINXLDA KBBUF,XJSR ASCNIBBCS :MERR:ST50LDA KBBUF,XJSR ASCNIBBCS :ST51;Found the EOL?STA KBBUF,XO}INXINYCPY #6BNE :ST50:ST51CMP #EOL;Verify EOLBNE :MERR;Found garbageLDY #0:ST52DEXCPX TEMPBEQ :MEMOK;FiP}nishedLDA KBBUF,XSTA BUFTOP,YDEXCPX TEMPBEQ :MEMOKLDA KBBUF,XASL AASL AASL AASL AORA BUFTOP,YSTA BUFTQ}OP,YINYCPY #2BCC :ST52;; Now we have the memory end address in BUFTOP.;:MEMOKJMP :ST60;Done with input processingR}:MERRLDX #0 ;Output error msgLDA #PUTCHRSTA ICCOM,XLDA MSG8LSTA ICBLL,XSTX ICBLHLDA #LOW MSG8STA ICBAL,XLS}DA #HIGH MSG8STA ICBAH,XJSR CIOVJMP :ST44;; Next ask for the output file name.;:ST60LDX #0LDA #PUTCHRSTA ICCOMT},XLDA MSG3LSTA ICBLL,XSTX ICBLHLDA #LOW MSG3STA ICBAL,XLDA #HIGH MSG3STA ICBAH,XJSR CIOVLDA #0STA CRSINHU};; Now get the name of the output file,append '.000'; to it,and put it in OUTFBF.;:ST62JSR GETMSG;Get output file nameV}BMI :ST60LDX #0LDA KBBUF,XCMP #EOLBNE :ST62ALDA #0 ;No file, turn off disk optionSTA DSKOPTJMP :ST80:ST62AW}CMP #'D'BNE :ST60STA OUTFBF,XINXLDA KBBUF,XCMP #':'BNE :ST63LDA TWODRBNE :ST60LDA KBBUF,XSTA OUTFBF,XJX}MP :ST64:ST63CLCLDA TWODRADC #'1'CMP KBBUF,XBNE :ST60STA OUTFBF,XINXLDA KBBUF,XCMP #':'BNE :ST60STA OUTY}FBF,X:ST64LDY #8:ST65INXDEYBMI :ST66LDA KBBUF,XSTA OUTFBF,XCMP #EOLBNE :ST65:ST66LDA #'.'STA OUTFBF,XLDZ}A #'0'LDY #3:ST67INXSTA OUTFBF,XDEYBNE :ST67INXLDA #EOLSTA OUTFBF,XLDA #0STA I2OPENLDA #1STA NUMFIL;[}; If this is a 2-drive run, we now get the disks inserted.;:ST70LDA TWODRBEQ :ST80LDX #0LDA #PUTCHRSTA ICCOM,XL\}DA MSG12LSTA ICBLL,XSTX ICBLHLDA #LOW MSG12STA ICBAL,XLDA #HIGH MSG12STA ICBAH,XLDA #1STA CRSINHJSR CIOVJ]}SR GETMSG:ST80RTS;;;*********************;; ASCNIB;;*********************;; Subroutine to convert an ASCII c^}haracter to; a hex nibble with validity check.;; Enter A=character;; Exit A=hex nibble (if valid); unchanged (if inv_}alid);Carry=clear (if valid); set (if invalid);PROCASCNIBCMP #$47BCS :BADCMP #$2FBCC :BADCMP #$3ABCC `}:CONVCMP #$41BCC :BAD:CONVSECSBC #'0'CMP #$ABCC :GOODSBC #7:GOODCLCRTS:BADSECRTS;tializes tables ankTITLE 'INNER DISASSEMBLY LOOP'SUBTTL 'File DSMINS.AMA';; This module actually disassembles a machine language; instructb}ion and loads the result in LINEBF.; It is called as a subroutine from DSMAIN.;DSMINSLDX INSBUF;Get the opcode.LDA MNEc}IND,X;Get the mnemonic offset.TAXLDY #2DSMIN1LDA MNETEX,X ;Move mnemonic to LINEBFSTA LINEBF+7,YDEXDEYBPL DSMd}IN1;; The mnemonic is in LINEBF. Now we insert the operand.;JSR OPERA;Does this mean go to the opera?RTS;Now LINEBFe} contains a; complete assembly-language instruction.;;; Subroutine to insert the operand into LINEBF.;PROCOPERALDX If}NSBUF;Get opcodeLDA MODES,X;Get mode byteAND #$1F;Mask out mode IDTAX;Index operand subroutine tableLDA OPERS,Xg};Get subroutine addressSTA TEMP;load in pointerINXLDA OPERS,XSTA TEMP+1JMP (TEMP);And go there.;:IMPOPLDA #EOLh};Implied modeSTA LINEBF+10RTS;Easy, wasn't it?;:ACCOPLDA #'A';Accumulator modeSTA LINEBF+11LDA #EOLSTA LINEBi}F+12RTS;Not much harder;:IMMOPLDA #'#';Immediate modeSTA LINEBF+11LDA #'$'STA LINEBF+12LDX #13LDA INSBUF+1j};Get immediate byteJSR WRTHEX;Output itLDA #EOLSTA LINEBF+15RTS;Now it's getting interesting.;:RELOPLDA INSBUF+k}1;Get the relative displacementSTA ADRBUFJSR RELADR;and convert to absolute.LDX #11JSR WRTOP;Write it out.JSR ADl}RCOMLDA #EOLSTA LINEBF,XRTS;:ABSOPLDA INSBUF+1;Get addressSTA ADRBUF ;Pass it to WRTOPLDA INSBUF+2STA ADRm}BUF+1LDX #11JSR WRTOP ;And write it out.JSR ADRCOMLDA #EOLSTA LINEBF,XRTS;:XOPLDA INSBUF+1STA ADRBUFLDAn} INSBUF+2STA ADRBUF+1LDX #11JSR WRTOPLDA #','STA LINEBF,XINXLDA #'X'STA LINEBF,XINXJSR ADRCOMLDA #EOLo}STA LINEBF,XRTS;:YOPLDA INSBUF+1STA ADRBUFLDA INSBUF+2STA ADRBUF+1LDX #11JSR WRTOPLDA #','STA LINEBF,XINp}XLDA #'Y'STA LINEBF,XINXJSR ADRCOMLDA #EOLSTA LINEBF,XRTS;:ZPOPLDX #11;Index operandLDA #0STA ADRBUF+1q};Zero high byteLDA INSBUF+1STA ADRBUFJSR WRTOP:ZPXITJSR ADRCOMLDA #EOLSTA LINEBF,XRTS;:ZPXOPLDX #11LDA #0r}STA ADRBUF+1LDA INSBUF+1STA ADRBUFJSR WRTOP:ZPXXTLDA #','STA LINEBF,XINXLDA #'X'STA LINEBF,XINXJSR ADRCOs}MLDA #EOLSTA LINEBF,XRTS;:ZPYOPLDX #11LDA #0STA ADRBUF+1LDA INSBUF+1STA ADRBUFJSR WRTOP:ZPYXTLDA #','St}TA LINEBF,XINXLDA #'Y'STA LINEBF,XINXJSR ADRCOMLDA #EOLSTA LINEBF,XRTS;:INDOPLDA #'('STA LINEBF+11LDA u}INSBUF+1STA ADRBUFLDA INSBUF+2STA ADRBUF+1LDX #12JSR WRTOPLDA #')'STA LINEBF,XINXJSR ADRCOMLDA #EOLSTA v}LINEBF,XRTS;:INXOPLDA #'('STA LINEBF+11LDA INSBUF+1STA ADRBUFLDA #0STA ADRBUF+1LDX #12JSR WRTOPINXLDA w}#','STA LINEBF,XINXLDA #'X'STA LINEBF,XINXLDA #')'STA LINEBF,XINXJSR ADRCOMLDA #EOLSTA LINEBF,XRTS;x}:INYOPLDA #'('STA LINEBF+11LDA INSBUF+1STA ADRBUFLDA #0STA ADRBUF+1LDX #12JSR WRTOPLDA #')'STA LINEBF,XIy}NXLDA #','STA LINEBF,XINXLDA #'Y'STA LINEBF,XINXJSR ADRCOMLDA #EOLSTA LINEBF,XRTS;;;; Vector table toz} operand subroutines.;OPERSDW :IMPOP,:ACCOP,:IMMOP,:RELOPDW :ABSOP,:XOP,:YOP,:ZPOPDW :ZPXOP,:ZPYOP,:INDOPDW :INXOP,:{}INYOPEPROCISASSEMBLY LOOP'SUBTTL 'File DSMINS.AMA';; This module actually disassembles a machine language; instructTITLE 'SYSTEM EQUATES'SUBTTL 'File SYSEQU.AMA';; Outputs a list of referenced system equates; to the source-code file. }};PROCSYSEQULDA #LOW STR1 ;Get comment stringSTA STRACCLDA #HIGH STR1STA STRACC+1LDX #0JSR WRTSTR ;Output it ~}LDA #EOLSTA LINEBF,XJSR RECOUTLDX #0:LP1LDA PAGTAB,X;Identify a system pageSTA SYSBASINXLDA PAGTAB,XSTA SYSB }AS+1INXLDA PAGTAB,XSTA PAGNO;Page nr we are onINXLDA PAGTAB,XSTA PAGTOP;How many labels on pageINXINXTXA }PHA;Save X; Now we have the system page base address in SYSBAS(2),; page number in PAGNO, page length in PAGTOP,; and X } (now the LINEBF pointer) saved on the stack.JSR :PAGEQ;Do equates for this pagePLATAX;Recover XCPX #[PTBEND-PAGTA }B]BCC :LP1;More pages to doLDA #LOW STR2;"End of equates" commentSTA STRACCLDA #HIGH STR2STA STRACC+1LDX #0JS }R WRTSTR;Output itLDA #EOLSTA LINEBF,XJSR RECOUTRTS;; Private subroutine to output equates for 1 page;; Enter SY }SBAS(2)=system page base address; No exit parameters. No registers guaranteed.;:PAGEQLDA #0 ;Start of pageSTA ADRBUF }:LP2JSR ADRSYS;Get label addressLDY #0LDA (SYSACC),Y ;Hi bit indicates "ref'd"BPL :NOTRF;Not referencedJSR :SYSEQ };Ref'd, output equateJSR RECOUT:NOTRFINC ADRBUFBEQ :PQXITLDA ADRBUFCMP PAGTOP;End of page?BCC :LP2;No, do anot }herBEQ :LP2:PQXITRTS;Yes, page done;; Private subroutine to output one system equate;; EnterSYSACC(2)=pointer to l }abel; PAGTAB(4) reflects present system page;(In SYSBAS,PAGNO);ADRBUF=lo byte of system address;; Exit LINEBF=one sy }stem equate pseudo-op;:SYSEQLDY #5:LP3LDA (SYSACC),YSTA LINEBF,YDEYBPL :LP3LDY #0;Clear ref bit on 1st charLD }A LINEBF,YAND #$7FSTA LINEBF,YLDA #' ';Some assemblers need this blankSTA LINEBF+6LDA #'='STA LINEBF+7;Always l }eaves at least 1 blankLDA #' 'STA LINEBF+8LDA #'$'STA LINEBF+9LDX #10;Set LINEBF pointerLDA PAGNO ;Hi byte of a }ddressBEQ :ZP;Don't output hi byte if p.0JSR WRTHEX;Output one byte as ASCII:ZPLDA ADRBUF;Lo byte of addressJSR WR }THEXLDA #EOLSTA LINEBF,XRTSEPROC;; Table of page base addresses and lengths ; for system labels;PAGTABDW SP0D }B 0,$7F,$FFDW SP2DB 2,$FF,$FFDW SP3DB 3,$4F,$FFDW SPD0RDB $D0,$13,1DW SPD0WDB $D0,$1F,0DW SPD2RDB $D2,$0F },1DW SPD2WDB $D2,$0F,0DW SPD4DB $D4,$0F,$FFDW SPE4DB $E4,$7F,$FFPTBEND= *;quates; to the source-code file. [TITLE 'MAIN SEQUENCE'SUBTTL 'File MAIN.AMA';;******************************;; DISK DISASSEMBLER Rev 2.2;;**********}********************;; Copyright 1982 Ralph Jones.;; This program disassembles Atari (tm) machine-language; programs fro}m binary DOS files, self-booting disks,; and memory into DOS text files suitable for editing; and reassembly. All program-i}nternal address references; are given labels up to a maximum of 1023 locations.; All references to locations within the Ata}ri Operating; System are given their documented system labels.; Example: instruction 20 56 E4 disassembles as JSR CIOV.; S}ystem locations used are defined by appropriate; equate pseudo-ops and hex values of all references; are given in comments }following the instructions.;; This is the mainline program.; It simply calls the major processing; modules in sequence (w}ith some looping); and wraps up at the end of the disassembly.; This file should be named in the assembly; command; it ref}erences all the other; modules via INCLUDE pseudo-ops.;;; Changes this version:;(1) Line number option;(2) Modified z}ero-page equate handling;(3) Zero-page labels prefixed with "Z";(4) Customizing file capability;; Changes this sub-vers}ion:;Printer option improved;LIST IINCLUDE D:PROGEQU.AMA;; Init code;ORG $2500INITLDA #LOW INITSTA DOSVECHD}A #HIGH INITSTA DOSVEC+1SECLDA MEMTOPSTA MEMLOSTA APPMHISTA BUFMAXLDA MEMTOP+1SBC #1 ;Leave some space abov}e.STA MEMLO+1STA APPMHI+1STA BUFMAX+1PROCJSR CUSTOMJSR VBLANK;Set up console switch monitorMAINJSR START;Set }up tables & pointersJSR GBINIT;Initialize GETBYT:BLDLPJSR BUILD; build label & symbol; tables for one; object} code segment.LDA MORSEGBNE :BLDLP; Do the same for the; next segment.JSR SYSEQU; Output equates for; all s}ystem labels used.JSR ZPEQU; Output zero-page equatesJSR GBINIT; Initialize GETBYT.:DSLPJSR DSMAIN; Disassemble one }segment.LDA MORSEGBNE :DSLP; Repeat for next segment.JSR EXTEQUWRAPLDY #20 ; Output end pseudo-opWRAP1LDA ENDOP},YSTA LINEBF,YDEYBPL WRAP1JSR RECOUTLDX #$20; Close output fileLDA #CLOSESTA ICCOM,XJSR CIOVLDX #0 ; Di}splay "done" msgLDA #PUTCHRSTA ICCOM,XLDA MSG13LSTA ICBLL,XSTX ICBLHLDA #LOW MSG13STA ICBAL,XLDA #HIGH MSG13}STA ICBAH,XJSR CIOVJSR GETMSG; Wait for CRJMP (DOSVEC) ; Start overEPROC;; Processing ends here and can be rest}arted; with Sys Reset or .;INCLUDE D:CUSTOM.AMAINCLUDE D:VBLANK.AMAINCLUDE D:START.AMAINCLUDE D:BUILD.AMAINCL}UDE D:SYSEQU.AMAINCLUDE D:ZPEQU.AMAINCLUDE D:DSMAIN.AMAINCLUDE D:EXTEQU.AMAINCLUDE D:DSMINS.AMAINCLUDE D:SYSLABS.AM}AINCLUDE D:DISTABLE.AMAINCLUDE D:SUBRS.AMAINCLUDE D:SCREEN.AMAINCLUDE D:DISKIO.AMA;BIGBUF= * ;Big Buffer starts} hereEND $2500ENCE'SUBTTL 'File MAIN.AMA';;******************************;; DISK DISASSEMBLER Rev 2.2;;**********TITLE 'PROGRAM EQUATES'SUBTTL 'File PROGEQU.AMA';; Program equates.;;************************;; Page 0 (system);};************************;DOSVECEQU $0ADOSINIEQU $0CAPPMHIEQU $0EFR0EQU $D4INBUFFEQU $F3;;;********************}****;; Page 0 (non-system);;************************;ORG $80ADRBUFDS 2BFAVLDS 2BTFLGDS 1BUFMAX DS 2BUFTOPD}S 2CONSAVDS 1DBTIMDS 1DOSHDRDS 4DSKOPTDS 1FILSZDS 2FREEZEDS 1GBPTRDS 2HEADERDS 4INSBUFDS 8INSPTRDS 1I2OP}ENDS 1LABACCDS 2LABCNTDS 2LABELDS 2LABNRDS 2LABTOPDS 2OBJPTRDS 2OPRCNTDS 1OPSAVDS 1OUTPTRDS 2PAGNODS 1P}AGTOPDS 1PROPENDS 1PROPTDS 1SECEDS 2SECSDS 2SECCNTDS 2SEQDS 1SRCTYPDS 1STARDS 2STARSTDS 2SYSACCDS 2SYSB}ASDS 2SYSOFFDS 1SECTRYDS 2STRACCDS 2STRLENDS 1TEMPDS 2TEXCNTDS 1WRTFLGDS 1;;**********************;; Pag}e 2 (system);;**********************;MEMTOPEQU $02E5MEMLOEQU $02E7CRSINHEQU $02F0;;**********************;; Pa}ge 3 (system);;**********************;DUNITEQU $0301DCOMNDEQU $0302DSTATSEQU $0303DBUFLOEQU $0304DBUFHIEQU $0305}DAUX1EQU $030ADAUX2 EQU $030BICCOMEQU $0342ICSTAEQU $0343ICBALEQU $0344ICBAHEQU $0345ICBLLEQU $0348ICBLH EQU }$0349ICAX1EQU $034A;;***********************;; Page 4;;***********************;; This part of cassette buffe}r used for variables;ORG $0400DISKIDDS 1MORSEGDS 1NUMFILDS 1PASS DS 1TWODRDS 1LABUFDS 5;;*******************}****;; Misc (system);;***********************;CONSOLEQU $D01FFASCEQU $D8E6IFPEQU $D9AADSKINVEQU $E453CIOVE}QU $E456SETVBVEQU $E45CXITVBVEQU $E462;;Command codesOPENEQU 3GETRECEQU 5GETCHREQU 7PUTRECEQU 9PUTCHREQU $BC}LOSE EQU $CGETSECEQU $52;; AUX1 equates;OPNINEQU 4OPNOTEQU 8;EOLEQU $9BCLEAREQU $7DTABEQU$7FBELLEQU $FDS}KIPEQU $1D;M EQUATES'SUBTTL 'File PROGEQU.AMA';; Program equates.;;************************;; Page 0 (system);TITLE 'MAIN DISASSEMBLY LOOP'SUBTTL 'File DSMAIN.AMA';; This module disassembles one segment of the object code.; It co}ntains most of the fancier analysis logic in the; program, and most of the unstructured code. Oh well...;PROCDSMAINLDA }#2STA PASS:DSMLPJSR CLRBUF ;Clear buffersJSR LINADR;Send line addr to E:,P:;; See if there's a label for this instr}uction.;LDA STARSTA ADRBUFLDA STAR+1STA ADRBUF+1:PUTLBJSR GETLABBCS :BYTE1;If not, skip ahead.LDA #1JSR FLG}LAB;Flag this label as "internal"LDX #0 ;Index output byte 0.JSR WRTLAB;Convert label nr to a ;text label and ins}ert it.:BYTE1JSR GETBYT;Get byte 1 of instruction.BCC :B1A;Get out if not there.JMP :EXIT1:B1ATAXLDA MODES,X;Loo}k at mode ID.CMP #NOP;Is it an opcode?BEQ :TEXT;No, handle as text.LDY TEXCNT;Yes, check text count.BEQ :NOTEX;No} text present,; so move on to disassembly.STX OPSAV;Save the opcode.JSR TEXOUT;Output a text instruction.;; Now we h}ave to output a line address to E:,P:.; Unfortunately the location counter is past the; first byte, so we have to back it u}p one.;SECLDA STARSBC #1STA STARLDA STAR+1SBC #0STA STAR+1JSR LINADRINC STAR ;Put counter back where it w}asBNE :B1BINC STAR+1:B1BJSR CLRBUF;Clear the buffers.LDX OPSAV;Recover the opcode.:NOTEXSTX INSBUF;Put in instru}ction buffer.INC INSPTR;Update the pointer.LDA MODES,X;Get the mode byte.AND #$60;Look at nr of operand bytes.LSR }A ;Shift it down.LSR ALSR ALSR ALSR ASTA OPRCNT;Move to operand count.AND #$02;Set up booby trap flagSTA BT}FLGLDA OPRCNT:OPLPBEQ :DSMBL;Here the Z bit must; reflect contents of OPRCNT because we either; shifted or decremented} it to get here.JSR GETBYT;Still need some oprs.BCS :EXIT2;Out of bytes, this;will become a text instruction.LDX INS}PTRSTA INSBUF,X;Put operand in buffer.INC INSPTRDEC OPRCNTJMP :OPLP;Try for another opr.;; Now we have the instru}ction buffer full,; so let's disassemble it.;:DSMBLLDA BTFLG;Check booby trap flagBEQ :DSMB1LDA INSBUF+2BNE :DSMB1};; Aha! We have a 2-byte address instruction but; the address is 0-page. We must be trying to; disassemble a text sequenc}e as an instruction.; Let's put a stop to this crapola.;LDA #3STA TEXCNTJMP :TEXFL:DSMB1JSR DSMINS ;Disassemble i}nstruction;JSR RECOUT ;Output it;JMP :DSMLP;and do it all again.;; Here we load the byte into the instruction buffer }as a; text byte. It's in the X register.:TEXTTXALDX TEXCNT;Tells where to put it.STA INSBUF,XINC TEXCNT;; If the }next location is labeled we must; bite off the text instruction here.;LDA STARSTA ADRBUFLDA STAR+1LDA ADRBUF+1JSR} GETLABBCS :NOLAB;It's not labeled.:TEXFLJSR TEXOUTJMP :DSMLP;Back thru main loop.:NOLABLDA TEXCNT;See how much te}xt we have.CMP #5 ;>=8 bytes?BCS :TEXFL;Yes, wrap it up.JMP :BYTE1;No, continue with text.;; Here we convert this} aborted instruction to text.;:EXIT2LDX INSPTR;This is number of bytes in INSBUF.STX TEXCNT;This makes INSBUF a text l}ine.:EXIT1LDA TEXCNT;Any text present?BEQ :EXIT0;No, get out.JSR TEXOUT;Yes, output it.:EXIT0LDA MORSEG;Any more }segments?BEQ :BYE;No, drop out;; There is another segment to disassemble so we have; to output a set-origin pseudo. But} first we must; see if we left a label hanging at the address that; follows the end of the current segment. If so we; just} unflag it so it will be an external reference.;LDA LINEBF;Look at first buffer byteCMP #'L';Start of a label?BNE :E}XIT;No, no label hereLDA #0;Yes, unflag itJSR FLGLAB:EXITJSR SETORG;Set the new origin:BYESEC ;Indicate end of }segmentRTS ;and split.EPROC;L 'File DSMAIN.AMA';; This module disassembles one segment of the object code.; It co%TITLE 'DISK I/O MODULE'SUBTTL 'File DISKIO.AMA';; Contains subroutines to do disk I/O and supply; object code to the di}sassembly loop.;;**********************;; GETBYT;;**********************;; Subroutine to get next unprocessed b}yte.;PROCGETBYTJMP (GBPTR);Vector to source-dependent; object code input routine.;GBMEMLDA PA}SS ;Code for memory inputCMP #2;Pass 2?BNE :GBM1;No, move onJSR SETORG;Yes, set the originJSR LINADR;Repeat }line addressLDA #0;and see that itSTA PASS;doesn't happen again:GBM1SEC;; Any data left in the Big Buffer?;LDA B}UFTOPSBC OBJPTRLDA BUFTOP+1SBC OBJPTR+1BCS :GBM2;Yes, go get it.LDA #0;No, so say soSTA MORSEGSEC;Indicate }failureRTS;And get out.:GBM2LDY #0LDA (OBJPTR),Y;Get the byteTAX;Save itINC OBJPTR;Step this counterBNE :GB}M4INC OBJPTR+1:GBM4INC STAR ;and locatin counterBNE :GBM6INC STAR+1:GBM6TXA;Recover byteCLC ;Indicate success}RTS;;GBFILSEC ;Code for DOS file input.;; Any data left in the Big Buffer?;LDA BUFTOPSBC OBJPTRLDA BUFTOP+1}SBC OBJPTR+1BCS :GBF2;Yes, go get a byte.JSR GOFIL;No, go get some more.BCC :GBF2;Got some dataLDA #0;File is emp}tySTA MORSEG;so say so.RTS ;Exit with carry set.;; There is data available in the Big Buffer; but we have to do some} interpretation yet.;:GBF2LDA HEADER+2;This is nr of bytes; remaining in the current file section. Is it 0?BNE :GBF8;}No, go get the next one.LDA HEADER+3BNE :GBF8LDA #0STA MORSEG;; Yes, see if there's another section in the file.;}; Here we read the next 4 bytes from the Big Buffer; and extract the section address/length information.; These 4 bytes mus}t be present because we already; know there is at least 1 byte, and GOFIL will not; load them if there isn't room for all 4}.;LDY #3:GBF4LDA (OBJPTR),YSTA HEADER,YDEYBPL :GBF4;; Now move OBJPTR up 4 bytes to jump over the header info.;}CLCLDA OBJPTRADC #4STA OBJPTRLDA OBJPTR+1ADC #0STA OBJPTR+1;; Now test the new section for contiguity with th}e last.;LDA HEADER;Section start addressCMP STAR;Disassembly location counterBNE :GBF6;Not equal, reset counterLD}A HEADER+1CMP STAR+1BEQ :GBF8;Equal, section is contiguous;; Set the location counter to the start of the new section.};:GBF6LDA HEADERSTA STARLDA HEADER+1STA STAR+1LDA #$FFSTA MORSEGSEC;Return without reading a byte.RTS;; }At last we go get the damn byte.;:GBF8LDY #0LDA (OBJPTR),YTAX;Save the byteINC OBJPTR;Step the pointerBNE :GBF1}0INC OBJPTR+1:GBF10CLC;Step the location counterINC STARBNE :GBF11INC STAR+1:GBF11DEC HEADER+2;Count down nr o}f bytes in sectionLDA HEADER+2CMP #$FFBNE :GBF12DEC HEADER+3:GBF12LDA HEADER+2BNE :GBF13LDA HEADER+3BNE :GBF1}3STA MORSEG:GBF13TXA;Recover the byteCLC;Indicate successRTSEPROC;;;;**********************;; GOFI}L;;**********************;; Subroutine to move more data from the source file; into the Big Buffer.;; Enter SECCNT=nr }of unloaded bytes remaining; in the current DOS file section;; Exit BUFTOP=address of top of loaded; part of Big Buffer};Carry=set if & only if no data got transferred;Y=error code if a disk read error occurred; PROCGOFILLDA MORSEGB}NE :GOFOKSECRTS:GOFOKSECLDA #BIGBUF&$FFSTA OBJPTR;Reset this pointerSBC #1STA BUFTOP;and this oneLDA #BIGBU}F/256STA OBJPTR+1SBC #0STA BUFTOP+1;; Now we have OBJPTR set equal to BIGBUF so it; points to the next byte to be pr}ocessed and; BUFTOP set to 1 less to indicate the top of; the loaded part of the Big Buffer.;; While we're at it, let's c}ompute buffer space available.;SECLDA BUFMAXSBC BUFTOPSTA BFAVLLDA BUFMAX+1SBC BUFTOP+1STA BFAVL+1;; Now sta}rt on the disk access. First get the input; disk into the drive if required.;LDA TWODRBNE :LOOP1LDA DISKIDBEQ :LOOP}1JSR GINDSK;Get input disk;; Get object code from a DOS file.;:LOOP1LDA SECCNT;Any data left in; current file secti}on?BEQ :LP1AJMP :OLDSC;Yes, go get it.:LP1ALDA SECCNT+1BEQ :LP1BJMP :OLDSC;; This section done, so see if there'}s room in the; Big Buffer for another section header.;:LP1BSECLDA BFAVLSBC #5LDA BFAVL+1SBC #0BCS :GF0JMP :BF}ULL;Not enough room, get out.;; We have room for a header and at least one data byte,; so get the header.;:GF0LDX #$10};Select IOCB 1LDA #GETCHRSTA ICCOM,X;; Set buffer length to 0 for one-byte xfer;LDA #0STA ICBLL,XSTA ICBLH,X;}; Watch closely now.;:GF1JSR CIOV;Get 1 byte from input fileBPL :GF1AJMP :FLEND;No byte, it's EOF:GF1ASTA DOSHDR}JSR CIOVBPL :GF1BJMP :FLEND:GF1BSTA DOSHDR+1CMP #$FF;Binary file flag?BNE :GF2;No, go on.CMP DOSHDRBEQ :GF1;}Yes, get 2 more bytes.:GF2JSR CIOVBPL :GF2AJMP :FLEND:GF2ASTA DOSHDR+2JSR CIOVBPL :GF2BJMP :FLEND:GF2BSTA DOS}HDR+3;; Now we have the file section start address in DOSHDR(2); and end address in DOSHDR+2(2).; Next we get the number }of bytes in the new section.;SECLDA DOSHDR+2;End addressSBC DOSHDR;Start addressSTA DOSHDR+2;Now section length}LDA DOSHDR+3SBC DOSHDR+1STA DOSHDR+3CLC;Have to add 1LDA DOSHDR+2;to get correct length.ADC #1STA DOSHDR+2ST}A SECCNTLDA DOSHDR+3ADC #0STA DOSHDR+3STA SECCNT+1;; OK, now the header block has start/length information and; SE}CCNT has the section length. With me? Now we; move the header block into the Big Buffer.;LDY #4:HDLPDEYLDA DOSHDR,Y}INYSTA (BUFTOP),YDEYBNE :HDLP;; Now move BUFTOP up 4 bytes.;CLCLDA BUFTOPADC #4STA BUFTOPLDA BUFTOP+1ADC} #0STA BUFTOP+1;; Now we have an active file section, so see how much; room we have in the Big Buffer.;:OLDSCSECLDA} BUFMAXSBC BUFTOPSTA BFAVLLDA BUFMAX+1SBC BUFTOP+1STA BFAVL+1BCC :BFULLBNE :OS1LDA BFAVLBEQ :BFULL;; Now }set up the IOCB to read SECCNT bytes.;:OS1LDX #$10;Select IOCB 1LDA SECCNTSTA ICBLL,XLDA SECCNT+1STA ICBLH,X;; }Now see if we can get away with this.;SECLDA BFAVLSBC SECCNTLDA BFAVL+1SBC SECCNT+1BCS :GF3;Yes we can.LDA BF }AVL ;No, only xfer BFAVL bytes.STA ICBLL,XLDA BFAVL+1STA ICBLH,X:GF3CLCLDA BUFTOP;Set buffer locationADC #1ST }A ICBAL,XLDA BUFTOP+1ADC #0STA ICBAH,XJSR CIOV;Load buffer;; Read error here will take care of itself later.; Nex }t move BUFTOP up by byte count.;CLCLDA BUFTOPADC ICBLL,XSTA BUFTOPLDA BUFTOP+1ADC ICBLH,XSTA BUFTOP+1;; And  }move SECCNT down by the same amount.;SECLDA SECCNTSBC ICBLL,XSTA SECCNTLDA SECCNT+1SBC ICBLH,XSTA SECCNT+1;; } And loop back for another section.;JMP :LOOP1:FLENDLDA #0STA MORSEG;Probably don't need this:BFULLSEC;This will }set the carryLDA BUFTOP;if we got any dataSBC #BIGBUF&$FFLDA BUFTOP+1SBC #BIGBUF/256ROR A;and this will toggle it}.EOR #$80ROL ARTS;;GBSECSEC;Input code for sector input.;; Any data left in the Big Buffer?;LDA BUFTOPSBC }OBJPTRLDA BUFTOP+1SBC OBJPTR+1BCS :GBS2;Yes, go get someJSR GOSEC;No, get more from diskBCC :GBS2;Got some, so p}rocessLDA #0 ;Disk exhaustedSTA MORSEG;so say soRTS;and get out.:GBS2LDY #0 ;Get a byteLDA (OBJPTR),YTAX};Save itINC OBJPTR;Step this pointerBNE :GBS4INC OBJPTR+1:GBS4INC STAR;and locatin counterBNE :GBS6INC STAR+1}:GBS6TXA;Recover byteCLC;Indicate successRTS;and exit with byte in A.;;;**********************;; GOSEC};;**********************;; Subroutine to fill the Big Buffer from a sector list.;GOSECLDA #$00STA MORSEGSECLDA #}BIGBUF&$FFSTA OBJPTR;Reset this pointerSBC #1STA BUFTOP;and this one.LDA #BIGBUF/256STA OBJPTR+1SBC #0STA BUF}TOP+1;; Does Big Buffer have room for another sector?;:GOS2SECLDA BUFMAXSBC BUFTOPSTA BFAVL;nr bytes avail in buf}ferLDA BUFMAX+1SBC BUFTOP+1STA BFAVL+1SECLDA BFAVLSBC #$80;Length of a sectorLDA BFAVL+1SBC #0BCC :GOXIT;}No room, get out.;; Buffer has room, now select a sector.;:GOS4INC SECTRYBNE :GOS6INC SECTRY+1:GOS6SEC;Out of se}ctor numbers?LDA #$D0SBC SECTRYLDA #2SBC SECTRY+1BCC :GOXIT;Yes, get out;; See if this sector number is in the s}ector list.;LDX SECTRYLDY SECTRY+1JSR MAPACCLDA SECMAP,XAND MASK,YBEQ :GOS4;No, try another sector;; We want }this sector, so go read it.;LDA TWODRBNE :GOS7LDA DISKIDBEQ :GOS7JSR GINDSK:GOS7LDA SECTRYSTA DAUX1LDA SECTR}Y+1STA DAUX2LDA #1;Drive 1STA DUNITLDA #GETSEC;Get sector commandSTA DCOMNDCLC;Start new sector oneLDA BUFT}OP;byte above BUFTOPADC #1STA DBUFLOLDA BUFTOP+1ADC #0STA DBUFHIJSR DSKINV;Read the sectorLDA DSTATS;; Need} some error trapping here;;; These NOP's form a hook for a subroutine to do; special input data processing after the sect}or; is read.;NOPNOPNOPCLC;Move BUFTOP up 128 bytesLDA BUFTOPADC #$80STA BUFTOPLDA BUFTOP+1ADC #0STA B }UFTOP+1JMP :GOS2;Go back for next sector:GOXITLDA PASS;Is this pass 2?CMP #2BNE :GOSX2JSR SETORG;Output ORG pseu!}do-opJSR LINADR;Repeat the line addressLDA #0STA PASS:GOSX2SECLDA BUFTOP;This sets carry ifSBC #BIGBUF&$FF;we g"}ot any dataLDA BUFTOP+1SBC #BIGBUF/256ROR A;and this toggles it.EOR #$80ROL ARTSEPROC;;;;*****************#}****;; RECOUT;;*********************;; Subroutine to output one record from the source line; buffer to the selec$}ted output devices.;; Enter LINEBF contains 1 assembly-language instruction;; No exit parameters;PROCRECOUTLDA LNFLA%}G;Want line numbers?BEQ :RE2;NoJSR LNNUM;Yes, put one in NUMBUF:RE2LDA DSKOPT;Write disk?BNE :RE3;YesJMP :NODS&}K;No, skip it:RE3LDA TWODR;1 or 2 disk drives?BNE :RE4;1LDA DISKID;2, which one do we have?CMP #1BEQ :RE4;Outp'}ut disk, go onJSR GOPDSK;Input disk, get the other:RE4LDA I2OPEN;Is IOCB2 open?BNE :RE6;YesJSR OPENO;No, open it(};; Is there room in the current output file for; another record?;:RE6SECLDA FILSZSBC MAXSZLDA FILSZ+1SBC MAXSZ+1)}BCC :RE8;Yes, send it on outJSR NEWFIL;No, open a new file;; Now output the instruction to the current output file.;*}:RE8LDX #$20;IOCB2JSR CIORECBPL :RE10JMP :RERROR:RE10CLCLDA FILSZ;Update length of fileADC ICBLL,XSTA FILSZ+}LDA FILSZ+1ADC ICBLH,XSTA FILSZ+1:NODSKLDA FREEZE;Freeze selected?BNE :NODSK;Yes, wait hereLDX #0 ;No, push ,}onJSR CIOREC;Put record to screenLDX #$30;IOCB3 for printerLDA PROPT;Printer option?BEQ :NOPR;NoLDA PROPEN;Pri-}nter open?BNE :PRINT;YesLDA #OPEN;No, open itSTA ICCOM,XLDA #OPNOTSTA ICAX1,XLDA #LOW :PBUFSTA ICBAL,XLDA #.}HIGH :PBUFSTA ICBAH,XJSR CIOVBPL :OPNOKJSR PHFFTLDX #0STX PROPTLDX #$30JMP :CLOSE:OPNOKLDA #$FF ;Signal /}successSTA PROPENJMP :EXIT;Don't print till next time:PRINTJSR CIORECBPL :EXITLDA #$FFSTA FREEZEJMP :EXIT:NOP0}RLDA PROPEN;Printer still open?BEQ :EXIT;NoJSR CIOREC;Yes, wrap up current line:CLOSELDA #CLOSE;and close itSTA 1}ICCOM,XJSR CIOVLDA #0STA PROPEN:EXITRTS:RERRORJMP IOERR;Failure exit point:PBUFDB 'P:';Name buffer;; Subrouti2}ne to output one record from buffer; pointed to by OUTPTR to the selected IOCB;CIORECLDA #PUTRECSTA ICCOM,XLDA OUTPTR3}STA ICBAL,XLDA OUTPTR+1STA ICBAH,XLDA #$80STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVRTSEPROC;;***************4}***;; NEWFIL;;******************;; Subroutine to close the current output file (because; full) and open a new one.5};PROC;; First find where in OUTFBF the extender starts.;NEWFILLDX #1:NF2INXCPX #$0FBNE :NF3JMP :NFERR:NF3LD6}A OUTFBF,XCMP #'.'BNE :NF2STX TEMP;Save offset to periodINX;Get offset to last digitINXINXSTX TEMP+1;Save t7}his offset;; Now we add 1 to the extender by ASCII addition (!);:NF4LDY OUTFBF,XINYCPY #':'BCC :NF6LDA #'0'STA8} OUTFBF,XDEXCPX TEMP;Finished?BNE :NF4;No, do another digit:NF6TYASTA OUTFBF,X;; Now the new extender is in the9} file name in OUTFBF.; Next we merge the file name into the LINK instruction.;LDY #6:NF8INY;Find end of pseudo-opLD:}A LINKBF,YCMP #$27;Quote?BEQ :NF10CMP #' ';Space?BEQ :NF9CPY #$12;No, try againBNE :NF8JMP :NFERR;Couldn't ;}find end:NF9INY ;Look at next charLDA LINKBF,YCMP #$27;Quote?BEQ :NF10;YesCMP #'#';#?BEQ :NF10;YesDEY <};No, use last charLDA LINKBF,Y:NF10PHA;Save last char of pseudo-opLDX #$FF:NF12INXINYLDA OUTFBF,X;Merge file =}nameSTA LINKBF,YCPX TEMP+1;Offset to final char in filenmBNE :NF12INYPLA;Recover space, quote or #CMP #$27BN>}E :NF14STA LINKBF,Y;Insert if quoteINY:NF14LDA #EOL;Terminate recordSTA LINKBF,Y;; Now the link instruction is in?} LINKBF but we may; need a line number.;LDA LNFLAGBEQ :NOLNLDX #$20;Output contents of NUMBUFLDA #PUTCHRSTA ICCO@}M,XLDA #LOW NUMBUFSTA ICBAL,XLDA #HIGH NUMBUFSTA ICBAH,XLDA #6STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVJSR LNNA}UM;Update the line number;;Now output the file link to the old file to wrap it up.;:NOLNLDX #$20LDA #PUTRECSTA ICCOB}M,XLDA #$80STA ICBLL,XLDA #0STA ICBLH,XLDA #LOW LINKBFSTA ICBAL,XLDA #HIGH LINKBFSTA ICBAH,XJSR CIOVBMI :C}NFERR;;Close the old file;LDA #CLOSESTA ICCOM,XJSR CIOVBMI :NFERRLDA #0STA I2OPEN;; See if output disk is fuD}ll & if so get it changed.;INC NUMFILLDA NUMFILCMP MAXFILBCC :NF16LDA #1STA CRSINHLDX #0LDA #PUTCHRSTA ICCE}OM,XLDA MSG14LSTA ICBLL,XSTX ICBLHLDA #LOW MSG14STA ICBAL,XLDA #HIGH MSG14STA ICBAH,XJSR CIOVJSR GETMSGLDF}A #1STA NUMFIL:NF16JSR OPENO;Open new fileLDA #0STA FILSZSTA FILSZ+1RTS:NFERRJMP IOERR;Failure exit pointEPG}ROC;;*******************;; OPENO;;*******************;; Subroutine to open an output file named in OUTFBF;PROH}COPENOLDX #$20;IOCB2LDA #OPENSTA ICCOM,XLDA #LOW OUTFBFSTA ICBAL,XLDA #HIGH OUTFBFSTA ICBAH,XLDA #OPNOTSTAI} ICAX1,XJSR CIOVBPL :OPN1JMP IOERR:OPN1LDA #$FFSTA I2OPENRTSEPROC;;;********************;; GINDSK;J};********************;; Subroutine to prompt user to insert the input disk.;; No enter parameters.; Exit DISKID=0 (inputK} disk);GINDSKLDA #1STA CRSINHLDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG10LSTA ICBLL,XSTX ICBLHLDA #LOW MSG10STAL} ICBAL,XLDA #HIGH MSG10STA ICBAH,XJSR CIOVJSR GETMSGLDA #0STA DISKIDRTS;;;*********************;; GOM}PDSK;;*********************;; Subroutine to prompt user to insert the output disk.;; No enter parameters.; Exit DISKIDN}=1 (output disk);GOPDSKLDA #1STA CRSINHLDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG11LSTA ICBLL,XSTX ICBLHLDA #MSG1O}1&$FFSTA ICBAL,XLDA #MSG11/256STA ICBAH,XJSR CIOVJSR GETMSGLDA #1STA DISKIDRTS;;;*********************;;P} GETMSG;;*********************;; Subroutine to accept a keyboard message from user.;; No enter parameters.; Exit Q}msg in KBBUF.;GETMSGLDX #0LDA #GETRECSTA ICCOM,XLDA #$20STA ICBLL,XSTX ICBLHLDA #KBBUF&$FFSTA ICBAL,XLDA #R}KBBUF/256STA ICBAH,XJSR CIOVRTS;;*********************;; GBINIT;;*********************;; Subroutine to sS}et appropriate pointers to initialize; GETBYT to the start of the selected data source.;PROCGBINITLDA SRCTYP;Get type T}of sourceCMP #'M';Memory?BNE :GBI1LDA STARST;Yes, this will be easySTA OBJPTRSTA STARLDA STARST+1STA OBJPTR+1U}STA STAR+1:GBIM1RTS;; Source must be either file or sectors, so we want the; input disk unless we have 2 drives.;:GBV}I1LDA TWODRBNE :GBI2LDA DISKIDBEQ :GBI2JSR GINDSK;Ask for input disk:GBI2LDA SRCTYPCMP #'F'BNE :GBI10;; FilW}e input, so we open the file for input.;LDX #$10;IOCB1LDA #CLOSESTA ICCOM,XJSR CIOVLDA #OPENSTA ICCOM,XLDA #OX}PNINSTA ICAX1,XLDA #LOW INFLBFSTA ICBAL,XLDA #HIGH INFLBFSTA ICBAH,XJSR CIOVBPL :GBI4JMP IOERR:GBI4LDA #0Y}STA SECCNT;Initialize dsik section countSTA SECCNT+1LDX #3:CLRHDSTA HEADER,X;And clear header blockDEXBPL :CLRHDZ}JMP :GBI12;; Must be sector input (error check already done);:GBI10LDA #0STA SECTRYSTA SECTRY+1LDA STARSTSTA ST[}ARLDA STARST+1STA STAR+1;; Now set up buffer pointers for either file or sector; input. BUFTOP=BIGBUF-1 and OBJPTR=BIG\}BUF is the; start condition for GETBYT.;:GBI12SECLDA #LOW BIGBUFSTA OBJPTRSBC #1STA BUFTOPLDA #HIGH BIGBUFSTA]} OBJPTR+1SBC #0STA BUFTOP+1CLCLDA #$FFSTA MORSEGRTSEPROC;;;*******************;; IOERR;;**********^}*********;; Routine to bomb the program in event of fatal I/O error;IOERRLDX #0LDA #PUTCHRSTA ICCOM,XLDA MSG9L;Ba_}d new msgSTA ICBLL,XSTX ICBLHLDA #LOW MSG9STA ICBAL,XLDA #HIGH MSG9STA ICBAH,XJSR CIOVHANGJMP HANG;Loop fore`}ver;;;**********************;; SETORG;;**********************;; Subroutine to output an origin-set pseudo-op.a};; Enter STAR(2)=value to set origin;; Exit ORGOP(20) contains the full pseudo-op with EOL.;PROCSETORGLDX #11LDA #b}'$'STA ORGOP,XINXLDY #1:LPLDA STAR,YLSR ALSR ALSR ALSR AJSR NIBASCSTA ORGOP,XINXLDA STAR,YAND #$0Fc}JSR NIBASCSTA ORGOP,XINXDEYBPL :LPLDA #EOLSTA ORGOP,XLDY #20:LP2LDA ORGOP,YSTA LINEBF,YDEYBPL :LP2JSd}R RECOUT:OKRTSEPROC;;**********************;; PHFFT;;**********************;; Subroutine to ring the consoe}le bell;PHFFTLDX #0STX ICBLLSTX ICBLHLDA #PUTCHRSTA ICCOMLDA #BELLJSR CIOVRTS;;; Miscellaneous tables & bf}uffers;KBBUFDS 32SECMAPDS 90NUMBUFDS 6;; NOTE: NUMBUF & LINEBF must be contiguous;LINEBFDS 64INFLBFDS 16OUTFBFg}DS 16DB 'Link file pseudo>***'LINKBFDB ' LINK 'DB ' ***'DB 'Origin set pseudo>***'ORGOq}BBUILD AMABNSTART AMABaDSMINS AMAB|SYSEQU AMABMAIN AMABPROGEQU AMABDSMAIN AMABDISKIO AMAB xEXTEQU AMAB`SYSLABS AMABSCREEN AMABsSUBRS AMABuDISTABLEAMAB ZPEQU AMABCUSTOM AMABVBLANK AMAMAIN OBJBUILD OBJPDB ' ORG ',EOLDB '***'DB 'Assembly end pseudo>***'ENDOPDB ' .END $2075',EOL,' 'DB '***'DB 'r}Comment insertion flag>'DB '***'COMENTDB '1***'DB 'Line number flag>***'LNFLAGDB 0,'***'STR1DB STR1E-STR1-1DB ';Ss}ystem equates used'STR1E= *STR2DB STR2E-STR2-1DB ';End of system equates'STR2E= *DB 'Define Byte pseudo>***'STR3Dt}B STR3E-STR3-1DB '.BYTE 'STR3E= *DB '***'STR4DB STR4E-STR4-1DB ';External reference equates'STR4E= *STR5DB STR5u}E-STR5-1DB ';End of external references'STR5E= *STR6DB STR6E-STR6-1DB ';Zero-page equates'STR6E= *STR7DB STR7E-STv}R7-1DB ';End of zero-page equates'STR7E= *DB '***Max file size (hex)>'DB '***'MAXSZDW $4000DB '***'DB 'Files/diw}sk+1 (hex)>***'MAXFILDB 5,'***'MASKDB 1,2,4,8DB $10,$20,$40,$80LABMAPDS 128LABBASDS 2048ly; object code to the dicTITLE 'EXTERNAL EQUATES'SUBTTL 'File EXTEQU.AMA';; This module outputs equate pseudo-ops for all; non-system address re!y}ferences not contained in; the disassembled program.;PROCEXTEQULDA #LOW STR4;External equates commentSTA STRACCLDA!z} #HIGH STR4STA STRACC+1LDX #0JSR WRTSTRLDA #EOLSTA LINEBF,XJSR RECOUTLDA LABCNTSTA LABNR;Temp storage for LA!{}BCNT/2LDA LABCNT+1STA LABNR+1LSR LABNR+1;Divide by 2ROR LABNRLDA #0STA LABELSTA LABEL+1:LP1INC LABEL;Pick a!|} labelBNE :NOCARINC LABEL+1:NOCARSECLDA LABNRSBC LABELLDA LABNR+1SBC LABEL+1BCC :WRAPLDX LABEL;See if it w!}}as ref'dLDY LABEL+1JSR MAPACCLDA LABMAP,XAND MASK,YBNE :LP1;Yes, try anotherLDX #0;No, output equateJSR WRTLA!~}BLDA #' ':LP3STA LINEBF,XINXCPX #7BCC :LP3LDA #'='STA LINEBF,XINXLDA #' 'STA LINEBF,XINXLDA #'$'STA!} LINEBF,XINXLDY #1CLC ; Add 2x LABEL to LABBASLDA #LOW LABBAS ; to get LABACCADC LABEL;Inelegant, what?STA LA!}BACCLDA #HIGH LABBASADC LABEL+1STA LABACC+1LDA LABACCADC LABELSTA LABACCLDA LABACC+1ADC LABEL+1STA LABACC+1!}LDY #1LDA (LABACC),YBEQ :LP1;Skip hi byte if p.0JSR WRTHEXDEYLDA (LABACC),YJSR WRTHEXLDA #EOLSTA LINEBF,X!}JSR RECOUTJMP :LP1;Back for another:WRAPLDA #LOW STR5;Closing commentSTA STRACCLDA #HIGH STR5STA STRACC+1LDX #!}0JSR WRTSTRLDA #EOLSTA LINEBF,XJSR RECOUTRTSEPROCule outputs equate pseudo-ops for all; non-system address re @TITLE 'SYSTEM LABELS'SUBTTL 'File SYSLABS.AMA';; Contains the table of labels for documented; system locations on pages%} 0,2,3,D0,D2 and E4.; Pages D0 and D2 have dual label sets representing; read and write accesses for these hardware locatio%}ns.;; System labels, page zero. Repre-; sents locations $00-$7F (128; bytes);SP0DB 'LINZBS'DB $78,1,' 'DB 'CASI%}NI'DB $78,1,' 'DB 'RAMLO 'DB $78,1,' 'DB 'TRAMSZ'DB 'TSTDAT'DB 'WARMST'DB 'BOOT 'DB 'DOSVEC'DB $78,1%},' 'DB 'DOSINI'DB $78,1,' 'DB 'APPMHI'DB $78,1,' 'DB 'POKMSK'DB 'BRKKEY'DB 'RTCLOK'DB $78,1,' '%}DB $78,2,' 'DB 'BUFADR'DB $78,1,' 'DB 'ICCOMT'DB 'DSKFMS'DB $78,1,' 'DB 'DSKUTL'DB $78,1,' 'DB 'P%}TIMOT'DB 'PBPNT 'DB 'PBUFSZ'DB 'PTEMP 'DB 'ICHIDZ'DB 'ICDNOZ'DB 'ICCOMZ'DB 'ICSTAZ'DB 'ICBALZ'DB 'ICBAHZ'%}DB 'ICPTLZ'DB 'ICPTHZ'DB 'ICBLLZ'DB 'ICBLHZ'DB 'ICAX1Z'DB 'ICAX2Z'DB 'ICSPRZ'DB $78,1,' 'DB 'ICIDNO'DB '%}CIOCHR'DB 'STATUS'DB 'CHKSUM'DB 'BUFRLO'DB 'BUFRHI'DB 'BFENLO'DB 'BFENHI'DB 'CRETRY'DB 'DRETRY'DB 'BUFRFL'%}DB 'RECVDN'DB 'XMTDON'DB 'CHKSNT'DB 'NOCKSM'DB 'BPTR 'DB 'FTYPE 'DB 'FEOF 'DB 'FREQ 'DB 'SOUNDR'DB 'CRI%}TIC'DB 'FMSZPG'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' 'DB $78,6,' 'DB '%}CKEY 'DB 'CASSBT'DB 'DSTAT 'DB 'ATRACT'DB 'DRKMSK'DB 'COLRSH'DB 'TMPCHR'DB 'HOLD1 'DB 'LMARGN'DB 'RMARGN'%}DB 'ROWCRS'DB 'COLCRS'DB $78,1,' 'DB 'DINDEX'DB 'SAVMSC'DB $78,1,' 'DB 'OLDROW'DB 'OLDCOL'DB $78,1,' %} 'DB 'OLDCHR'DB 'OLDADR'DB $78,1,' 'DB 'NEWROW'DB 'NEWCOL'DB $78,1,' 'DB 'LOGCOL'DB 'ADRESS'DB $78,1%},' 'DB 'MLTTMP'DB $78,1,' 'DB 'SAVADR'DB $78,1,' 'DB 'RAMTOP'DB 'BUFCNT'DB 'BUFSTR'DB $78,1,' '%}DB 'BITMSK'DB 'SHFAMT'DB 'ROWAC 'DB $78,1,' 'DB 'COLAC 'DB $78,1,' 'DB 'ENDPT 'DB $78,1,' 'DB 'DELTA%}R'DB 'DELTAC'DB $78,1,' 'DB 'ROWINC'DB 'COLINC'DB 'SWPFLG'DB 'HOLDCH'DB 'INSDAT'DB 'COUNTR'DB $78,1,' %} ';; System labels page 2. Occupies all; of this page.;SP2DB 'VDSLST'DB $78,1,' 'DB 'VPRCED'DB $78,1,' 'D%}B 'VINTER'DB $78,1,' 'DB 'VBREAK'DB $78,1,' 'DB 'VKEYBD'DB $78,1,' 'DB 'VSERIN'DB $78,1,' 'DB 'VS%}EROR'DB $78,1,' 'DB 'VSEROC'DB $78,1,' 'DB 'VTIMR1'DB $78,1,' 'DB 'VTIMR2'DB $78,1,' 'DB 'VTIMR4'%}DB $78,1,' 'DB 'VIMIRQ'DB $78,1,' 'DB 'CDTMV1'DB $78,1,' 'DB 'CDTMV2'DB $78,1,' 'DB 'CDTMV3'DB %}$78,1,' 'DB 'CDTMV4'DB $78,1,' 'DB 'CDTMV5'DB $78,1,' 'DB 'VVBLKI'DB $78,1,' 'DB 'VVBLKD'DB $78,1%},' 'DB 'CDTMA1'DB $78,1,' 'DB 'CDTMA2'DB $78,1,' 'DB 'CDTMF3'DB 'SRTIMR'DB 'CDTMF4'DB 'INTEMP'DB '%}CDTMF5'DB 'SDMCTL'DB 'SDLSTL'DB 'SDLSTH'DB 'SSKCTL'DB $78,1,' 'DB 'LPENH 'DB 'LPENV 'DB $78,1,' 'DB $%}78,2,' 'DB $78,3,' 'DB $78,4,' 'DB 'CDEVIC'DB 'CCOMND'DB 'CAUX1 'DB 'CAUX2 'DB 'TEMP 'DB 'ERRFLG'%}DB 'DFLAGS'DB 'DBSECT'DB 'BOOTAD'DB $78,1,' 'DB 'COLDST'DB $78,1,' 'DB 'DSKTIM'DB 'LINBUF'DB $78,1,' %} 'DB $78,2,' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' 'DB $78,6,' 'DB $78,7,' 'DB $78,8,' 'DB%} $78,9,' 'DB $78,10,' 'DB $78,11,' 'DB $78,12,' 'DB $78,13,' 'DB $78,14,' 'DB $78,15,' 'DB%} $78,16,' 'DB $78,17,' 'DB $78,18,' 'DB $78,19,' 'DB $78,20,' 'DB $78,21,' 'DB $78,22,' 'D%}B $78,23,' 'DB $78,24,' 'DB $78,25,' 'DB $78,26,' 'DB $78,27,' 'DB $78,28,' 'DB $78,29,' '%}DB $78,30,' 'DB $78,31,' 'DB $78,32,' 'DB $78,33,' 'DB $78,34,' 'DB $78,35,' 'DB $78,36,' '%}DB $78,37,' 'DB $78,38,' 'DB $78,39,' 'DB 'GPRIOR'DB 'PADDL0'DB 'PADDL1'DB 'PADDL2'DB 'PADDL3'DB 'P%}ADDL4'DB 'PADDL5'DB 'PADDL6'DB 'PADDL7'DB 'STICK0'DB 'STICK1'DB 'STICK2'DB 'STICK3'DB 'PTRIG0'DB 'PTRIG1'%}DB 'PTRIG2'DB 'PTRIG3'DB 'PTRIG4'DB 'PTRIG5'DB 'PTRGI6'DB 'PTRIG7'DB 'STRIG0'DB 'STRIG1'DB 'STRIG2'DB 'STRI%}G3'DB 'CSTAT 'DB 'WMODE 'DB 'BLIM 'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' %} 'DB 'TXTROW'DB 'TXTCOL'DB $78,1,' 'DB 'TINDEX'DB 'TXTMSC'DB $78,1,' 'DB 'TXTOLD'DB $78,1,' 'DB $7%}8,2,' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' 'DB 'TMPX1 'DB 'HOLD3 'DB 'SUBTMP'DB 'HOLD2 'DB 'DMASK %}'DB 'TMPLBT'DB 'ESCFLG'DB 'TABMAP'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' '%}DB $78,6,' 'DB $78,7,' 'DB $78,8,' 'DB $78,9,' 'DB $78,$A,' 'DB $78,$B,' 'DB $78,$C,' 'D%}B $78,$D,' 'DB $78,$E,' 'DB 'LOGMAP'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB 'INVFLG'DB 'FILFLG'%}DB 'TMPROW'DB 'TMPCOL'DB $78,1,' 'DB 'SCRFLG'DB 'HOLD4 'DB 'HOLD5 'DB 'SHFLOK'DB 'BOTSCR'DB 'PCOLR0'DB '%}PCOLR1'DB 'PCOLR2'DB 'PCOLR3'DB 'COLOR0'DB 'COLOR1'DB 'COLOR2'DB 'COLOR3'DB 'COLOR4'DB $78,1,' 'DB $78,2%},' 'DB $78,3,' 'DB $78,4,' 'DB $78,5,' 'DB $78,6,' 'DB $78,7,' 'DB $78,8,' 'DB $78,9,' %}'DB $78,10,' 'DB $78,11,' 'DB $78,12,' 'DB $78,13,' 'DB $78,14,' 'DB $78,15,' 'DB $78,16,' %} 'DB $78,17,' 'DB $78,18,' 'DB $78,19,' 'DB $78,20,' 'DB $78,21,' 'DB $78,22,' 'DB $78,23,' %} 'DB 'GLBABS'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB 'RAMSIZ'DB 'MEMTOP'DB $78,1,' 'DB 'MEMLO '%}DB $78,1,' 'DB $78,2,' 'DB 'DVSTAT'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB 'CBAUDL'DB 'CBAUDH'D%}B 'CRSINH'DB 'KEYDEL'DB 'CH1 'DB 'CHACT 'DB 'CHBAS 'DB $78,1,' 'DB $78,2,' 'DB $78,3,' 'DB $78,4,'%} 'DB $78,5,' 'DB 'CHAR 'DB 'ATACHR'DB 'CH 'DB 'FILDAT'DB 'DSPFLG'DB 'SSFLAG';; Page 3;SP3DB 'DDE%}VIC'DB 'DUNIT ' DB 'DCOMND'DB 'DSTATS'DB 'DBUFLO'DB 'DBUFHI'DB 'DTIMLO'DB 'DUNUSE'DB 'DBYTLO'DB 'DBYTHI'%}DB 'DAUX1 'DB 'DAUX2 'DB 'TIMER1'DB $78,1,' 'DB 'ADDCOR'DB 'CASFLG'DB 'TIMER2'DB $78,1,' 'DB 'TEMP1 '%}DB $78,1,' 'DB 'TEMP2 'DB 'TEMP3 'DB 'SAVIO 'DB 'TIMFLG'DB 'STACKP'DB 'TSTAT 'DB 'HATABS' DB $78,1,%}' ' DB $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' %}' DB $78,7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' %} DB $78,12,' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' ' DB $78,16,' ' %} DB $78,17,' ' DB $78,18,' ' DB $78,19,' ' DB $78,20,' ' DB $78,21,' ' %} DB $78,22,' ' DB $78,23,' ' DB $78,24,' ' DB $78,25,' ' DB $78,26,' ' %} DB $78,27,' ' DB $78,28,' ' DB $78,29,' ' DB $78,30,' ' DB $78,31,' ' %} DB $78,32,' ' DB $78,33,' ' DB $78,34,' ' DB $78,35,' ' DB $78,36,' ' %} DB $78,37,' 'DB 'ICHID 'DB 'ICDNO 'DB 'ICCOM 'DB 'ICSTA 'DB 'ICBAL 'DB 'ICBAH 'DB 'ICPTL 'DB 'ICPTH%} 'DB 'ICBLL 'DB 'ICBLH 'DB 'ICAX1 'DB 'ICAX2 'DB 'ICSPR ' DB $78,1,' ' DB $78,2,' ' D%}B $78,3,' ';; Page D0 (read);SPD0RDB 'M0PF 'DB 'M1PF 'DB 'M2PF 'DB 'M3PF 'DB 'P0PF 'DB 'P1PF 'DB 'P%}2PF 'DB 'P3PF 'DB 'M0PL 'DB 'M1PL 'DB 'M2PL 'DB 'M3PL 'DB 'P0PL 'DB 'P1PL 'DB 'P2PL 'DB 'P3PL '%}DB 'TRIG0 'DB 'TRIG1 'DB 'TRIG2 'DB 'TRIG3 ';; Page D0 (write);SPD0WDB 'HPOSP0'DB 'HPOSP1'DB 'HPOSP2'DB 'HPO%}SP3'DB 'HPOSM0'DB 'HPOSM1'DB 'HPOSM2'DB 'HPOSM3'DB 'SIZEP0'DB 'SIZEP1'DB 'SIZEP2'DB 'SIZEP3'DB 'SIZEM 'DB%} 'GRAFP0'DB 'GRAFP1'DB 'GRAFP2'DB 'GRAFP3'DB 'GRAFM 'DB 'COLPM0'DB 'COLPM1'DB 'COLPM2'DB 'COLPM3'DB 'COLPF0%}'DB 'COLPF1'DB 'COLPF2'DB 'COLPF3'DB 'COLBK 'DB 'PRIOR 'DB 'VDELAY'DB 'GRACTL'DB 'HITCLR'DB 'CONSOL';;Pag%}e D2 (read);SPD2RDB 'POT0 'DB 'POT1 'DB 'POT2 'DB 'POT3 'DB 'POT4 'DB 'POT5 'DB 'POT6 'DB 'POT7 'D%}B 'ALLPOT'DB 'KBCODE'DB 'RANDOM'DB 'POTGO 'DB $78,1,' 'DB 'SERIN 'DB 'IRQST 'DB 'SKSTAT'SPD2WDB 'AUDF1 '%}DB 'AUDC1 'DB 'AUDF2 'DB 'AUDC2 'DB 'AUDF3 'DB 'AUDC3 'DB 'AUDF4 'DB 'AUDC4 'DB 'AUDCTL'DB 'STIMER'DB 'SKRE%}S 'DB $78,1,' 'DB $78,2,' 'DB 'SEROUT'DB 'IRQEN 'DB 'SKCTL ';; Page D4;SPD4DB 'DMACTL'DB 'CHACTL'DB %}'DLISTL'DB 'DLISTH'DB 'HSCROL'DB 'VSCROL'DB $78,1,' 'DB 'PMBASE'DB $78,1,' 'DB 'CHBASE'DB 'WSYNC 'DB %}'VCOUNT'DB 'PENH 'DB 'PENV 'DB 'NMIEN 'DB 'NMIST ';; Page E4;SPE4DB 'EDITRV' DB $78,1,' ' D%}B $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' ' DB $78%},7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' DB $78,12%},' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' 'DB 'SCRENV' DB $78,1,' ' %} DB $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' ' DB%} $78,7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' DB $7%}8,12,' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' 'DB 'KEYBDV' DB $78,1,' ' %} DB $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' ' %} DB $78,7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' D%}B $78,12,' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' 'DB 'PRINTV' DB $78,1,' %} ' DB $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' ' %} DB $78,7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' %} DB $78,12,' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' 'DB 'CASETV' DB $78,1,%}' ' DB $78,2,' ' DB $78,3,' ' DB $78,4,' ' DB $78,5,' ' DB $78,6,' %}' DB $78,7,' ' DB $78,8,' ' DB $78,9,' ' DB $78,10,' ' DB $78,11,' ' %} DB $78,12,' ' DB $78,13,' ' DB $78,14,' ' DB $78,15,' 'DB 'DISKIV' DB $7%}8,1,' ' DB $78,2,' 'DB 'DSKINV' DB $78,1,' ' DB $78,2,' 'DB 'CIOV ' DB $78,1%},' ' DB $78,2,' 'DB 'SIOV ' DB $78,1,' ' DB $78,2,' 'DB 'SETVBV' DB $78,1,' %} ' DB $78,2,' 'DB 'SYSVBV' DB $78,1,' ' DB $78,2,' 'DB 'XITVBV' DB $78,1,' %}' DB $78,2,' 'DB 'SIOINV' DB $78,1,' ' DB $78,2,' 'DB 'SENDEV' DB $78,1,' ' %} DB $78,2,' 'DB 'INTINV' DB $78,1,' ' DB $78,2,' 'DB 'CIOINV' DB $78,1,' ' %} DB $78,2,' 'DB 'BLKBDV' DB $78,1,' ' DB $78,2,' 'DB 'WARMSV' DB $78,1,' ' %} DB $78,2,' 'DB 'COLDSV' DB $78,1,' ' DB $78,2,' 'DB 'RBLOKV' DB $78,1,' ' DB%} $78,2,' 'DB 'CSOPIV' DB $78,1,' ' DB $78,2,' 'DB 'VCTABL';; End of sys equates;ons on pages$qTITLE 'Module SCREEN'SUBTTL 'File SCREEN.AMA';; This module contains text for the output messages.;;PROCLOGOLDW :L)}OGOE-LOGOLOGODB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB TAB,' 'DB $C4,$C9,$D3,$CB,$A0DB $C4,$C9,$D3,$C1,$D)}3,$D3DB $C5,$CD,$C2,$CC,$C5,$D2DB EOL,SKIP,TAB,' 'DB 'Copyright 1982 'DB 'Ralph Jones',EOLDB SKIP,SKIP,TAB,' 'D)}B 'How many DISK 'DB 'DRIVES?',EOLDB SKIP,TAB,TAB,' ',BELL:LOGOE= *;MSG1LDW :MSG1E-MSG1MSG1DB CLEAR,SKIP,SKIP,S)}KIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,SKIP,' 'DB '(F)ile, (S)ector 'DB 'or (M)emory input?'DB EOL,SKIP,SKIPDB TAB,TAB,)}' ',BELL:MSG1E= *;MSG2LDW :MSG2E-MSG2MSG2DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,SKIP,TAB,' 'D)}B 'Enter INPUT file'DB 'spec',EOL,SKIP,TABDB ' ',BELL:MSG2E= *;MSG3LDW :MSG3E-MSG3MSG3DB CLEAR,SKIP,SKIP,SKIP)}DB SKIP,SKIP,SKIP,SKIPDB SKIP,TAB,' 'DB 'Enter OUTPUT file'DB 'spec',EOL,SKIP,TABDB ' 'DB '(NO extender)')},EOLDB SKIP,TAB,TAB,BELL:MSG3E= *;MSG4LDW :MSG4E-MSG4MSG4DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,TA)}B,' 'DB 'Enter sector list 'DB 'in HEX',EOL,SKIPDB TAB,'mn for'DB ' single sector',EOLDB TAB,' mn,pq'DB ' for sequence',EOLDB TAB,' 'DB 'to end list',EOLDB SKIP,TAB,TAB,' ',BELL:MSG4E= *;MSG5LDW )}:MSG5E-MSG5MSG5DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,' Enter program'DB ' start address in 'DB 'HEX)}',EOL,SKIP,TAB,TABDB 'strt',EOLDB SKIP,TAB,TAB,' ',BELL:MSG5E= *;MSG6LDW :MSG6E-MSG6MSG6DB CLEAR,SKIP,S)}KIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,' Enter start, end'DB ' addresses in HEX',EOLDB SKIP,TAB,' ssss,'DB )}'eeee',EOLDB SKIP,TAB,TAB,' ',BELL:MSG6E= *;MSG7LDW :MSG7E-MSG7MSG7DB TAB,TAB,'OK',EOL,TAB,TAB,' ':MSG7E)}= *;MSG8LDW :MSG8E-MSG8MSG8DB TAB,TAB,'ERROR-NO ENTRY'DB EOL,TAB,TAB,' ',BELL:MSG8E= *;MSG9LDW :MSG9E-MSG9MSG9)}DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,SKIP,TAB,' 'DB $C6,$C1,$D4,$C1,$CCDB $A0,$C9,$AF,$CF,$A0D)}B $C5,$D2,$D2,$CF,$D2DB $A1,EOL,SKIP,TABDB 'Press to 'DB 'start over',EOL,BELL:MSG9E= *;MSG10LDW :MS10E-MS)}G10MSG10DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,TAB,' 'DB 'Insert ',$C9,$CEDB $D0,$D5,$D4,' disk')}DB EOL,SKIP,TAB,TABDB 'and press',EOL,SKIPDB TAB,TAB,' ',EOL,BELL:MS10E= *;MSG11LDW :MS11E-MSG11MSG11DB C)}LEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,TAB,' 'DB 'Insert ',$CF,$D5,$D4DB $D0,$D5,$D4,' disk'DB EOL,SK)}IP,TAB,TABDB 'and press',EOL,SKIPDB TAB,TAB,' ',EOL,BELL:MS11E= *;MSG12LDW :MS12E-MSG12MSG12DB CLEAR,SKIP,)}SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB ' Insert ',$C9,$CEDB $D0,$D5,$D4,' disk 'DB 'in Drive 1',EOLDB SKIP,TAB, 'and )}'DB $CF,$D5,$D4,$D0,$D5,$D4DB ' disk in Drive 2',EOLDB SKIP,TAB,' and 'DB 'press ',EOL,BELL:MS12E= *;M)}SG13LDW :MS13E-MSG13MSG13DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,TAB,' 'DB $C4,$C9,$D3,$C1DB $D3,$D)}3,$C5,$CDDB $C2,$CC,$D9,' 'DB $C3,$CF,$CD,$D0DB $CC,$C5,$D4,$C5DB EOL,SKIP,TAB, 'Press'DB ' to 'DB 'run )}again',EOL,BELL:MS13E= *;MSG14LDW :MS14E-MSG14MSG14DB CLEAR,SKIP,SKIP,SKIPDB SKIP,SKIP,SKIP,SKIPDB SKIP,TAB,' )} 'DB $CF,$D5,$D4,$D0,$D5,$D4DB $A0,$C4,$C9,$D3,$CBDB $A0,$C6,$D5,$CC,$CCDB EOL,SKIP,TAB,' 'DB 'Insert another d*}isk',EOLDB SKIP,TAB,' and 'DB 'press ',EOL,BELL:MS14E= *;MSG15LDW :MS15E-MSG15MSG15DB 'CREATING LABELS*}...'DB ' ':MS15E= *;EPROCThis module contains text for the output messages.;;PROCLOGOLDW :L(5 TITLE 'SUBROUTINES'SUBTTL 'File SUBRS.AMA';; Utility subroutine library;;;******************;; WRTOP;;****.}**************;; Writes an operand (system or internal label); into the text line buffer.;; Enter ADRBUF(2)=referenced a.}ddress; X=offset (from LINEBF) to start writing;; Exit X=offset of next available output bytePROCWRTOPTXA;Sav.}e XPHAJSR GETSYS;System label?BCS :WRT1;NoJSR ADRSYS;Yes, get its addressPLA ;and output itTAXJSR WRTSY.}SRTS:WRT1JSR GETLAB;Get label IDPLATAXJSR WRTLAB;Output itRTSEPROC;;;*******************;; ADRSYS;.};*******************;; Computes memory address of a system label.;; Enter SYSBAS(2)=page base address; ADRBUF=add.}ress lo byte; Exit SYSACC(2)=pointer to label;; Preserves X register;PROCADRSYSLDA #0STA SYSACCSTA SYSACC+1;; . }Multiply ADRBUFx6 to get offset from SYSBAS;LDY #6:LP1CLCLDA SYSACCADC ADRBUFSTA SYSACCLDA SYSACC+1ADC #0STA. } SYSACC+1DEYBNE :LP1;; Now add it to SYSBAS;CLCLDA SYSACCADC SYSBASSTA SYSACCLDA SYSACC+1ADC SYSBAS+1STA. } SYSACC+1RTSEPROC;;;*********************;; GETSYS;;*********************;; Checks an address for system r. }eferences.;; Enter ADRBUF(2)=referenced address; Exit SYSBAS(2)=base address of system page group; ADRBUF=system a. }ddress lo byte; Carry=Clear (system location); Set (not system location);PROCGETSYSLDX #0:GS2CPX #[PTBEND-P.}AGTAB]BCS :GSBADLDA PAGTAB,X;Sys page addr (lo)STA SYSBASINXLDA PAGTAB,X;Sys page addr (hi)STA SYSBAS+1INXL.}DA PAGTAB,X;Sys page numberSTA PAGNOINXLDA PAGTAB,X;Sys page topSTA PAGTOPINXLDA PAGTAB,X;Read/write access fl.}agSTA WRTFLGINXLDA PAGNO;Look at page nrCMP ADRBUF+1;Are we on this page?BNE :GS2;No, try anotherLDA PAGTOPC.}MP ADRBUF;Within page limits?BCC :GSBAD;No, bomb outLDA WRTFLG;Yes, get page access directionBMI :GSOK;Don't care, .}go onJSR RDORWR;Get kind of instructionCMP WRTFLG;and compare with page typeBNE :GS2 ;Mismatch, go back:GSOKCLC .};SuccessRTS:GSBADSEC ;FailureRTSEPROC;;;********************;; WRTSYS;;********************;; Writ.}es a system label (with offset if applicable); into the text line buffer.;; Enter SYSACC(2)=address of label;X=offset (f.}rom LINEBF) of operand;ExitX=offset of next byte;PROCWRTSYSLDY #0STY SYSOFF;Assume no offsetLDA (SYSACC),Y;Get f.}irst byteAND #$7F;Remove referenced bitCMP #'x';Offset flag?BNE :NOOFF;No, no offsetINY ;Yes, get offsetLDA (S.}YSACC),YSTA SYSOFF;Save it;; Now we have the address in SYSACC and the offset; from the system label in SYSOFF. Next we.} have to; back up 6xSYSOFF to find the actual label.;LDY #6:MLTSSEC;Multiple subtraction loopLDA SYSACCSBC SYSOFF.}STA SYSACCLDA SYSACC+1SBC #0STA SYSACC+1DEYBNE :MLTS:NOOFFLDY #0:LP1LDA (SYSACC),Y;Move label into LINEBFA.}ND #$7F;Clear hi bitCMP #' 'BEQ :CKOFFSTA LINEBF,XINXINYCPY #6BCC :LP1:CKOFFLDA SYSOFF ;Offset?BNE :OFF;.}Yes, process itRTS;No, we're done.:OFFLDA #'+'STA LINEBF,XINXTXAPHA;Save XLDA SYSOFFSTA FR0;Convert offs.}et to ASCIILDA #0STA FR0+1JSR IFPJSR FASCPLA;Recover XTAXJSR WRTNUM;Output offsetRTS;and hang it up.;;.}********************;; GETLAB;;********************;; Computes the ID number of the internal label; represented .}by an address.;; Enter ADRBUF(2)=referenced address;; Exit LABEL(2)=label ID;Carry=Clear (label found); Set (no.} label);PROCGETLABLDA #LOW LABBAS;InitializeSTA LABACC; the label pointerLDA #HIGH LABBASSTA LABACC+1:LOOPCLC. }LDA LABACCADC #2;Step pointerSTA LABACCLDA LABACC+1ADC #0STA LABACC+1LDY #0LDA (LABACC),Y;Label address=loc c.!}ounter?CMP ADRBUFBNE :NOMATINYLDA (LABACC),YCMP ADRBUF+1BNE :NOMATSEC;Yes, compute label #.LDA LABACC;Get ."}table offsetSBC #LOW LABBASSTA LABELLDA LABACC+1SBC #HIGH LABBASSTA LABEL+1LSR LABEL+1;and divide by 2ROR LABE.#}L;and we have the label number.:GLXITCLC;Signal successRTS;and we're done.:NOMATSEC;No matchLDA LABACC;So are.$} we out of labels?SBC LABTOPLDA LABACC+1;Don't need to storeSBC LABTOP+1BCC :LOOP;No, try another.LDA #0;Yes, fl.%}ag the failure.STA LABELSTA LABEL+1SEC:EXIT RTS;and we're done.EPROC;;;******************;; FLGLAB;;*.&}*****************;; Subroutine to flag a label number as "internal"; in the label map,or to unflag it.;; Enter LABEL(2)=.'}label number; Acc=0 (unflag); nonzero (flag);; No exit parameters.;PROCFLGLABPHA ;Save acc keyLDX LABEL .(} ;Locate label flagLDY LABEL+1JSR MAPACCLDA LABMAP,XORA MASK,YSTA LABMAP,X;Set itPLA ;Get keyBNE :EXIT;F.)}lag, we're doneLDA LABMAP,X;UnflagEOR MASK,Y;So clear the bitSTA LABMAP,X:EXITRTSEPROC;;;******************;.*}; WRTLAB;;******************;; Writes an internal label into the output text buffer.;; Enter LABEL(2)=label ID;X.+}=offset (from LINEBF) to label; Exit X=offset to next output byte;PROCWRTLABLDA LABEL;Does a label exist?BNE :DOIT.,};Yes, do itLDA LABEL+1BNE :DOITLDA #'$';No, table full, enterSTA LINEBF,X;the address instead.INXLDY #1:LPLDA.-} ADRBUF,YJSR WRTHEXDEYBPL :LPRTS:DOITTXASTA TEMPPHA;Save XLDA LABELSTA FR0;Convert to ASCIILDA LABEL+1..}STA FR0+1JSR IFPJSR FASCPLATAX;Recover X;; The label number is to be 4-digit fixed-field so; now we index to t./}he 4th digit.;INXINXINXINXTXA ;Save XPHA;; Now use Y to find the index to last byte; of label nr in the FP .0}buffer.;LDY #$FF:LP2INYLDA (INBUFF),Y;Bit 7 set?BPL :LP2;No, try another;; Found the offset. Now move label nr t.1}o buffer;:LP4LDA (INBUFF),YAND #$7FSTA LINEBF,XDEXDEYBPL :LP4LDA #'0':LP6CPX TEMPBEQ :PREFSTA LINEBF,X.2}DEXJMP :LP6;; Now insert the label prefix: Z if zero-page,; L otherwise;:PREFLDA #'L'LDY ADRBUF+1BNE :NOTZPLDA .3}#'Z':NOTZPSTA LINEBF,XPLA ;Recover XTAXINX ;Index to next byteRTSEPROC;; ;********************;.4}; WRTNUM;;********************;; Writes an ASCII number into the output text buffer.;; Enter INBUFF(2) points to .5}ASCII number;X=offset (from LINEBF) to first digit; Exit X=offset to next output byte;; Note:expects ASCII number in th.6}e format generated; by the FP package (variable field length, high bit; set in last BCD digit).;PROCWRTNUMDEXLDY #$F.7}F:LP1INXINYLDA (INBUFF),Y;Get BCD digitSTA LINEBF,XBPL :LP1 ;Last byte?AND #$7F ;Yes, clear high bitSTA LINE.8}BF,X;and store again.INX;Index next byteRTS;and split.EPROC;;;*******************;; LNNUM;;**********.9}*********;; Subroutine to attach a source line number,; incrementing the current number in NUMBUF.;; No parameters.;P.:}ROCLNNUMLDX #3;Operate on 10's digit:LN2LDY NUMBUF,XINYCPY #':'BCC :LN4LDA #'0'STA NUMBUF,XDEXBPL :LN2:LN.;}4TYASTA NUMBUF,XRTSEPROC;;;*******************;; FLGSYS;;*******************;; Flags a system label to .<}indicate it has; been referenced.;; Enter SYSBAS(2)=system page base address;ADRBUF=address lo byte; Exit byte 0 of la.=}bel has high bit set;PROCFLGSYSJSR ADRSYS;Get label addressLDY #0LDA (SYSACC),Y;Get byte 0AND #$7F;Clear hi bit.>}CMP #'x';Offset location?BNE :NOOFFINYLDA (SYSACC),YSTA SYSOFFLDY #6:LPSECLDA SYSACCSBC SYSOFFSTA SYSACC.?}LDA SYSACC+1SBC #0STA SYSACC+1DEYBNE :LP:NOOFFLDY #0LDA (SYSACC),YORA #$80;Set high bitSTA (SYSACC),Y;and.@} restore.RTSEPROC;;;*********************;; ENTERL;;*********************;; Enters an address in the label.A} table.;; Enter ADRBUF(2)=address to enter; No exit params.;PROCENTERLSEC;Is label table full?LDA LABCNTSBC #LO.B}W[BIGBUF-LABBAS-2]LDA LABCNT+1SBC #HIGH[BIGBUF-LABBAS-2]BCS :ENXIT;; Carry must be clear;LDA LABCNT;2x nr of labe.C}lsADC #2;Increment itSTA LABCNTLDA LABCNT+1ADC #0STA LABCNT+1CLCLDA #LOW LABBASADC LABCNT;Add to table base.D}STA LABACCSTA LABTOPLDA #HIGH LABBASADC LABCNT+1STA LABACC+1STA LABTOP+1LDY #0LDA ADRBUF;Get the addressST.E}A (LABACC),Y;and store itINYLDA ADRBUF+1STA (LABACC),Y:ENXITRTSEPROC;;;*************************;; CLR.F}BUF;;*************************;; Clears instruction and text output buffers; and resets their pointers.;PROCCLRBUFL.G}DA #' 'LDX #35:LP1STA LINEBF,XDEXBPL :LP1LDA #0LDX #7:LP2STA INSBUF,XDEXBPL :LP2STA TEXCNTSTA INSPTRS.H}TA BTFLGRTSEPROC;;;*********************;; TEXOUT;;*********************;; Converts contents of INSBUF to .I}a text; pseudo-op and outputs it.;PROCTEXOUTLDX #7LDA #LOW STR3;Pseudo-opSTA STRACCLDA #HIGH STR3STA STRACC+1.J}JSR WRTSTR;Output itLDX #7 ;Find end:LP0INXCPX #$DBNE :OKLDA #' ' ;Too long, truncateSTA LINEBF,XINXL.K}DY #0JMP :LP1:OKLDA LINEBF,XCMP #' 'BNE :LP0INXLDY #0:LP1LDA #'$'STA LINEBF,XINXLDA INSBUF,YJSR WRTHEX.L}LDA #','STA LINEBF,XINXINYDEC TEXCNT;Any text left?BNE :LP1;Yes, go backDEX ;Back up oneLDA #EOL;to repl.M}ace final commaSTA LINEBF,XJSR RECOUT;Output itJSR CLRBUF;Clear buffersRTSEPROC;;*********************;; .N} WRTSTR;;*********************;; Writes a string to the text output buffer.;; Enter STRACC(2)=pointer to start of stri.O}ng; First byte of string=length;X=pointer to start point in output buffer;; No exit parameters.;PROCWRTSTRLDY.P} #0LDA (STRACC),Y;Get string lengthSTA STRLEN:LP1INYLDA (STRACC),Y;Get string byteSTA LINEBF,X;Output itINXD.Q}EC STRLEN;Any left?BNE :LP1;Yes, go backRTS;No, doneEPROC;;********************;; WRTHEX;;*************.R}*******;; Writes a hex number to the output buffer in ASCII form.;; Enter Acc=hex byte;X=pointer to start point in buff.S}er;; Exit X=pointer to next byte in buffer;WRTHEXPHA;Save byteLSR ALSR ALSR ALSR A ;Get high nibbleJSR NI.T}BASC;Convert to ASCIISTA LINEBF,X;Output itINXPLA;Recover byteAND #$0F;Get lo nibbleJSR NIBASC;Convert to ASC.U}IISTA LINEBF,X;Output itINXRTS;;********************;; NIBASC;;********************;; Converts a hex nib.V}ble to an ASCII chracter.;; Enter Acc=hex nibble;; Exit Acc=ASCII byte;PROCNIBASCCLCADC #$30CMP #$3ABCC :NOAD.W}DCLCADC #$07:NOADDRTSEPROC;;;********************;; CLRSEC;;********************;; Subroutine to clear.X} active sector map;PROCCLRSECLDA #0LDX #$59;90 bytes to clear:LP1STA SECMAP,X;Clear a byteDEXBPL :LP1RTSEP.Y}ROC;;;********************;; CLRLAB;;********************;CLRLABLDA #0LDX #127:LP1STA LABMAP,XDEXBPL .Z}:LP1RTSEPROC;;;********************;; MAPACC;;********************;; Subroutine to access active sector/ref.[}erenced label maps;; Enter X,Y=sector number (lo,hi); Exit X=byte number in map;Y=bit number in byte;MAPACCLDA #0S.\}TA TEMP+1;Clear bit numberSTX TEMP;Sector nr (lo)TYA;Sector nr (hi)LDX #3;Divide-by-8 routineMAPAC1LSR AROR TE.]}MPROR TEMP+1DEXBNE MAPAC1;; Now we have byte number (=sec/8) in TEMP;LDX #5;Divide-by-32 routineMAPAC2LSR TEMP+.^}1DEXBNE MAPAC2;; Now we have bit number in TEMP+1;LDX TEMPLDY TEMP+1RTS;;;*********************;; RDO._}RWR;;*********************;; Subroutine to determine whether a system label is; accessed by a read or write instruction..`} Used in; selecting the proper system label for; hardware locations.;; Enter INSBUF=opcode oc current instruction; Exit.a}Z bit=set for write access; clear for read access;PROCRDORWRLDA INSBUF;Get opcodeAND #%11100111CMP #%1000011.b}0BEQ :WRXITCMP #%10000100BEQ :WRXITAND #%11100011CMP #%10000001BEQ :WRXITLDA #1RTS:WRXITLDA #0RTSEPROC.c};;;**********************;; ADRCOM;;**********************;; Writes a comment into LINEBF indicating the; add.d}ress referenced by a label.;; Enter ADRBUF(2) contains the address;X=LINEBF offset to start of comment;; Exit X=offset.e} to next available output byte;PROCADRCOMLDA COMENTBEQ :EXITLDA #' 'STA LINEBF,XINXLDA #';'STA LINEBF,XINX.f}LDA #'$'STA LINEBF,XINXLDY #1:LPLDA ADRBUF,YJSR WRTHEXDEYBPL :LP:EXITRTSEPROC;;;**********************.g};; RELADR;;**********************;; Subroutine to compute the absolute address referenced; by a branch instruct.h}ion.;; Enter STAR(2)=current location counter; (address of first byte after instruction);ADRBUF=branch displacem.i}ent;; Exit ADRBUF(2)=asolute address;PROCRELADRLDA #0STA ADRBUF+1LDA ADRBUF;Forward branch?BPL :FWD;Yes, go o.j}nLDA #$FF;No, fill out displacementSTA ADRBUF+1:FWDCLC;Add disp to addrLDA ADRBUFADC STARSTA ADRBUFLDA ADRBU.k}F+1ADC STAR+1STA ADRBUF+1RTSEPROC;;;***********************;; LABMSG;;***********************;; Subr.l}outine to output a screen message to; indicate label creation in progress.;; No parameters;LABMSGLDX #0LDA #PUTCHRS.m}TA ICCOM,XLDA MSG15LSTA ICBLL,XSTX ICBLHLDA #LOW MSG15STA ICBAL,XLDA #HIGH MSG15STA ICBAH,XJSR CIOVRTS;;*.n}*********************;; LINADR;;**********************;; Subroutine to output address of the current; instructi.o}on line to the screen and (if selected); the printer.;; Enter STAR(2)=line address;; No exit parameters.;PROCLINADR.p}LDX #0;Index to LABUFLDY #1:LP0LDA STAR,YLSR ALSR ALSR ALSR AJSR NIBASCSTA LABUF,XINXLDA STAR,YAND #$0.q}FJSR NIBASCSTA LABUF,XINXDEYBPL :LP0LDA #' 'STA LABUF,XLDX #0JSR CIOLA;Output address to E:LDA PROPT;Pr.r}int?AND PROPENBEQ :EXIT;NoLDX #$30;YesJSR CIOLABPL :EXITLDA #$FFSTA FREEZE:EXITRTSCIOLALDA #PUTCHRSTA I.s}CCOM,XLDA #5STA ICBLL,XLDA #0STA ICBLH,XLDA #LOW LABUFSTA ICBAL,XLDA #HIGH LABUFSTA ICBAH,XJSR CIOVRTSE.t}PROC; 'SUBROUTINES'SUBTTL 'File SUBRS.AMA';; Utility subroutine library;;;******************;; WRTOP;;****,TITLE 'DISASSEMBLY TABLES'SUBTTL 'File DISTABLE.AMA';; Disassembler data tables.; Table MNETEX is mnemonic text.; Tab2v}le MNEIND translates opcode to MNETEX offset.; Table MODES translates opcode to addressing mode ID.;; This is the table of2w} instruction mnemonics.;MNETEXDB 'ADCANDASLBCC'DB 'BCSBEQBITBMI'DB 'BNEBPLBRKBVC'DB 'BVSCLCCLDCLI'DB 'CLVCMPCPXCPY2x}'DB 'DECDEXDEYEOR'DB 'INCINXINYJMP'DB 'JSRLDALDXLDY'DB 'LSRNOPORAPHA'DB 'PHPPLAPLPROL'DB 'RORRTIRTSSBC'DB 'SECS2y}EDSEISTA'DB 'STXSTYTAXTAY'DB 'TSXTXATXSTYA';; This is the table of offsets to table MNETEX.; Each entry indexes the LA2z}ST character of its mnemonic.;MNEINDDB 32,104,255,255,255,104,8,255DB 110,104,8,255,255,104,8,255 DB 29,104,255,2{}255,255,104,8,255DB 41,104,255,255,255,104,8,255DB 86,5,255,255,20,5,119,255DB 116,5,119,255,20,5,119,255DB 23,5,255,2|}255,255,5,119,255DB 134,5,255,255,255,5,119,255DB 125,71,255,255,255,71,98,255DB 107,71,98,255,83,71,98,255DB 35,71,22}}55,255,255,71,98,255DB 47,71,255,255,255,71,98,255DB 128,2,255,255,255,2,122,255DB 113,2,122,255,83,2,122,255DB 38,2,2~}255,255,255,2,255,255DB 140,2,255,255,255,2,255,255DB 255,143,255,255,149,143,146,255DB 68,255,161,255,149,143,146,2552}DB 11,143,255,255,149,143,146,255DB 167,143,164,255,255,143,255,255DB 95,89,92,255,95,89,92,255DB 155,89,152,255,95,892},92,255DB 14,89,255,255,95,89,92,255DB 50,89,158,255,95,89,92,255DB 59,53,255,255,59,53,62,255DB 80,53,65,255,59,53,62}2,255DB 26,53,255,255,255,53,62,255DB 44,53,255,255,255,53,62,255DB 56,131,255,255,56,131,74,255DB 77,131,101,255,56,2}131,74,255DB 17,131,255,255,255,131,74,255DB 137,131,255,255,255,131,74,255;; This is the table of addressing mode ID's2}.; It uses the following equates:;IMPEQU $00;ImpliedACCEQU $02 ;AccumulatorIMMEQU $24;ImmediateRELEQU $2}26;RelativeABSEQU $48;Absolute (JMP/JSR only)ABSREQU $48;Absolute, read accessABSWEQU $C8;Absolute, write accessXR2}EQU $4A;Absolute,X,readXWEQU $CA;Absolute,X,writeYREQU $4C;Absolute,Y,readYWEQU $CC;Absolute,Y,writeZPREQU $2E;2}Zero-page, readZPWEQU $AE;Zero-page,writeZPXREQU $30;Zero-page,X,readZPXWEQU $B0;Zero-page,X,writeZPYREQU $32;Zer2}o-page,Y,readZPYWEQU $B2;Zero-page,Y,writeINDEQU $54;Indirect (JSR only)INDXREQU $36;Indirect,X,readINDXWEQU $B6;2}Indirect,X,writeINDYREQU $38;Indirect,Y,readINDYWEQU $B8;Indirect,Y,writeNOPEQU $FF;Not an opcode;MODESDB IMP,IND2}XR,NOP,NOP,NOP,ZPR,ZPW,NOPDB IMP,IMM,ACC,NOP,NOP,ABSR,ABSW,NOPDB REL,INDYR,NOP,NOP,NOP,ZPXR,ZPXW,NOPDB IMP,YR,NOP,NOP,N2}OP,XR,XW,NOPDB ABS,INDXR,NOP,NOP,ZPR,ZPR,ZPW,NOPDB IMP,IMM,ACC,NOP,ABSR,ABSR,ABSW,NOPDB REL,INDYR,NOP,NOP,NOP,ZPXR,ZPXW2},NOPDB IMP,YR,NOP,NOP,NOP,XR,XW,NOPDB IMP,INDXR,NOP,NOP,NOP,ZPR,ZPW,NOPDB IMP,IMM,ACC,NOP,ABS,ABSR,ABSW,NOPDB REL,IND2}YR,NOP,NOP,NOP,ZPXR,ZPXW,NOPDB IMP,YR,NOP,NOP,NOP,XR,XW,NOPDB IMP,INDXR,NOP,NOP,NOP,ZPR,ZPW,NOPDB IMP,IMM,ACC,NOP,IND,A2}BSR,ABSW,NOPDB REL,INDYR,NOP,NOP,NOP,ZPXR,NOP,NOPDB IMP,YR,NOP,NOP,NOP,XR,NOP,NOPDB NOP,INDXW,NOP,NOP,ZPW,ZPW,ZPW,NOP2}DB IMP,NOP,IMP,NOP,ABSW,ABSW,ABSW,NOPDB REL,INDYW,NOP,NOP,ZPXW,ZPXW,ZPYW,NOPDB IMP,YW,IMP,NOP,NOP,XW,NOP,NOPDB IMM,INDX2}R,IMM,NOP,ZPR,ZPR,ZPR,NOPDB IMP,IMM,IMP,NOP,ABSR,ABSR,ABSR,NOPDB REL,INDYR,NOP,NOP,ZPXR,ZPXR,ZPYR,NOPDB IMP,YR,IMP,NOP,2}XR,XR,YR,NOPDB IMM,INDXR,NOP,NOP,ZPR,ZPR,ZPW,NOPDB IMP,IMM,IMP,NOP,ABSR,ABSR,ABSW,NOPDB REL,INDYR,NOP,NOP,NOP,ZPXR,ZPXW2},NOPDB IMP,YR,NOP,NOP,NOP,XR,XW,NOPDB IMM,INDXR,NOP,NOP,ZPR,ZPR,ZPW,NOPDB IMP,IMM,IMP,NOP,ABSR,ABSR,ABSW,NOPDB REL,IN2}DYR,NOP,NOP,NOP,ZPXR,ZPXW,NOPDB IMP,YR,NOP,NOP,NOP,XR,XW,NOPembler data tables.; Table MNETEX is mnemonic text.; Tab0CTITLE 'ZERO-PAGE EQUATES'SUBTTL 'File ZPEQU.AMA';; This module outputs equate statements; for all referenced zero-page 6}locations other; than system locations. These equates must be; placed at the front of the pseudo-source file; because of t6}he zero-page forward reference problem; in 6502 assemblers.;PROCZPEQULDA #LOW STR6;Output opening msgSTA STRACCLDA6} #HIGH STR6STA STRACC+1LDX #0JSR WRTSTRLDA #EOLSTA LINEBF,XJSR RECOUTLDA LABCNT;Store LABCNT/2STA LABNRLDA6} LABCNT+1STA LABNR+1LSR LABNR+1ROR LABNRLDA #0 ;Initialize label nrSTA LABELSTA LABEL+1:LP1INC LABEL;Pick a6} labelBNE :NOCARINC LABEL+1:NOCARSEC ;Out of labels?LDA LABNRSBC LABELLDA LABNR+1SBC LABEL+1BCC :WRAP;Y6}es, get outCLC ;No, check this oneLDA #LOW LABBASADC LABELSTA LABACCLDA #HIGH LABBASADC LABEL+1STA LABACC+16}LDA LABACCADC LABELSTA LABACCLDA LABACC+1ADC LABEL+1STA LABACC+1LDY #1 ;Zero-page label?LDA (LABACC),YBNE6} :LP1;No, try anotherLDX #0 ;Yes, format itSTA ADRBUF+1;"Z/L" logic keys on thisJSR WRTLABLDA #' ':LP4STA LINE6}BF,XINXCPX #7BCC :LP4LDA #'='STA LINEBF,XINXLDA #' 'STA LINEBF,XINXLDA #'$'STA LINEBF,XINXLDY #0L6}DA (LABACC),YJSR WRTHEXLDA #EOLSTA LINEBF,XJSR RECOUT;Output equateJMP :LP1;and do it again:WRAPLDA #LOW STR7;6}Output closing msgSTA STRACCLDA #HIGH STR7STA STRACC+1LDX #0JSR WRTSTRLDA #EOLSTA LINEBF,XJSR RECOUTRTSEP6}ROC'ZERO-PAGE EQUATES'SUBTTL 'File ZPEQU.AMA';; This module outputs equate statements; for all referenced zero-page 4TITLE 'CUSTOMIZING MODULE'SUBTTL 'File CUSTOM.AMA';; This module reads a DISKDIS customizing file; if one is present on:} Drive 1, and sets the; various customizing options to adapt DISKDIS; to the user's assembler.;PROC;; Open file if pre:}sent;CUSTOMLDX #$30;IOCB3LDA #OPENSTA ICCOM,XLDA #LOW CUSFILSTA ICBAL,XLDA #HIGH CUSFILSTA ICBAH,XLDA #OPNI:}NSTA ICAX1,XJSR CIOVBPL :OK0JMP :EXIT:OK0LDA #GETREC ;File link pseudoSTA ICCOM,XLDA #LOW LINKBFSTA ICBAL,X:}LDA #HIGH LINKBFSTA ICBAH,XLDA #37STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVBPL :OK2JMP :EXIT:OK2LDA #LOW ORGOP :};Origin pseudoSTA ICBAL,XLDA #HIGH ORGOPSTA ICBAH,XLDA #21STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVBPL :OK4JMP:} :EXIT:OK4LDA #LOW ENDOPSTA ICBAL,XLDA #HIGH ENDOPSTA ICBAH,XLDA #20STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVB:}PL :OK6JMP :EXIT:OK6LDA #LOW [STR3+1];Define byte pseudoSTA ICBAL,XLDA #HIGH [STR3+1]STA ICBAH,XLDA #9STA ICBL:}L,XLDA #0STA ICBLH,XJSR CIOVBMI :EXITLDA #0 ;Spare recordSTA ICBAL,XLDA #$FFSTA ICBAH,XLDA #$80STA ICB:}LL,XLDA #0STA ICBLH,XJSR CIOVBMI :EXITLDA # LOW MISCBF;Misc. flagsSTA ICBAL,XLDA #HIGH MISCBFSTA ICBAH,XLD:}A #10STA ICBLL,XLDA #0STA ICBLH,XJSR CIOVBMI :EXITLDA MISCBFSTA COMENTLDA MISCBF+1STA LNFLAGLDA MISCBF+2:}STA MAXSZLDA MISCBF+3STA MAXSZ+1LDA MISCBF+4STA MAXFIL:EXITLDA #CLOSE;Close file & get outSTA ICCOM,XJSR CIOV:}LDA LNFLAG;Want line numbers?BNE :NUMON;YesLDA #LOW LINEBF;NoSTA OUTPTRLDA #HIGH LINEBFSTA OUTPTR+1RTS:NUMON:}LDA #LOW NUMBUFSTA OUTPTRLDA #HIGH NUMBUFSTA OUTPTR+1RTSMISCBFDB $31,$00;Comments on, line nrs offDW $4000;Byt:}es/fileDB $05,$00;Files/disk+1,spareCUSFILDB 'D1:DISKDIS.CUS'EPROCSKDIS customizing file; if one is present on8PTITLE 'VBI MODULE'SUBTTL 'File VBLANK.AMA';; This module creates & invokes a deferred; vertical blank interrupt routine>} to monitor the; console switch status and set flags for screen; display and printer output when selected; by the operator>}.;PROCVBLANKLDA #7 ; Select deferred VBILDY #LOW DVBILDX #HIGH DVBIJSR SETVBVRTS;; This is the deferred V>}BI routine;DVBILDA CONSOLAND #$07EOR #$07BNE :DVB2;Switch pressedLDA DBTIM;Debounce timerBEQ :EXITDEC DBTIM>}JMP :EXIT:DVB2STA CONSAVLDA DBTIMBNE :EXITLDA #5STA DBTIMLDA CONSAVAND #4BEQ :DVB4LDA PROPT ;OPTION sele>}cts printerEOR #$FFSTA PROPT:DVB4LDA CONSAVAND #1BEQ :EXITLDA FREEZE ;START freezes displayEOR #$FFSTA FREE>}ZE:EXITJMP XITVBVEPROCFile VBLANK.AMA';; This module creates & invokes a deferred; vertical blank interrupt routine<