10REM NewTerm <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 20Comm$ = "UNIX" 30Reverse$="XINU" 40Vers$ = "0.02" 50PutV = &22A 60GetV = &22C 70 80Oput = &80 90Oget = &82 100 110putptr = &84 120getptr = &86 130 140Top = &88 150Bot = &8A 160 170S_sent = &8C 180 190Buffer_count_lo = &8D:Buffer_count_hi = &8E 200XOFFtrigger_lo = &09:XOFFtrigger_hi = &00 210XONtrigger_lo = &03:XONtrigger_hi=&00 220Q_needed=&8F 230 240true=0 250false=&FF 260 270 oswrch = &FFEE 280 osbyte = &FFF4 290 300 TEMP = &0070 310 TEMP1 = &0071 320 NewTemp = &72 330 NewTemp1 = &73 :REM *LOAD ECFG 340 350 B% = &8000 360 370 C% = &C000 380 390FOR Pass = 4 TO 6 STEP 2 400 P%=B% 410 O%=C% 420[ OPT Pass 430 440 450.startROM 460JMP Second_processor 470JMP SERVJP 480EQUB &C2 490EQUB copyright-startROM 500EQUB &00 510EQUS "UNIX Terminal Emulator V"+Vers$ 520EQUB &00 530EQUS Vers$ 540.copyright 550EQUB &00 560EQUS "(C) 1983 Acorn" 570EQUB &00 580\ 590 600\ BRK handler - should only be called on Language side. 610 620EQUS "<<< Start of BRK handler >>>" 630.Brkhand 640 Ldy #0 650.ErrLoop 660 Iny 670 Lda (&FD),Y 680 Beq ErrEnd 690 Jsr oswrch 700Jmp ErrLoop 710 720.ErrEnd 740JMP Second_processor 750 770 780 790 800 810.InitFX 820 OPT FNosbyte(&E5,1,0) \ Treat ESC as ascii 830 OPT FNosbyte(2,2,0) \ Enable RS 232 reception 831 OPT FNosbyte(3,0,0) \ Output to VDU by default 840 OPT FNosbyte(181,1,0) \ Receive 8-bits, no softkeys on RS232 850 OPT FNosbyte(15,0,0) \ Flush all buffers 860 OPT FNosbyte(12,3,0) \ Auto-repeat rate 870 OPT FNosbyte(144,0,1) \ Interlace off 880 OPT FNosbyte(7,7,0) \ Receive 9600 890 OPT FNosbyte(8,7,0) \ Transmit 9600 900 OPT FNosbyte(20,6,0) \ Explode char set 910 OPT FNosbyte(6,0,0) \ Printer ignore char = 0 920 OPT FNosbyte(202,127,128) \ No caps lock, no shift lock 930 OPT FNosbyte(&76,0,0) \ Echo status in LEDs 940 OPT FNosbyte(153,0,13) \ type ahead a 950 Rts 960 970 980EQUS "<<< Start of Emulator code >>>" 990.Second_processor 1000LDX #&FF :TXS 1010Lda #Brkhand MOD 256: Sta &202 1020Lda #Brkhand DIV 256: Sta &203 1030Cli 1040JSR InitECFG 1050JSR InitFX 1060Jsr init_filter 1070Jsr initBF 1080Lda #true: Sta Q_needed 1090.Emulator 1100 OPT FNosbyte(&91,1,0) \ Get char from RS232 input buffer 1110 1120 BCS RS232_empty 1130 1140 TYA 1150 JSR oswrch 1160 1170.RS232_empty \ Also poll keyboard even if input was present, 1180 \ in order to give higher priority 1190 1200 OPT FNosbyte(&81,0,0) \ Get char from keyboard with soft-key expansion 1210 Txa:Tay 1220 1230 \ Y contains char!!! 1240 BCC Typed_something \C=1 => Buffer empty 1250 1260 Lda Q_needed 1270 Cmp #false 1280 Beq Emulator 1290 1300 Ldy #ASC("Q") AND 31 \ Fake a ^Q typed at keyboard 1310 Lda #false:Sta S_sent:Sta Q_needed 1320 1330.Typed_something 1340 \ Y contains char!!! 1350 TYA 1360 1370 PHA 1380 \ char ON STACK <<<<<<<< 1390 OPT FNosbyte(3,16+3,0) \ Select printer & RS232 output 1400 \ NO SPOOLing when writing to RS232 1410 PLA 1420 \ char OFF STACK <<<<<<< 1430 Jsr oswrch 1440 1450 OPT FNosbyte(3,0,0) \ RE-select VDU output 1460Jmp Emulator 1580 1603\ 1610EQUS "<<< Start of s/w ROM decoding >>>" 1620.SERVJP CMP #&04 \Offer command line 1630 BNE RET 1640 TYA \Save regs 1650 PHA 1660 TXA 1670 PHA 1680 LDX #LEN(Comm$) \Load counter 1690.CHKCOM LDA (&F2),Y \Pointer to command line 1700 CMP COMMAND-1,X 1710 BNE BADCOMM \Command not recognised 1720 INY 1730 DEX 1740 BNE CHKCOM 1750.DUMBGO \ JSR InitFX 1760 \ JSR initBF \ Order important - InitFX explodes char set, 1770 \ ... initBF reads OSHWM 1780 PLA 1790 TAX \Get rom no. in X 1800 LDA #&8E 1810 JSR osbyte \Jump to language 1820 1830.BADCOMM CMP #ASC"." \Check for abbreviation 1840 BEQ DUMBGO 1850 PLA 1860 TAX 1870 PLA 1880 TAY 1890 LDA #&04 \Pass command on 1900.RET RTS 1910 1920 1930 1940 1950 1960 1970.VSTRING PLA 1980 STA TEMP 1990 PLA 2000 STA TEMP+1 2010 LDY #&00 2020 BEQ VLOOP 2030.VGO JSR oswrch 2040.VLOOP INC TEMP 2050 BNE VGON 2060 INC TEMP+1 2070.VGON LDA (TEMP),Y 2080 BPL VGO 2090 JMP (TEMP) 2100.VDDONE RTS 2110 2120.COMMAND EQUS Reverse$ 2130 2140 2150 2160 2170 2180.initBF 2190 OPT FNosbyte(&85,0,0) \ Bottom of screen RAM for mode 0 2199Ldx #&FF 2200 STX Top 2209Ldy #&2D 2210 STY Top+1 2212 Lda &FFB7: Sta TEMP 2213 Lda &FFB8: Sta TEMP+1 2220 LDA PutV : Ldy #&2A: Lda (TEMP),Y 2230 STA Oput 2240 LDA PutV+1 : Iny: Lda (TEMP),Y 2250 STA Oput+1 2260 LDA GetV : Ldy #&2C: Lda (TEMP),Y 2270 STA Oget 2280 LDA GetV+1 : Iny: Lda (TEMP),Y 2290 STA Oget+1 2300 LDA #Myget AND &FF 2310 STA GetV 2320 LDA #Myput AND &FF 2330 STA PutV 2340 LDA #Myget DIV 256 2350 STA GetV+1 2360 LDA #Myput DIV 256 2370 STA PutV+1 2380 OPT FNosbyte(&83,0,0) \ Get OSHWM 2390 STY Bot+1 2400 STX Bot 2410LDA Bot 2420STA putptr 2430STA getptr 2440LDA Bot+1 2450STA putptr+1 2460STA getptr+1 2470 Lda #false \ Flow-control via X-ON/X-OFF - No ^S sent yet. 2480 Sta S_sent 2490 Lda #0 2500 Sta Buffer_count_lo \ and nothing in the buffer as far as XON/XOFF is 2510 Sta Buffer_count_hi \ concerned 2520 RTS 2530 2540 2550 2560 2570 2580 2590\########################################################################## 2600\## ## 2610\## PUT character into RS423 input buffer ## 2620\## ## 2630\########################################################################## 2640EQUS "<<< Start of buffer routines >>>" 2650.Recover_softkeys 2660 Sec 2670 Sbc #&10:Jmp Hisput 2680.CheckKey 2690 Cpx #0 2700 Bne Hisput 2710 Cmp #&90: Bcc lookup 2720 Cmp #&A0: Bcc Recover_softkeys 2730.lookup Tay 2740 Lda keytab,Y 2750 Bpl Hisput 2760 Pha 2770 Lda #27 2780 Jsr Hisput 2790 Pla 2800 And #127 2810.Hisput JMP (Oput) 2820.Myput 2830 Cpx #1 \ Check that it is a RS423 buffer operation 2840 Bne CheckKey \ If not, then use original buffer handler 2850 Jsr put_in_RS423 \ *** Link-level filtering, 8-bit conversion etc. 2860 \ *** May jump off here never to return... 2870 Ldy #0 2880 Php \ Mask interrupts 2890 Sei 2900 Sta (putptr),Y \ Place character in buffer at 'putptr' 2910 Inc putptr 2920 Bne nocar1 2930 Inc putptr+1 2940.nocar1 \ and increment 'putptr' 2950 Lda putptr 2960 Cmp Top 2970 Bne done2 2980 Lda putptr+1 2990 Cmp Top+1 3000 Bne done2 \ If 'putptr' is at the end of the buffer, 3010 \ wrap it round to the start again 3020 Lda Bot 3030 Sta putptr 3040 Lda Bot+1 3050 Sta putptr+1 3060.done2 3070 Lda putptr 3080 Cmp getptr 3090 Bne done1 3100 Lda putptr+1 3110 Cmp getptr+1 3120 Bne done1 \ If putptr' has caught up with 'getptr', 3130 \ i.e. the buffer is full, then... 3140 Lda putptr 3150 Bne zz1 3160 Dec putptr+1 3170.zz1 3180 Dec putptr \ undo the put operation, 3190 Plp \ disable interrupts, 3200 Sec \ and return 'buffer full' code in carry 3210 Rts 3220.done1 \ Otherwise 3230 Inc Buffer_count_lo \ Increment count of bytes in buffer 3240 Bne qaz1 3250 Inc Buffer_count_hi 3260 .qaz1 3270 Lda Buffer_count_lo 3280 Cmp #XOFFtrigger_lo \ Test trigger value to see if ^S needed 3290 Bne Plenty_room_left 3300 \ in order not to overflow the buffer... 3310 Lda Buffer_count_hi 3320 Cmp #XOFFtrigger_hi 3330 Bne Plenty_room_left 3340 Lda S_sent 3350 Cmp #true 3360 Beq Plenty_room_left \ Oscillating around XOFF trigger, but 3370 \ should stop soon as value is going down... 3380 OPT FNosbyte (3,16+3,0) \ (No spooling) 3390 Lda #ASC("S") AND 31 \ Send XOFF if so. 3400 Jsr oswrch 3410 OPT FNosbyte (3,0,0) 3420 Lda #true \ And note the fact so that 'get from buffer' 3430 \ can send the XON when there is room. 3440 Sta S_sent \ (Note that S_sent is a flag, not a semaphore, 3450 \ as this machine does not have processes) 3460.Plenty_room_left 3470 Plp \ Restore interrupts, 3480 Clc \ and return 'buffer not full' code in carry 3490 Rts 3500 3510 3520 3530 3540 3550 3560 3570\########################################################################## 3580\## ## 3590\## GET character from RS423 input buffer ## 3600\## ## 3610\########################################################################## 3620.Hisget JMP (Oget) 3630.Myget CPX #1 3640 Bne Hisget \ Check for RS324 'get from buffer' operation 3650 Php \ Mask interrupts 3660 Sei 3670 Lda getptr 3680 Cmp putptr 3690 Bne L27 3700 Lda getptr+1 3710 Cmp putptr+1 3720 Bne L27 \ If nothing in buffer ('getptr' = 'putptr') 3730 Plp \ then restore interrupts 3740 Sec \ and return 'buffer empty' code in carry 3750 Rts 3760.L27 3770 Ldy #0 3780 Lda (getptr),Y \ else fetch the byte 3790 Tay 3800 Inc getptr 3810 Bne L30 3820 Inc getptr+1 3830.L30 \ and increment the 'get' pointer 3840 Lda getptr 3850 Cmp Top 3860 Bne done10 3870 Lda getptr+1 3880 Cmp Top+1 3890 Bne done10 \ If the 'get' pointer is at the limit 3900 \ of the cyclic buffer, then 3910 Lda Bot 3920 Sta getptr 3930 Lda Bot+1 3940 Sta getptr+1 \ reset it to the other end. 3950.done10 3960 Lda Buffer_count_lo 3970 Bne qaz2 3980 Dec Buffer_count_hi 3990.qaz2 4000 Dec Buffer_count_lo 4010 Lda S_sent 4020 Cmp #true \ Are we holding off input? 4030 Bne No_check_needed 4040 Lda Buffer_count_lo 4050 Cmp #XONtrigger_lo \ Is there enough room yet? 4060 Bne No_check_needed 4070 Lda Buffer_count_hi 4080 Cmp #XONtrigger_hi 4090 Bne No_check_needed 4100\******* Set flag to send ^Q from top level. 4110\******* Top level will set S_sent to false... 4120Lda #true:Sta Q_needed 4130.No_check_needed 4140 Plp \ Restore interrupts 4150 Clc \ Return 'character fetched OK' code in carry 4160 Rts 4170EQUS "<<< Start of keyboard table >>>" 4180.keytab 4190 EQUB &0 \ 0 4200 EQUB &1 \ 1 4210 EQUB &2 \ 2 4220 EQUB &3 \ 3 4230 EQUB &4 \ 4 4240 EQUB &5 \ 5 4250 EQUB &6 \ 6 4260 EQUB &7 \ 7 4270 EQUB &8 \ 8 4280 EQUB &9 \ 9 4290 EQUB &A \ A 4300 EQUB &B \ B 4310 EQUB &C \ C 4320 EQUB &D \ D 4330 EQUB &E \ E 4340 EQUB &F \ F 4350 EQUB &10 \ 10 4360 EQUB &11 \ 11 4370 EQUB &12 \ 12 4380 EQUB &13 \ 13 4390 EQUB &14 \ 14 4400 EQUB &15 \ 15 4410 EQUB &16 \ 16 4420 EQUB &17 \ 17 4430 EQUB &18 \ 18 4440 EQUB &19 \ 19 4450 EQUB &1A \ 1A 4460 EQUB &1B \ 1B 4470 EQUB &1C \ 1C 4480 EQUB &1D \ 1D 4490 EQUB &1E \ 1E 4500 EQUB &1F \ 1F 4510 EQUB &20 \ 20 4520 EQUB &21 \ 21 4530 EQUB &22 \ 22 4540 EQUB &23 \ 23 4550 EQUB &24 \ 24 4560 EQUB &25 \ 25 4570 EQUB &26 \ 26 4580 EQUB &27 \ 27 4590 EQUB &28 \ 28 4600 EQUB &29 \ 29 4610 EQUB &2A \ 2A 4620 EQUB &2B \ 2B 4630 EQUB &2C \ 2C 4640 EQUB &2D \ 2D 4650 EQUB &2E \ 2E 4660 EQUB &2F \ 2F 4670 EQUB &30 \ 30 4680 EQUB &31 \ 31 4690 EQUB &32 \ 32 4700 EQUB &33 \ 33 4710 EQUB &34 \ 34 4720 EQUB &35 \ 35 4730 EQUB &36 \ 36 4740 EQUB &37 \ 37 4750 EQUB &38 \ 38 4760 EQUB &39 \ 39 4770 EQUB &3A \ 3A 4780 EQUB &3B \ 3B 4790 EQUB &3C \ 3C 4800 EQUB &3D \ 3D 4810 EQUB &3E \ 3E 4820 EQUB &3F \ 3F 4830 EQUB &40 \ 40 4840 EQUB &41 \ 41 4850 EQUB &42 \ 42 4860 EQUB &43 \ 43 4870 EQUB &44 \ 44 4880 EQUB &45 \ 45 4890 EQUB &46 \ 46 4900 EQUB &47 \ 47 4910 EQUB &48 \ 48 4920 EQUB &49 \ 49 4930 EQUB &4A \ 4A 4940 EQUB &4B \ 4B 4950 EQUB &4C \ 4C 4960 EQUB &4D \ 4D 4970 EQUB &4E \ 4E 4980 EQUB &4F \ 4F 4990 EQUB &50 \ 50 5000 EQUB &51 \ 51 5010 EQUB &52 \ 52 5020 EQUB &53 \ 53 5030 EQUB &54 \ 54 5040 EQUB &55 \ 55 5050 EQUB &56 \ 56 5060 EQUB &57 \ 57 5070 EQUB &58 \ 58 5080 EQUB &59 \ 59 5090 EQUB &5A \ 5A 5100 EQUB &5B \ 5B 5110 EQUB &5C \ 5C 5120 EQUB &5D \ 5D 5130 EQUB &5E \ 5E 5140 EQUB &5F \ 5F 5150 EQUB &60 \ 60 5160 EQUB &61 \ 61 5170 EQUB &62 \ 62 5180 EQUB &63 \ 63 5190 EQUB &64 \ 64 5200 EQUB &65 \ 65 5210 EQUB &66 \ 66 5220 EQUB &67 \ 67 5230 EQUB &68 \ 68 5240 EQUB &69 \ 69 5250 EQUB &6A \ 6A 5260 EQUB &6B \ 6B 5270 EQUB &6C \ 6C 5280 EQUB &6D \ 6D 5290 EQUB &6E \ 6E 5300 EQUB &6F \ 6F 5310 EQUB &70 \ 70 5320 EQUB &71 \ 71 5330 EQUB &72 \ 72 5340 EQUB &73 \ 73 5350 EQUB &74 \ 74 5360 EQUB &75 \ 75 5370 EQUB &76 \ 76 5380 EQUB &77 \ 77 5390 EQUB &78 \ 78 5400 EQUB &79 \ 79 5410 EQUB &7A \ 7A 5420 EQUB &7B \ 7B 5430 EQUB &7C \ 7C 5440 EQUB &7D \ 7D 5450 EQUB &7E \ 7E 5460 EQUB &7F \ 7F Delete 5470\ <<<<<<<<<<< Normal Fn keys >>>>>>>>>>>> 5480 EQUB ASC("<")+128 \ 80 F0 5490 EQUB ASC(">")+128 \ 81 F1 5500 EQUB ASC(",")+128 \ 82 F2 5510 EQUB ASC(".")+128 \ 83 F3 5520 EQUB ASC("4")+128 \ 84 F4 5530 EQUB ASC("5")+128 \ 85 F5 5540 EQUB ASC("O")+128 \ 86 F6 5550 EQUB ASC("7")+128 \ 87 F7 5560 EQUB ASC("8")+128 \ 88 F8 5570 EQUB ASC("J")+128 \ 89 F9 5580 EQUB &8A \ 8A 5590 EQUB ASC("]")+128 \ 8B Copy 5600 EQUB ASC("D")+128 \ 8C Left 5610 EQUB ASC("C")+128 \ 8D Right 5620 EQUB ASC("@")+128 \ 8E Down 5630 EQUB ASC("A")+128 \ 8F Up 5640\ <<<<<<<<<<<<< Shift Fn keys >>>>>>>>>>>>>>> 5650\ This section maps onto &80 - &8F (soft keys & cursor keys) 5660 EQUB &90 \ 90 5670 EQUB &91 \ 91 5680 EQUB &92 \ 92 5690 EQUB &93 \ 93 5700 EQUB &94 \ 94 5710 EQUB &95 \ 95 5720 EQUB &96 \ 96 5730 EQUB &97 \ 97 5740 EQUB &98 \ 98 5750 EQUB &99 \ 99 5760 EQUB &9A \ 9A 5770 EQUB &9B \ 9B Shift copy 5780 EQUB &9C \ 9C Shift left 5790 EQUB &9D \ 9D Shift right 5800 EQUB &9E \ 9E Shift down 5810 EQUB &9F \ 9F Shift up 5820\ <<<<<<<<<<< Control Fn keys >>>>>>>> 5830 EQUB &A0 \ A0 5840 EQUB &A1 \ A1 5850 EQUB &A2 \ A2 5860 EQUB &A3 \ A3 5870 EQUB &A4 \ A4 5880 EQUB &A5 \ A5 5890 EQUB &A6 \ A6 5900 EQUB &A7 \ A7 5910 EQUB &A8 \ A8 5920 EQUB &A9 \ A9 5930 EQUB &AA \ AA 5940 EQUB &8B \ AB Control copy 5950 EQUB &8C \ AC Control left 5960 EQUB &8D \ AD Control right 5970 EQUB &8E \ AE Control down 5980 EQUB &8F \ AF Control up 5990\ <<<<<<<<<<<<< Control+Shift Fn keys >>>>>>>>>> 6000 EQUB &B0 \ B0 6010 EQUB &B1 \ B1 6020 EQUB &B2 \ B2 6030 EQUB &B3 \ B3 6040 EQUB &B4 \ B4 6050 EQUB &B5 \ B5 6060 EQUB &B6 \ B6 6070 EQUB &B7 \ B7 6080 EQUB &B8 \ B8 6090 EQUB &B9 \ B9 6100 EQUB &BA \ BA 6110 EQUB &BB \ BB 6120 EQUB &BC \ BC 6130 EQUB &BD \ BD 6140 EQUB &BE \ BE 6150 EQUB &BF \ BF 6160 EQUB &C0 \ C0 6170 EQUB &C1 \ C1 6180 EQUB &C2 \ C2 6190 EQUB &C3 \ C3 6200 EQUB &C4 \ C4 6210 EQUB &C5 \ C5 6220 EQUB &C6 \ C6 6230 EQUB &C7 \ C7 6240 EQUB &C8 \ C8 6250 EQUB &C9 \ C9 6260 EQUB &CA \ CA 6270 EQUB &CB \ CB 6280 EQUB &CC \ CC 6290 EQUB &CD \ CD 6300 EQUB &CE \ CE 6310 EQUB &CF \ CF 6320 EQUB &D0 \ D0 6330 EQUB &D1 \ D1 6340 EQUB &D2 \ D2 6350 EQUB &D3 \ D3 6360 EQUB &D4 \ D4 6370 EQUB &D5 \ D5 6380 EQUB &D6 \ D6 6390 EQUB &D7 \ D7 6400 EQUB &D8 \ D8 6410 EQUB &D9 \ D9 6420 EQUB &DA \ DA 6430 EQUB &DB \ DB 6440 EQUB &DC \ DC 6450 EQUB &DD \ DD 6460 EQUB &DE \ DE 6470 EQUB &DF \ DF 6480 EQUB &E0 \ E0 6490 EQUB &E1 \ E1 6500 EQUB &E2 \ E2 6510 EQUB &E3 \ E3 6520 EQUB &E4 \ E4 6530 EQUB &E5 \ E5 6540 EQUB &E6 \ E6 6550 EQUB &E7 \ E7 6560 EQUB &E8 \ E8 6570 EQUB &E9 \ E9 6580 EQUB &EA \ EA 6590 EQUB &EB \ EB 6600 EQUB &EC \ EC 6610 EQUB &ED \ ED 6620 EQUB &EE \ EE 6630 EQUB &EF \ EF 6640 EQUB &F0 \ F0 6650 EQUB &F1 \ F1 6660 EQUB &F2 \ F2 6670 EQUB &F3 \ F3 6680 EQUB &F4 \ F4 6690 EQUB &F5 \ F5 6700 EQUB &F6 \ F6 6710 EQUB &F7 \ F7 6720 EQUB &F8 \ F8 6730 EQUB &F9 \ F9 6740 EQUB &FA \ FA 6750 EQUB &FB \ FB 6760 EQUB &FC \ FC 6770 EQUB &FD \ FD 6780 EQUB &FE \ FE 6790 EQUB &FF \ FF 6800] 6810GOSUB 6940 6820NEXT 6830OSCLI("LOAD Ec2E00 "+STR$~(ECFG-B%+C%)) 6840OSCLI("SAVE X.term "+STR$~(C%)+" "+STR$~(O%+1+&800)+" 8000 8000") 6845OSCLI("SAVE :0.R.UNIX "+STR$~(C%)+" "+STR$~(O%+1+&800)+" 8000 8000") 6850END 6860DEFFNosbyte(A,X,Y) 6870[OPT Pass 6880 Lda #A 6890 Ldx #X 6900 Ldy #Y 6910 Jsr osbyte 6920] 6930=Pass 6940locals=&7C0 :REM <<<<<<<<<<<<<<<<<<<<<<<<<<<< dodgy 6950esc=locals 6960mask=locals+1 6970char=locals+2 6980byte=locals+3 6990hex_only=locals+4 7000add_needed=locals+5 7010sub_needed=locals+6 7020hex_needed=locals+7 7030esc_seen=locals+8 7040new_esc_next=locals+9 7050XonXoff=locals+10 7060[OPT Pass 7070EQUS "<<< Start of link-level handling >>>" 7080.put_in_RS423 7090 \ Char is in A 7100 And mask 7110 Sta char 7120 Bit hex_only 7130 Bmi not_hex_only 7140 \ 7150 Cmp #ASC("0") 7160 Bcc test_control 7170 Cmp #ASC("0")+15+1 7180 Bcs test_control \ IF '0' <= A <= '0'+15 THEN ... 7190 Lda hex_needed 7200 Cmp #1 7210 Beq last_nibble 7220 Cmp #2 7230 Beq first_nibble 7240 EQUB 0:EQUB 1:EQUS "hex_needed wrong value":EQUB 0 7250 .first_nibble 7260 Lda char 7270 Sec: Sbc #ASC("0") 7280 Asl A: Asl A: Asl A: Asl A 7290 Sta byte 7300 Lda #1 7310 Sta hex_needed 7320 Jmp ignore 7330 .last_nibble 7340 Lda char 7350 Sec: Sbc #ASC("0") 7360 Ora byte 7370 Sta char 7380 Lda #2 7390 Sta hex_needed 7400 .end_case_1 7410 Jmp over_tests 7420 .test_control 7430 Lda char 7440 Cmp #ASC(" ") 7450 Bcs invalid_hex 7460 Jmp ignore 7470 .invalid_hex 7480 Lda #false 7490 Sta hex_only 7500 .over_tests 7510 .not_hex_only 7520 Lda char 7530 Cmp esc 7540 Bne test_esc_seen 7550 Bit esc_seen 7560 Bmi got_esc 7570 Lda #false 7580 Sta esc_seen 7590 Jmp end_if_esc_seen 7600 .got_esc 7610 Lda #true 7620 Sta esc_seen 7630 Jmp ignore 7640 .end_if_esc_seen 7650 Jmp no_esc_3\over_esc_handler 7660 .test_esc_seen 7670 Bit esc_seen 7680 Bmi no_esc_3 7690 Jmp handle_esc 7700 .no_esc_3 7710 .test_hex_pair 7720 Lda hex_needed 7730 Cmp #2 7740 Bne next_hex_test 7750 Lda char 7760 Sec: Sbc #ASC("0") 7770 Asl A: Asl A: Asl A: Asl A 7780 Sta byte 7790 Lda #1 7800 Sta hex_needed 7810 Jmp ignore 7820 .next_hex_test 7830 Cmp #1 7840 Beq got_last_digit 7850 Cmp #0 7860 Beq no_hex_fiddles 7870 EQUB 0:EQUB 2:EQUS "hex_needed value wrong":EQUB 0 7880 .got_last_digit 7890 Lda char 7900 Sec: Sbc #ASC("0") 7910 Ora byte 7920 Sta char 7930 Lda #0 7940 Sta hex_needed 7950 .no_hex_fiddles 7960 Bit sub_needed 7970 Bmi test_add 7980 Lda char 7990 Sec: Sbc #64 8000 Sta char 8010 Lda #false 8020 Sta sub_needed 8030 .test_add 8040 Bit add_needed 8050 Bmi no_more_tests 8060 Lda char 8070 Eor #&80 8080 Sta char 8090 Lda #false 8100 Sta add_needed 8110 .no_more_tests 8120 .test_new_esc 8130 Bit new_esc_next 8140 Bmi not_new_esc 8150 Lda char 8160 Sta esc 8170 Lda #false 8180 Sta new_esc_next 8190 Jmp ignore 8200 .not_new_esc 8210 Jmp over_final_else 8220 .handle_esc 8230 Lda char 8240 Cmp #ASC("8") 8250 Bne test_7 8260 Lda #&FF: Sta mask 8270 Jmp end_case 8280 .test_7 8290 Cmp #ASC("7") 8300 Bne test_4 8310 Lda #&7F: Sta mask 8320 Jmp end_case 8330 .test_4 8340 Cmp #ASC("4") 8350 Bne test_minus 8360 Lda #true 8370 Sta hex_only 8380 Lda #2 8390 Sta hex_needed 8400 Jmp end_case 8410 .test_minus 8420 Cmp #ASC("-") 8430 Bne test_plus 8440 Lda #true 8450 Sta sub_needed 8460 Jmp end_case 8470 .test_plus 8480 Cmp #ASC("+") 8490 Bne test_and 8500 Lda #true 8510 Sta add_needed 8520 Jmp end_case 8530 .test_and 8540 Cmp #ASC("&") 8550 Bne test_pling 8560 Lda #2 8570 Sta hex_needed 8580 Jmp end_case 8590 .test_pling 8600 Cmp #ASC("!") 8610 Bne test_query 8620 Lda #true 8630 Sta XonXoff 8640 Jmp end_case 8650 .test_query 8660 Cmp #ASC("?") 8670 Bne test_equals 8680 Lda #false 8690 Sta XonXoff 8700 Jmp end_case 8710 .test_equals 8720 Cmp #ASC("=") 8730 Bne default 8740 Lda #true 8750 Sta new_esc_next 8760 Jmp end_case 8770 .default 8780 EQUB 0:EQUB 3:EQUS "Bad protocol after escape":EQUB 0 8790 .end_case 8800 Lda #false 8810 Sta esc_seen 8820 Jmp ignore 8830 .over_final_else 8840 .over_esc_handler 8850\ 8860\ Put char in buffer 8870 Lda char 8880 Rts 8890.ignore 8900 Pla:Pla:Rts 8910 8920 8930.init_filter 8940Lda #false: Sta add_needed 8950 Sta sub_needed 8960 Sta hex_only 8970 Sta esc_seen 8980 Sta new_esc_next 8990Lda #ASC("|") : Sta esc 9000Lda #0: Sta hex_needed 9010Lda #&7F: Sta mask 9020Rts 9040.InitECFG 9070 Lda #(ECFG MOD 256): Sta NewTemp 9080 Lda #(ECFG DIV 256): Sta NewTemp+1 9090 Lda #&00: Sta TEMP 9100 Lda #&2E: Sta TEMP+1 9150.CopyECFG 9160 Ldy #0 9170 Lda (NewTemp),Y 9180 Sta (TEMP),Y 9190 Inc TEMP 9200 Bne inc1 9210 Inc TEMP+1 9220.inc1 9230 Inc NewTemp 9240 Bne inc2 9250 Inc NewTemp+1 9260.inc2 9270 Lda TEMP+1 9280 Cmp #&30 9290 Bne CopyECFG 9292 Lda #&04: Sta &20E: Lda #&2E: Sta &20F 9301 Rts 9460.ECFG Nop 9470] 9480RETURN