10
20 ver$="1.17"
30
40
50
60 :
70 OSRDCH=&FFE0:OSNEWL=&FFE7:OSWRCH=&FFEE:OSWORD=&FFF1
80 OSARGS=&FFDA:OSFIND=&FFCE:OSBGET=&FFD7:OSWRCR=&FFEC
90 OSASCI=&FFE3:BRKV=&0202:WORDV=&020C
100 :
110 blk=&A8:lptr=&AA:arg=&AC
120 PRPAD=&80:PRTEMP=&81:LineNumber=&82:len=&85
130 Handle=&86:HandleFirst=&87:InsideAssem=&88
140 ErrFlag=&89:FileType=&8A
150 :
160 DIM mcode% &300:load%=&FFFF08C0
170 :
180 FORP=0TO1
190 O%=mcode%:P%=load%
200 [OPT P*3+4
210 .FileNotFound
220 BRK:EQUB 214:EQUS "File not found":BRK
230 :
240 .go%
250 LDY #&00:STY ErrFlag:STY InsideAssem :\ Clear flags
260 LDA #&01:LDX #lptr:JSR OSARGS
270 LDX lptr+0:LDY lptr+1:LDA #&40:JSR OSFIND
280 TAY:BEQ FileNotFound
290 STY Handle:STY HandleFirst:JSR CheckFileType :\ Check if Basic or Text
300 JSR SwapVectors :\ Set up the vectors
310 :
320 .PrintPass :\ Print the current pass
330 LDX #MsgPass-MsgBase
340 .PrMessage
350 LDA MsgBase,X:BEQ PrMsgDone
360 JSR OSASCI:INX:BNE PrMessage
370 :
380 .NewWORD
390 CMP #&00:BEQ Word0:JMP (OldWORDV)
400 .Word0
410 STA len :\ Clear line length
420 STX blk+0:STY blk+1 :\ Point to block
430 TAY:LDA (blk),Y:STA lptr+0
440 INY:LDA (blk),Y:STA lptr+1 :\ Get pointer to input buffer
450 LDA ErrFlag:BEQ WasNoError :\ Re-entering after an error?
460 LDX #MsgIgnore-MsgBase:JSR PrMessage
470 LDA &0256:PHA:LDA &0268:PHA :\ Save Exec and FKey handles
480 LDA #0:STA &0256:STA &0268:STA ErrFlag :\ Clear Exec and FKey handles
490 JSR OSRDCH:AND #&DF:PHA:JSR OSNEWL :\ Get a key-press
500 PLA:CMP #ASC"N":BNE IgnoreError :\ If not 'N', ignore error
510 PLA:PLA:BEQ NoExecFileOpen
520 TAY:JSR CloseY :\ Close the EXEC file
530 .NoExecFileOpen
540 JMP EndOfAssem
550 :
560 .PrMsgDone
570 .EscapePressed
580 SEC:RTS
590 :
600 .IgnoreError
610 PLA:STA &0268:PLA:STA &0256 :\ Restore Exec and FKey handles
620 .WasNoError
630 LDA PassChar:CMP #ASC"5":BCS ReadLineHeader
640 .PrintAddr
650 LDA &0440,Y:JSR PrHex:DEY:BPL PrintAddr :\ Print P%
660 .ReadLineHeader
670 INC LineNumber:BNE P%+4:INC LineNumber+1 :\ Inc line number for text file
680 JSR OSWRCR:LDY Handle :\ Print a CR
690 BIT FileType:BMI SkipLineSpaces :\ Text file, no line numbers
700 LDX #2
710 .ReadLineLp
720 JSR OSBGET:BCS EndReached :\ Get line number
730 STA LineNumber-1,X:DEX:BPL ReadLineLp :\ and skip line length
740 LDX LineNumber+1:INX:BEQ EndReached
750 .SkipLineSpaces
760 JSR OSBGET:BCS EndReached
770 CMP #ASC" ":BEQ SkipLineSpaces
780 LDY #&00:LDX #&FF
790 CMP #ASC"[":BEQ StartLine :\ X=&FF, start assembler code
800 BIT InsideAssem:BPL ReadLine :\ Outside assembler
810 PHA
820 .InsertOPT
830 LDA MsgOPT,Y:STA (lptr),Y:INY
840 CMP #ASC":":BNE InsertOPT :\ Put OPT at start of line
850 PLA:CMP #ASC"]":BNE ReadLine :\ End of assembler?
860 INX :\ X=&00, end assembler code
870 .StartLine
880 STX InsideAssem
890 .ReadLine
900 STA (lptr),Y:INY:STY len
910 CMP #&0D:BEQ EndOfLine
920 CMP #&0A:BEQ EndOfLine
930 BIT &FF:BMI EscapePressed
940 LDY Handle:JSR OSBGET:BCS EndReached
950 LDY len:BNE ReadLine
960 .EndOfLine
970 LDY #&00:LDA (lptr),Y
980 CMP #ASC">":BEQ NextFile
990 LDY len:CLC:RTS
1000 :
1010 .EndReached
1020 LDA PassChar:CMP #ASC"5":BCS EndOfAssem :\ Very end reached in pass 2
1030 INC MsgPass+5:LDA #ASC"7":STA PassChar :\ Set the number for pass 2
1040 JSR PrintPass:JSR CloseIfNotFirst
1050 LDY HandleFirst:STY Handle:JSR RewindFile
1060 .StartAFile
1070 JSR CheckFileType:JMP ReadLineHeader
1080 :
1090 .CheckFileType
1100 LDA #0:STA FileType:STA LineNumber:STA LineNumber+1
1110 JSR OSBGET:CMP #13:BEQ SwapVectorsEnd :\ Look at first byte
1120 DEC FileType :\ Flag as Text, and rewind
1130 :
1140 .RewindFile
1150 LDX #3:LDA #0
1160 .Rewind
1170 STA arg,X:DEX:BPL Rewind
1180 LDX #arg:LDA #&01:JMP OSARGS :\ Rewind to start of file
1190 :
1200 .NextFile
1210 JSR CloseIfNotFirst
1220 LDX lptr+0:LDY lptr+1
1230 INX:BNE P%+3:INY :\ Point to filename in buffer
1240 LDA #&40:JSR OSFIND:STA Handle
1250 TAY:BNE StartAFile :\ If not present, will fall thru
1260 :
1270 .CloseIfNotFirst
1280 LDY Handle:CPY HandleFirst:BEQ SwapVectorsEnd
1290 :
1300 .CloseY
1310 LDA #&00:JMP OSFIND
1320 :
1330 .EndOfAssem
1340 JSR CloseIfNotFirst:LDY HandleFirst:JSR CloseY
1350 LDY #0:LDA #&0D:STA (lptr),Y :\ Length=0, CR in position
1360 .SwapVectors
1370 PHP:SEI:LDY #2
1380 .SwapVecLp
1390 LDA BRKV-1,Y:LDX OldBRKV-1,Y:STA OldBRKV-1,Y:TXA:STA BRKV-1,Y
1400 LDA WORDV-1,Y:LDX OldWORDV-1,Y:STA OldWORDV-1,Y:TXA:STA WORDV-1,Y
1410 DEY:BNE SwapVecLp :\ End with Y=0
1420 PLP:CLC
1430 .SwapVectorsEnd
1440 RTS
1450 :
1460 .OldBRKV :EQUW NewBRK
1470 .OldWORDV:EQUW NewWORD
1480 :
1490 .PrHex
1500 PHA:LSR A:LSR A:LSR A:LSR A:JSR PrNyb:PLA:AND #&0F
1510 .PrNyb
1520 SED:CLC:ADC #&90:ADC #&40:CLD:JMP OSWRCH
1530 :
1540 .NewBRK
1550 LDY #&00:LDA (&FD),Y
1560 CMP #&20:BEQ ErrorExit
1570 CMP #&DE:BNE NotChannelError
1580 JSR SwapVectors :\ *BUG* after this, jmp (oldbrkv) will come back here
1590 .NotChannelError
1600 LDX #MsgError-MsgBase:STX ErrFlag :\ Flag for next entry to Osw0
1610 JSR PrMessage:JSR PRDEC16 :\ Print error line number
1620 LDA #ASC":":JSR OSWRCH
1630 .ErrorExit
1640 JMP (OldBRKV)
1650 :
1660 .PRDEC16
1670 LDA #255:PHA \ Terminator
1680 .PRDECDIGIT
1690 LDX #15 \ 16-bit divide
1700 LDA #0 \ Remainder=0
1710 CLV \ V=0 means divide result = 0
1720 .PRDECDIV10
1730 CMP #10/2:BCC PRDEC10 \ Calculate OSNUM/10
1740 SBC #10/2+&80 \ Remove digit & set V=1 to show div result > 0
1750 SEC \ Shift 1 into div result
1760 .PRDEC10
1770 ROL LineNumber+0 \ Shift /10 result
1780 ROL LineNumber+1
1790 ROL A \ Shift bits of input into acc (input mod 10)
1800 DEX:BNE PRDECDIV10 \ Continue 16-bit divide
1810 PHA:BVS PRDECDIGIT \ If V=1, result of /10 was >0, do next digit
1820 PLA
1830 .PRDECLP2
1840 ORA #ASC"0":JSR OSWRCH \ Pop character left to right and print it
1850 PLA:BPL PRDECLP2:RTS
1870 :
1880 .MsgBase
1890 .MsgIgnore
1900 EQUS CHR$7+"Ignore? (Y/N)":BRK
1910 .MsgOPT
1920 EQUS "[OPT":.PassChar:EQUS "4:"
1930 .MsgPass
1940 EQUS "Pass 1":EQUB 13:BRK
1950 .MsgError
1960 EQUS "Error at line ":BRK
1970 :
1980 EQUS ver$
1990 \ =&AF9
2000 ]:NEXT
2010 PRINT"*Save Assem ";~mcode%;" ";~O%;" ";~go%OR&FFFF0000;" ";~load%