10Comm$ = "UNIX" 11Reverse$="XINU" 20Vers$ = "0.01" 30PutV = &22A 40GetV = &22C 50 60Oput = &80 70Oget = &82 80 90putptr = &84 100getptr = &86 110 120Top = &88 130Bot = &8A 140 150S_sent = &8C 160 170Buffer_count_lo = &8D:Buffer_count_hi = &8E 180XOFFtrigger_lo = &20:XOFFtrigger_hi = &0A 190XONtrigger_lo = &00:XONtrigger_hi=0 200Q_needed=&4FF 210 220true=1 230false=0 240 250 oswrch = &FFEE 260 osbyte = &FFF4 270 280 TEMP = &0070 290 TEMP1 = &0071 300 310 B% = &8000 320 330 C% = &C000 340 350FOR Pass = 4 TO 6 STEP 2 360 P%=B% 370 O%=C% 380[ OPT Pass 390 400 410.startROM 420JMP Second_processor 430JMP SERVJP 440EQUB &C2 450EQUB copyright-startROM 460EQUB &00 470EQUS "UNIX Terminal Emulator" 480EQUB &00 490EQUS Vers$ 500.copyright 510EQUB &00 520EQUS "(C) 1983 Acorn" 530EQUB &00 540\ 550 560\ BRK handler - should only be called on Language side. 570 580.Brkhand 590 Ldy #0 600.ErrLoop 610 Iny 620 Lda (&FD),Y 630 Beq ErrEnd 640 Jsr oswrch 650Jmp ErrLoop 660 670.ErrEnd 680Lda #0 690Sta Q_needed \ Clean-up... Might need ^Q 700 710Jmp Emulator 720 730 740 750 760.InitFX 770 OPT FNosbyte(&E5,1,0) 780 OPT FNosbyte(2,2,0) 790 OPT FNosbyte(181,1,0) \ Receive 8-bits 800 OPT FNosbyte(15,0,0) \ Flush buffers 810 OPT FNosbyte(11,190,0) \ Auto-repeat delay 820 OPT FNosbyte(144,0,1) \ *TV 0,1 830 OPT FNosbyte(7,7,0) \ Receive 9600 840 OPT FNosbyte(8,7,0) \ Transmit 9600 850 OPT FNosbyte(20,6,0) \ Explode char set? 860 Rts 870 880 890.Second_processor 900Lda #Brkhand MOD 256: Sta &202 910Lda #Brkhand DIV 256: Sta &203 920Cli 930.Emulator 970 OPT FNosbyte(&91,1,0) \ Get char from RS232 input buffer 980 990 BCS RS232_empty 1000 1010 TYA 1020 AND #&7F 1030 JSR oswrch 1040 1050.RS232_empty \ Also poll keyboard even if input was present, 1060 \ in order to give higher priority 1070 1110 OPT FNosbyte(&91,0,0) \ Get char from keyboard buffer 1120 1121 \ Y contains char!!! 1130 BCC Keyboard_empty \C=1 => Buffer empty 1140 1150 Lda Q_needed 1160 Cmp #true 1170 Beq Emulator 1171 1180 Ldy #ASC("Q") AND 31 \ Fake a ^Q typed at keyboard 1190 Lda #false:Sta S_sent:Sta Q_needed 1200 1210.Keyboard_empty 1211 \ Y contains char!!! 1220 TYA 1221 1230 PHA 1231 \ char ON STACK <<<<<<<< 1270 OPT FNosbyte(3,3,0) \ Select printer & RS232 output 1280\ ... Select Output (423) 1290 PLA 1291 \ char OFF STACK <<<<<<< 1300 Jsr oswrch 1310 1350 OPT FNosbyte(3,0,0) \ RE-select VDU output 1360Jmp Emulator 1361 1362 1363 1364 1365 1366 1370.SERVJP CMP #&04 \Offer command line 1380 BNE RET 1390 TYA \Save regs 1400 PHA 1410 TXA 1420 PHA 1430 LDX #LEN(Comm$) \Load counter 1440.CHKCOM LDA (&F2),Y \Pointer to command line 1450 CMP COMMAND-1,X 1460 BNE BADCOMM \Command not recognised 1470 INY 1480 DEX 1490 BNE CHKCOM 1500.DUMBGO JSR InitFX 1510 JSR initBF \ Order important - InitFX explodes char set, 1511 \ ... initBF reads OSHWM 1520 PLA 1530 TAX \Get rom no. in X 1540 LDA #&8E 1550 JSR osbyte \Jump to language 1551 1560.BADCOMM CMP #ASC"." \Check for abbreviation 1570 BEQ DUMBGO 1580 PLA 1590 TAX 1600 PLA 1610 TAY 1620 LDA #&04 \Pass command on 1630.RET RTS 1631 1632 1633 1634 1635 1636 1640.VSTRING PLA 1650 STA TEMP 1660 PLA 1670 STA TEMP+1 1680 LDY #&00 1690 BEQ VLOOP 1700.VGO JSR oswrch 1710.VLOOP INC TEMP 1720 BNE VGON 1730 INC TEMP+1 1740.VGON LDA (TEMP),Y 1750 BPL VGO 1760 JMP (TEMP) 1780.VDDONE RTS 1781 1782.COMMAND EQUS Reverse$ 1783 1784 1785 1786 1787 1790.initBF 1800 LDA #00 1810 STA Top 1820 LDA #&38 \ BOTTOM OF MODE 0 SCREEN (WORST CASE) 1830 STA Top+1 1840 LDA PutV 1850 STA Oput 1860 LDA PutV+1 1870 STA Oput+1 1880 LDA GetV 1890 STA Oget 1900 LDA GetV+1 1910 STA Oget+1 1920 LDA #Myget AND &FF 1930 STA GetV 1940 LDA #Myput AND &FF 1950 STA PutV 1960 LDA #Myget DIV 256 1970 STA GetV+1 1980 LDA #Myput DIV 256 1990 STA PutV+1 2030 OPT FNosbyte(&83,0,0) \ Get OSHWM 2040 CLC 2050 TYA 2060 ADC #7 2070 STA Bot+1 \ OSHWM +&700 - BOTTOM OF BUFFER 2080 STX Bot 2090LDA Bot 2100STA putptr 2110STA getptr 2120LDA Bot+1 2130STA putptr+1 2140STA getptr+1 2150 Lda #false \ Flow-control via X-ON/X-OFF - No ^S sent yet. 2160 Sta S_sent 2170 Lda #0 2180 Sta Buffer_count_lo \ and nothing in the buffer as far as XON/XOFF is 2190 Sta Buffer_count_hi \ concerned 2191\WHERE DO WE INIT Q_NEEDED ????????????? 2200 RTS 2201 2202 2203 2204 2205 2206 2210\########################################################################## 2220\## ## 2230\## PUT character into RS423 input buffer ## 2240\## ## 2250\########################################################################## 2260.Hisput JMP (Oput) 2270.Myput 2280 Cpx #1 \ Check that it is a RS423 buffer operation 2290 Bne Hisput \ If not, then use original buffer handler 2300 Tya \ A now contains character to be put in buffer 2310 Ldy #0 2320 Php \ Mask interrupts 2330 Sei 2340 Sta (putptr),Y \ Place character in buffer at 'putptr' 2350 Inc putptr 2360 Bne nocar1 2370 Inc putptr+1 2380.nocar1 \ and increment 'putptr' 2390 Lda putptr 2400 Cmp Top 2410 Bne done2 2420 Lda putptr+1 2430 Cmp Top+1 2440 Bne done2 \ If 'putptr' is at the end of the buffer, 2450 \ wrap it round to the start again 2460 Lda Bot 2470 Sta putptr 2480 Lda Bot+1 2490 Sta putptr+1 2500.done2 2510 Lda putptr 2520 Cmp getptr 2530 Bne done1 2540 Lda putptr+1 2550 Cmp getptr+1 2560 Bne done1 \ If putptr' has caught up with 'getptr', 2570 \ i.e. the buffer is full, then... 2580 Lda putptr 2590 Bne zz1 2600 Dec putptr+1 2610.zz1 2620 Dec putptr \ undo the put operation, 2630 Plp \ disable interrupts, 2640 Sec \ and return 'buffer full' code in carry 2650 Rts 2660.done1 \ Otherwise 2670 Inc Buffer_count_lo \ Increment count of bytes in buffer 2680 Bne qaz1 2690 Inc Buffer_count_hi 2700 .qaz1 2710 Lda Buffer_count_lo 2720 Cmp #XOFFtrigger_lo \ Test trigger value to see if ^S needed 2730 Bne Plenty_room_left 2740 \ in order not to overflow the buffer... 2750 Lda Buffer_count_hi 2760 Cmp #XOFFtrigger_hi 2770 Bne Plenty_room_left 2780 Lda S_sent 2790 Cmp #true 2800 Beq Plenty_room_left \ Oscillating around XOFF trigger, but 2810 \ should stop soon as value is going down... 2820 Lda #3: Ldx #3: Ldy #0: Jsr osbyte 2830 Lda #ASC("S") AND 31 \ Send XOFF if so. 2840 Jsr oswrch 2850 Lda #3: Ldx #0: Ldy #0: Jsr osbyte 2860 Lda #true \ And note the fact so that 'get from buffer' 2870 \ can send the XON when there is room. 2880 Sta S_sent \ (Note that S_sent is a flag, not a semaphore, 2890 \ as this machine does not have processes) 2900.Plenty_room_left 2910 Plp \ Restore interrupts, 2920 Clc \ and return 'buffer not full' code in carry 2930 Rts 2932 2933 2934 2935 2936 2937 2938 2940\########################################################################## 2950\## ## 2960\## GET character from RS423 input buffer ## 2970\## ## 2980\########################################################################## 2990.Hisget JMP (Oget) 3000.Myget CPX #1 3010 Bne Hisget \ Check for RS324 'get from buffer' operation 3020 Php \ Mask interrupts 3030 Sei 3040 Lda getptr 3050 Cmp putptr 3060 Bne L27 3070 Lda getptr+1 3080 Cmp putptr+1 3090 Bne L27 \ If nothing in buffer ('getptr' = 'putptr') 3100 Plp \ then restore interrupts 3110 Sec \ and return 'buffer empty' code in carry 3120 Rts 3130.L27 3140 Ldy #0 3150 Lda (getptr),Y \ else fetch the byte 3160 Tay 3170 Inc getptr 3180 Bne L30 3190 Inc getptr+1 3200.L30 \ and increment the 'get' pointer 3210 Lda getptr 3220 Cmp Top 3230 Bne done10 3240 Lda getptr+1 3250 Cmp Top+1 3260 Bne done10 \ If the 'get' pointer is at the limit 3270 \ of the cyclic buffer, then 3280 Lda Bot 3290 Sta getptr 3300 Lda Bot+1 3310 Sta getptr+1 \ reset it to the other end. 3320.done10 3330 Lda Buffer_count_lo 3340 Bne qaz2 3350 Dec Buffer_count_hi 3360.qaz2 3370 Dec Buffer_count_lo 3380 Lda S_sent 3390 Cmp #true \ Are we holding off input? 3400 Bne No_check_needed 3410 Lda Buffer_count_lo 3420 Cmp #XONtrigger_lo \ Is there enough room yet? 3430 Bne No_check_needed 3440 Lda Buffer_count_hi 3450 Cmp #XONtrigger_hi 3460 Bne No_check_needed 3470\******* Set flag to send ^Q from top level. 3480\******* Top level will set S_sent to false... 3490Lda #true:Sta Q_needed 3500.No_check_needed 3510 Plp \ Restore interrupts 3520 Clc \ Return 'character fetched OK' code in carry 3530 Rts 3540] 3550NEXT 3551OSCLI("SAVE :0.R."+Comm$+" "+STR$~(C%)+" "+STR$~(O%+1)+" 8000 8000") 3560END 4000DEFFNosbyte(A,X,Y) 4010[OPT Pass 4020 Lda #A 4030 Ldx #X 4040 Ldy #Y 4050 Jsr osbyte 4060] 4070=Pass