10REM Term <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 20Comm$ = "UNIX" 30Reverse$="XINU" 40Vers$ = "0.01" 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 = &20:XOFFtrigger_hi = &0A 210XONtrigger_lo = &00:XONtrigger_hi=0 220Q_needed=&8F 230 240true=1 250false=0 260 270 oswrch = &FFEE 280 osbyte = &FFF4 290 300 TEMP = &0070 310 TEMP1 = &0071 320 330 B% = &8000 340 350 C% = &C000 360 370FOR Pass = 4 TO 6 STEP 2 380 P%=B% 390 O%=C% 400[ OPT Pass 410 420 430.startROM 440JMP Second_processor 450JMP SERVJP 460EQUB &C2 470EQUB copyright-startROM 480EQUB &00 490EQUS "UNIX Terminal Emulator" 500EQUB &00 510EQUS Vers$ 520.copyright 530EQUB &00 540EQUS "(C) 1983 Acorn" 550EQUB &00 560\ 570 580\ BRK handler - should only be called on Language side. 590 600.Brkhand 610 Ldy #0 620.ErrLoop 630 Iny 640 Lda (&FD),Y 650 Beq ErrEnd 660 Jsr oswrch 670Jmp ErrLoop 680 690.ErrEnd 700Lda #true 710Sta Q_needed \ Clean-up... Might need ^Q 720 730Jmp Emulator 740 750 760 770 780.InitFX 790 OPT FNosbyte(&E5,1,0) \ Treat ESC as ascii 800 OPT FNosbyte(2,2,0) \ Enable RS 232 reception 810 OPT FNosbyte(181,1,0) \ Receive 8-bits, no softkeys on RS232 820 OPT FNosbyte(15,0,0) \ Flush all buffers 830 OPT FNosbyte(12,3,0) \ Auto-repeat rate 840 OPT FNosbyte(144,0,1) \ Interlace off 850 OPT FNosbyte(7,7,0) \ Receive 9600 860 OPT FNosbyte(8,7,0) \ Transmit 9600 870 OPT FNosbyte(20,6,0) \ Explode char set 880 OPT FNosbyte(6,0,0) \ Printer ignore char = 0 890 OPT FNosbyte(202,127,128) \ No caps lock, no shift lock 900 OPT FNosbyte(&76,0,0) \ Echo status in LEDs 910 OPT FNosbyte(153,0,13) \ type ahead a 920 Rts 930 940 950.Second_processor 960Lda #Brkhand MOD 256: Sta &202 970Lda #Brkhand DIV 256: Sta &203 980Cli 990JSR InitFX 991Jsr initBF 992Lda #false: Sta Q_needed 1000.Emulator 1010 OPT FNosbyte(&91,1,0) \ Get char from RS232 input buffer 1020 1030 BCS RS232_empty 1040 1050 TYA 1060 AND #&7F 1070 JSR oswrch 1080 1090.RS232_empty \ Also poll keyboard even if input was present, 1100 \ in order to give higher priority 1110 1120 OPT FNosbyte(&81,0,0) \ Get char from keyboard with soft-key expansion 1130 Txa:Tay 1140 1150 \ Y contains char!!! 1160 BCC Typed_something \C=1 => Buffer empty 1170 1180 Lda Q_needed 1190 Cmp #false 1200 Beq Emulator 1210 1220 Ldy #ASC("Q") AND 31 \ Fake a ^Q typed at keyboard 1230 Lda #false:Sta S_sent:Sta Q_needed 1240 1250.Typed_something 1260 \ Y contains char!!! 1270 TYA 1280 1290 PHA 1300 \ char ON STACK <<<<<<<< 1310 OPT FNosbyte(3,16+3,0) \ Select printer & RS232 output 1320 \ NO SPOOLing when writing to RS232 1330 PLA 1340 \ char OFF STACK <<<<<<< 1350 Jsr oswrch 1360 1370 OPT FNosbyte(3,0,0) \ RE-select VDU output 1380Jmp Emulator 1390 1400 1410 1420 1430 1440 1450.SERVJP CMP #&04 \Offer command line 1460 BNE RET 1470 TYA \Save regs 1480 PHA 1490 TXA 1500 PHA 1510 LDX #LEN(Comm$) \Load counter 1520.CHKCOM LDA (&F2),Y \Pointer to command line 1530 CMP COMMAND-1,X 1540 BNE BADCOMM \Command not recognised 1550 INY 1560 DEX 1570 BNE CHKCOM 1580.DUMBGO \ JSR InitFX 1590 \ JSR initBF \ Order important - InitFX explodes char set, 1600 \ ... initBF reads OSHWM 1610 PLA 1620 TAX \Get rom no. in X 1630 LDA #&8E 1640 JSR osbyte \Jump to language 1650 1660.BADCOMM CMP #ASC"." \Check for abbreviation 1670 BEQ DUMBGO 1680 PLA 1690 TAX 1700 PLA 1710 TAY 1720 LDA #&04 \Pass command on 1730.RET RTS 1740 1750 1760 1770 1780 1790 1800.VSTRING PLA 1810 STA TEMP 1820 PLA 1830 STA TEMP+1 1840 LDY #&00 1850 BEQ VLOOP 1860.VGO JSR oswrch 1870.VLOOP INC TEMP 1880 BNE VGON 1890 INC TEMP+1 1900.VGON LDA (TEMP),Y 1910 BPL VGO 1920 JMP (TEMP) 1930.VDDONE RTS 1940 1950.COMMAND EQUS Reverse$ 1960 1970 1980 1990 2000 2010.initBF 2020 OPT FNosbyte(&85,0,0) \ Bottom of screen RAM for mode 0 2030 STX Top 2050 STY Top+1 2060 LDA PutV 2070 STA Oput 2080 LDA PutV+1 2090 STA Oput+1 2100 LDA GetV 2110 STA Oget 2120 LDA GetV+1 2130 STA Oget+1 2140 LDA #Myget AND &FF 2150 STA GetV 2160 LDA #Myput AND &FF 2170 STA PutV 2180 LDA #Myget DIV 256 2190 STA GetV+1 2200 LDA #Myput DIV 256 2210 STA PutV+1 2220 OPT FNosbyte(&83,0,0) \ Get OSHWM 2260 STY Bot+1 2270 STX Bot 2280LDA Bot 2290STA putptr 2300STA getptr 2310LDA Bot+1 2320STA putptr+1 2330STA getptr+1 2340 Lda #false \ Flow-control via X-ON/X-OFF - No ^S sent yet. 2350 Sta S_sent 2360 Lda #0 2370 Sta Buffer_count_lo \ and nothing in the buffer as far as XON/XOFF is 2380 Sta Buffer_count_hi \ concerned 2410 RTS 2420 2430 2440 2450 2460 2470 2480\########################################################################## 2490\## ## 2500\## PUT character into RS423 input buffer ## 2510\## ## 2520\########################################################################## 2530.Recover_softkeys 2540 Sec 2550 Sbc #&10:Jmp Hisput 2560.CheckKey 2570 Cpx #0 2580 Bne Hisput 2581 Cmp #&90: Bcc lookup 2590 Cmp #&A0: Bcc Recover_softkeys 2600.lookup Tay 2610 Lda keytab,Y 2620 Bpl Hisput 2630 Pha 2640 Lda #27 2650 Jsr Hisput 2660 Pla 2661 And #127 2670.Hisput JMP (Oput) 2680.Myput 2690 Cpx #1 \ Check that it is a RS423 buffer operation 2700 Bne CheckKey \ If not, then use original buffer handler 2710 Ldy #0 2720 Php \ Mask interrupts 2730 Sei 2740 Sta (putptr),Y \ Place character in buffer at 'putptr' 2750 Inc putptr 2760 Bne nocar1 2770 Inc putptr+1 2780.nocar1 \ and increment 'putptr' 2790 Lda putptr 2800 Cmp Top 2810 Bne done2 2820 Lda putptr+1 2830 Cmp Top+1 2840 Bne done2 \ If 'putptr' is at the end of the buffer, 2850 \ wrap it round to the start again 2860 Lda Bot 2870 Sta putptr 2880 Lda Bot+1 2890 Sta putptr+1 2900.done2 2910 Lda putptr 2920 Cmp getptr 2930 Bne done1 2940 Lda putptr+1 2950 Cmp getptr+1 2960 Bne done1 \ If putptr' has caught up with 'getptr', 2970 \ i.e. the buffer is full, then... 2980 Lda putptr 2990 Bne zz1 3000 Dec putptr+1 3010.zz1 3020 Dec putptr \ undo the put operation, 3030 Plp \ disable interrupts, 3040 Sec \ and return 'buffer full' code in carry 3050 Rts 3060.done1 \ Otherwise 3070 Inc Buffer_count_lo \ Increment count of bytes in buffer 3080 Bne qaz1 3090 Inc Buffer_count_hi 3100 .qaz1 3110 Lda Buffer_count_lo 3120 Cmp #XOFFtrigger_lo \ Test trigger value to see if ^S needed 3130 Bne Plenty_room_left 3140 \ in order not to overflow the buffer... 3150 Lda Buffer_count_hi 3160 Cmp #XOFFtrigger_hi 3170 Bne Plenty_room_left 3180 Lda S_sent 3190 Cmp #true 3200 Beq Plenty_room_left \ Oscillating around XOFF trigger, but 3210 \ should stop soon as value is going down... 3220 Lda #3: Ldx #3: Ldy #0: Jsr osbyte 3230 Lda #ASC("S") AND 31 \ Send XOFF if so. 3240 Jsr oswrch 3250 Lda #3: Ldx #0: Ldy #0: Jsr osbyte 3260 Lda #true \ And note the fact so that 'get from buffer' 3270 \ can send the XON when there is room. 3280 Sta S_sent \ (Note that S_sent is a flag, not a semaphore, 3290 \ as this machine does not have processes) 3300.Plenty_room_left 3310 Plp \ Restore interrupts, 3320 Clc \ and return 'buffer not full' code in carry 3330 Rts 3340 3350 3360 3370 3380 3390 3400 3410\########################################################################## 3420\## ## 3430\## GET character from RS423 input buffer ## 3440\## ## 3450\########################################################################## 3460.Hisget JMP (Oget) 3470.Myget CPX #1 3480 Bne Hisget \ Check for RS324 'get from buffer' operation 3490 Php \ Mask interrupts 3500 Sei 3510 Lda getptr 3520 Cmp putptr 3530 Bne L27 3540 Lda getptr+1 3550 Cmp putptr+1 3560 Bne L27 \ If nothing in buffer ('getptr' = 'putptr') 3570 Plp \ then restore interrupts 3580 Sec \ and return 'buffer empty' code in carry 3590 Rts 3600.L27 3610 Ldy #0 3620 Lda (getptr),Y \ else fetch the byte 3630 Tay 3640 Inc getptr 3650 Bne L30 3660 Inc getptr+1 3670.L30 \ and increment the 'get' pointer 3680 Lda getptr 3690 Cmp Top 3700 Bne done10 3710 Lda getptr+1 3720 Cmp Top+1 3730 Bne done10 \ If the 'get' pointer is at the limit 3740 \ of the cyclic buffer, then 3750 Lda Bot 3760 Sta getptr 3770 Lda Bot+1 3780 Sta getptr+1 \ reset it to the other end. 3790.done10 3800 Lda Buffer_count_lo 3810 Bne qaz2 3820 Dec Buffer_count_hi 3830.qaz2 3840 Dec Buffer_count_lo 3850 Lda S_sent 3860 Cmp #true \ Are we holding off input? 3870 Bne No_check_needed 3880 Lda Buffer_count_lo 3890 Cmp #XONtrigger_lo \ Is there enough room yet? 3900 Bne No_check_needed 3910 Lda Buffer_count_hi 3920 Cmp #XONtrigger_hi 3930 Bne No_check_needed 3940\******* Set flag to send ^Q from top level. 3950\******* Top level will set S_sent to false... 3960Lda #true:Sta Q_needed 3970.No_check_needed 3980 Plp \ Restore interrupts 3990 Clc \ Return 'character fetched OK' code in carry 4000 Rts 4010.keytab 4020 EQUB &0 \ 0 4030 EQUB &1 \ 1 4040 EQUB &2 \ 2 4050 EQUB &3 \ 3 4060 EQUB &4 \ 4 4070 EQUB &5 \ 5 4080 EQUB &6 \ 6 4090 EQUB &7 \ 7 4100 EQUB &8 \ 8 4110 EQUB &9 \ 9 4120 EQUB &A \ A 4130 EQUB &B \ B 4140 EQUB &C \ C 4150 EQUB &D \ D 4160 EQUB &E \ E 4170 EQUB &F \ F 4180 EQUB &10 \ 10 4190 EQUB &11 \ 11 4200 EQUB &12 \ 12 4210 EQUB &13 \ 13 4220 EQUB &14 \ 14 4230 EQUB &15 \ 15 4240 EQUB &16 \ 16 4250 EQUB &17 \ 17 4260 EQUB &18 \ 18 4270 EQUB &19 \ 19 4280 EQUB &1A \ 1A 4290 EQUB &1B \ 1B 4300 EQUB &1C \ 1C 4310 EQUB &1D \ 1D 4320 EQUB &1E \ 1E 4330 EQUB &1F \ 1F 4340 EQUB &20 \ 20 4350 EQUB &21 \ 21 4360 EQUB &22 \ 22 4370 EQUB &23 \ 23 4380 EQUB &24 \ 24 4390 EQUB &25 \ 25 4400 EQUB &26 \ 26 4410 EQUB &27 \ 27 4420 EQUB &28 \ 28 4430 EQUB &29 \ 29 4440 EQUB &2A \ 2A 4450 EQUB &2B \ 2B 4460 EQUB &2C \ 2C 4470 EQUB &2D \ 2D 4480 EQUB &2E \ 2E 4490 EQUB &2F \ 2F 4500 EQUB &30 \ 30 4510 EQUB &31 \ 31 4520 EQUB &32 \ 32 4530 EQUB &33 \ 33 4540 EQUB &34 \ 34 4550 EQUB &35 \ 35 4560 EQUB &36 \ 36 4570 EQUB &37 \ 37 4580 EQUB &38 \ 38 4590 EQUB &39 \ 39 4600 EQUB &3A \ 3A 4610 EQUB &3B \ 3B 4620 EQUB &3C \ 3C 4630 EQUB &3D \ 3D 4640 EQUB &3E \ 3E 4650 EQUB &3F \ 3F 4660 EQUB &40 \ 40 4670 EQUB &41 \ 41 4680 EQUB &42 \ 42 4690 EQUB &43 \ 43 4700 EQUB &44 \ 44 4710 EQUB &45 \ 45 4720 EQUB &46 \ 46 4730 EQUB &47 \ 47 4740 EQUB &48 \ 48 4750 EQUB &49 \ 49 4760 EQUB &4A \ 4A 4770 EQUB &4B \ 4B 4780 EQUB &4C \ 4C 4790 EQUB &4D \ 4D 4800 EQUB &4E \ 4E 4810 EQUB &4F \ 4F 4820 EQUB &50 \ 50 4830 EQUB &51 \ 51 4840 EQUB &52 \ 52 4850 EQUB &53 \ 53 4860 EQUB &54 \ 54 4870 EQUB &55 \ 55 4880 EQUB &56 \ 56 4890 EQUB &57 \ 57 4900 EQUB &58 \ 58 4910 EQUB &59 \ 59 4920 EQUB &5A \ 5A 4930 EQUB &5B \ 5B 4940 EQUB &5C \ 5C 4950 EQUB &5D \ 5D 4960 EQUB &5E \ 5E 4970 EQUB &5F \ 5F 4980 EQUB &60 \ 60 4990 EQUB &61 \ 61 5000 EQUB &62 \ 62 5010 EQUB &63 \ 63 5020 EQUB &64 \ 64 5030 EQUB &65 \ 65 5040 EQUB &66 \ 66 5050 EQUB &67 \ 67 5060 EQUB &68 \ 68 5070 EQUB &69 \ 69 5080 EQUB &6A \ 6A 5090 EQUB &6B \ 6B 5100 EQUB &6C \ 6C 5110 EQUB &6D \ 6D 5120 EQUB &6E \ 6E 5130 EQUB &6F \ 6F 5140 EQUB &70 \ 70 5150 EQUB &71 \ 71 5160 EQUB &72 \ 72 5170 EQUB &73 \ 73 5180 EQUB &74 \ 74 5190 EQUB &75 \ 75 5200 EQUB &76 \ 76 5210 EQUB &77 \ 77 5220 EQUB &78 \ 78 5230 EQUB &79 \ 79 5240 EQUB &7A \ 7A 5250 EQUB &7B \ 7B 5260 EQUB &7C \ 7C 5270 EQUB &7D \ 7D 5280 EQUB &7E \ 7E 5290 EQUB &7F \ 7F Delete 5300\ <<<<<<<<<<< Normal Fn keys >>>>>>>>>>>> 5310 EQUB ASC("<")+128 \ 80 F0 5320 EQUB ASC(">")+128 \ 81 F1 5330 EQUB ASC(",")+128 \ 82 F2 5340 EQUB ASC(".")+128 \ 83 F3 5350 EQUB ASC("4")+128 \ 84 F4 5360 EQUB ASC("5")+128 \ 85 F5 5370 EQUB ASC("O")+128 \ 86 F6 5380 EQUB ASC("7")+128 \ 87 F7 5390 EQUB ASC("8")+128 \ 88 F8 5400 EQUB ASC("J")+128 \ 89 F9 5410 EQUB &8A \ 8A 5420 EQUB ASC("]")+128 \ 8B Copy 5430 EQUB ASC("D")+128 \ 8C Left 5440 EQUB ASC("C")+128 \ 8D Right 5450 EQUB ASC("@")+128 \ 8E Down 5460 EQUB ASC("A")+128 \ 8F Up 5470\ <<<<<<<<<<<<< Shift Fn keys >>>>>>>>>>>>>>> 5471\ This section maps onto &80 - &8F (soft keys & cursor keys) 5480 EQUB &90 \ 90 5490 EQUB &91 \ 91 5500 EQUB &92 \ 92 5510 EQUB &93 \ 93 5520 EQUB &94 \ 94 5530 EQUB &95 \ 95 5540 EQUB &96 \ 96 5550 EQUB &97 \ 97 5560 EQUB &98 \ 98 5570 EQUB &99 \ 99 5580 EQUB &9A \ 9A 5590 EQUB &9B \ 9B Shift copy 5600 EQUB &9C \ 9C Shift left 5610 EQUB &9D \ 9D Shift right 5620 EQUB &9E \ 9E Shift down 5630 EQUB &9F \ 9F Shift up 5640\ <<<<<<<<<<< Control Fn keys >>>>>>>> 5650 EQUB &A0 \ A0 5660 EQUB &A1 \ A1 5670 EQUB &A2 \ A2 5680 EQUB &A3 \ A3 5690 EQUB &A4 \ A4 5700 EQUB &A5 \ A5 5710 EQUB &A6 \ A6 5720 EQUB &A7 \ A7 5730 EQUB &A8 \ A8 5740 EQUB &A9 \ A9 5750 EQUB &AA \ AA 5760 EQUB &8B \ AB Control copy 5770 EQUB &8C \ AC Control left 5780 EQUB &8D \ AD Control right 5790 EQUB &8E \ AE Control down 5800 EQUB &8F \ AF Control up 5810\ <<<<<<<<<<<<< Control+Shift Fn keys >>>>>>>>>> 5820 EQUB &B0 \ B0 5830 EQUB &B1 \ B1 5840 EQUB &B2 \ B2 5850 EQUB &B3 \ B3 5860 EQUB &B4 \ B4 5870 EQUB &B5 \ B5 5880 EQUB &B6 \ B6 5890 EQUB &B7 \ B7 5900 EQUB &B8 \ B8 5910 EQUB &B9 \ B9 5920 EQUB &BA \ BA 5930 EQUB &BB \ BB 5940 EQUB &BC \ BC 5950 EQUB &BD \ BD 5960 EQUB &BE \ BE 5970 EQUB &BF \ BF 5980 EQUB &C0 \ C0 5990 EQUB &C1 \ C1 6000 EQUB &C2 \ C2 6010 EQUB &C3 \ C3 6020 EQUB &C4 \ C4 6030 EQUB &C5 \ C5 6040 EQUB &C6 \ C6 6050 EQUB &C7 \ C7 6060 EQUB &C8 \ C8 6070 EQUB &C9 \ C9 6080 EQUB &CA \ CA 6090 EQUB &CB \ CB 6100 EQUB &CC \ CC 6110 EQUB &CD \ CD 6120 EQUB &CE \ CE 6130 EQUB &CF \ CF 6140 EQUB &D0 \ D0 6150 EQUB &D1 \ D1 6160 EQUB &D2 \ D2 6170 EQUB &D3 \ D3 6180 EQUB &D4 \ D4 6190 EQUB &D5 \ D5 6200 EQUB &D6 \ D6 6210 EQUB &D7 \ D7 6220 EQUB &D8 \ D8 6230 EQUB &D9 \ D9 6240 EQUB &DA \ DA 6250 EQUB &DB \ DB 6260 EQUB &DC \ DC 6270 EQUB &DD \ DD 6280 EQUB &DE \ DE 6290 EQUB &DF \ DF 6300 EQUB &E0 \ E0 6310 EQUB &E1 \ E1 6320 EQUB &E2 \ E2 6330 EQUB &E3 \ E3 6340 EQUB &E4 \ E4 6350 EQUB &E5 \ E5 6360 EQUB &E6 \ E6 6370 EQUB &E7 \ E7 6380 EQUB &E8 \ E8 6390 EQUB &E9 \ E9 6400 EQUB &EA \ EA 6410 EQUB &EB \ EB 6420 EQUB &EC \ EC 6430 EQUB &ED \ ED 6440 EQUB &EE \ EE 6450 EQUB &EF \ EF 6460 EQUB &F0 \ F0 6470 EQUB &F1 \ F1 6480 EQUB &F2 \ F2 6490 EQUB &F3 \ F3 6500 EQUB &F4 \ F4 6510 EQUB &F5 \ F5 6520 EQUB &F6 \ F6 6530 EQUB &F7 \ F7 6540 EQUB &F8 \ F8 6550 EQUB &F9 \ F9 6560 EQUB &FA \ FA 6570 EQUB &FB \ FB 6580 EQUB &FC \ FC 6590 EQUB &FD \ FD 6600 EQUB &FE \ FE 6610 EQUB &FF \ FF 6620] 6630NEXT 6640OSCLI("SAVE X.term "+STR$~(C%)+" "+STR$~(O%+1)+" 8000 8000") 6650END 6660DEFFNosbyte(A,X,Y) 6670[OPT Pass 6680 Lda #A 6690 Ldx #X 6700 Ldy #Y 6710 Jsr osbyte 6720] 6730=Pass