10PutV = &22A 20GetV = &22C 30Oput = &80 40Oget = &82 50putptr = &84 60getptr = &86 70Top = &88 80Bot = &8A 90S_sent = &8C 100Buffer_count_lo = &8D:Buffer_count_hi = &8E 110XOFFtrigger_lo = &20:XOFFtrigger_hi = &0A 120XONtrigger_lo = &00:XONtrigger_hi=0 130true=1 140false=0 150 oswrch = &FFEE 160 osbyte = &FFF4 170 OSWORD = &FFF1 180 TEMP = &0070 190 Sym = TEMP 200 TEMP1 = &0071 210 220Q_needed=&4FF 230 240 COMLEN = 4 250 260 REM Len ("UNIX") 270 280 B% = &8000 290 300 C% = &C000 310 320 FOR Z = 4 TO 7 STEP 3 330 P%=B% 340 O%=C% 350[ OPT Z 360 370 380.startROM 390JMP LANGJP 400JMP SERVJP 410EQUB &C2 420EQUB COPYR-startROM 430EQUB &00 440EQUS "UNIX Terminal Emulator" 450EQUB &00 460EQUS "0.00" 470.COPYR EQUB &00 480EQUS "(C) 1983 Acorn" 490EQUB &00 500\ 510\Brk handler 520.Brkhand 530Lda #31:JSR oswrch:Lda #1:JSR oswrch:LDA #24:JSR oswrch 540Ldy #0 550.ErrLoop Iny 560Lda (&FD),Y:Beq ErrEnd 570Ora #&80:Jsr oswrch 580Jmp ErrLoop 590.ErrEnd 600Lda #0 610Sta Q_needed 620JMP LOOP 630 640.LANGJP 650Lda #Brkhand MOD 256: Sta &202 660Lda #Brkhand DIV 256: Sta &203 670Cli 680LDA #&E5 690LDX #&1 700LDY #&0 710JSR osbyte 720LDA #&02 730TAX 740LDY #0 750JSR osbyte 760LDA #181 770LDX #1 780LDY #0 790 JSR osbyte \ RS 8 bit 800 lda #15:ldx #0:ldy #0: jsr osbyte \ *fx 15,0 - flush buffers 810 LDA #11 820 LDX #190 830 JSR osbyte \ AUTO REP DELAY 840 LDA #144 850 LDX #0 860 LDY #1 870 JSR osbyte \ *TV 0,1 880LDA #22 890JSR oswrch 900LDA #3 910JSR oswrch \ Mode 3 920JSR VSTRING 930EQUB 31 940 EQUB 44 \ Send to spare report line 950 EQUB 0 960 EQUS "Acorn UNIX Terminal Emulator 0.00" 970 EQUB 30 980 NOP 990 LDX #7 1000 LDA #7 1010 JSR osbyte \ *FX 7,7 9600 Rx 1020 LDX #7 1030 LDA #8 1040 JSR osbyte \ *FX 8,7 9600 Tx 1050 LDA #20:LDX #6:LDY #0: JSR osbyte 1060 1070.LOOP LDA #&91 1080 LDX #&01 1090 LDY #&00 1100 JSR osbyte \*FX145,1 Get char from 423 i/p buffer 1110 1120\ Select Input (423) assumed 1130\ A = Inkey (0) 1140 1150 BCS KEYBOARD \C=1 => Buffer empty 1160\ if Success then ... 1170 TYA 1180 AND #&7F 1190 JSR oswrch 1200\ ... ToVDU (A) 1210.KEYBOARD 1220 LDA #&91 1230 LDX #&00 1240 LDY #&00 1250 JSR osbyte \*FX 145,0 Get char from keyboard buffer 1260\ A = Inkey (0) 1270 BCS pdone \C=1 => Buffer empty 1280\ if Success then ... 1281.BODGEUP 1290 TYA 1300 PHA 1310 LDA #3 1320 LDX #3 1330 LDY #0 1340 JSR osbyte \*FX3,3 Select printer & 423 1350\ ... Select Output (423) 1360 PLA 1370 Jsr oswrch 1380\ ... To423 (A) 1390 LDA #&03 1400 LDX #&00 1410 LDY #&00 1420 JSR osbyte \*FX3,0 Re-select VDU 1430JMP LOOP 1440.pdone 1450\ ... Select Output (VDU) 1460\? RS423 output assumed? 1470Lda Q_needed 1480Cmp #true 1490Bne qdone 1500LdY #ASC("Q") AND 31 1510JSR oswrch 1520Lda #false:Sta S_sent:Sta Q_needed 1521JMP BODGEUP 1530.qdone JMP LOOP 1540\ >> forever 1550.SERVJP CMP #&04 \Offer command line 1560 BNE RET 1570 TYA \Save regs 1580 PHA 1590 TXA 1600 PHA 1610 LDX #COMLEN \Load counter 1620.CHKCOM LDA (&F2),Y \Pointer to command line 1630 CMP COMMAND-1,X 1640 BNE BADCOMM \Command not recognised 1650 INY 1660 DEX 1670 BNE CHKCOM 1680.DUMBGO JSR initBF 1690 PLA 1700 TAX \Get rom no. in X 1710 LDA #&8E 1720 JSR osbyte \Jump to language 1730.BADCOMM CMP #ASC"." \Check for abbreviation 1740 BEQ DUMBGO 1750 PLA 1760 TAX 1770 PLA 1780 TAY 1790 LDA #&04 \Pass command on 1800.RET RTS 1810.VSTRING PLA 1820 STA TEMP 1830 PLA 1840 STA TEMP+1 1850 LDY #&00 1860 BEQ VLOOP 1870.VGO JSR oswrch 1880.VLOOP INC TEMP 1890 BNE VGON 1900 INC TEMP+1 1910.VGON LDA (TEMP),Y 1920 BPL VGO 1930 JMP (TEMP) 1940.COMMAND EQUS "XINU" 1950.VDDONE RTS 1960.initBF 1970 LDA #00 1980 STA Top 1990 LDA #&38 2000 STA Top+1 2010 LDA PutV 2020 STA Oput 2030 LDA PutV+1 2040 STA Oput+1 2050 LDA GetV 2060 STA Oget 2070 LDA GetV+1 2080 STA Oget+1 2090 LDA #Myget AND &FF 2100 STA GetV 2110 LDA #Myput AND &FF 2120 STA PutV 2130 LDA #Myget DIV 256 2140 STA GetV+1 2150 LDA #Myput DIV 256 2160 STA PutV+1 2170LDA #&83 2180LDY #0 2190LDX #0 2200JSR osbyte 2210 CLC 2220 TYA 2230 ADC #7 2240 STA Bot+1 2250 STX Bot 2260LDA Bot 2270STA putptr 2280STA getptr 2290LDA Bot+1 2300STA putptr+1 2310STA getptr+1 2320 Lda #false \ Flow-control via X-ON/X-OFF - No ^S sent yet. 2330 Sta S_sent 2340 Lda #0 2350 Sta Buffer_count_lo \ and nothing in the buffer as far as XON/XOFF is 2360 Sta Buffer_count_hi \ concerned 2370 RTS 2380\########################################################################## 2390\## ## 2400\## PUT character into RS423 input buffer ## 2410\## ## 2420\########################################################################## 2430.Hisput JMP (Oput) 2440.Myput 2450 Cpx #1 \ Check that it is a RS423 buffer operation 2460 Bne Hisput \ If not, then use original buffer handler 2470 Tya \ A now contains character to be put in buffer 2480 Ldy #0 2490 Php \ Mask interrupts 2500 Sei 2510 Sta (putptr),Y \ Place character in buffer at 'putptr' 2520 Inc putptr 2530 Bne nocar1 2540 Inc putptr+1 2550.nocar1 \ and increment 'putptr' 2560 Lda putptr 2570 Cmp Top 2580 Bne done2 2590 Lda putptr+1 2600 Cmp Top+1 2610 Bne done2 \ If 'putptr' is at the end of the buffer, 2620 \ wrap it round to the start again 2630 Lda Bot 2640 Sta putptr 2650 Lda Bot+1 2660 Sta putptr+1 2670.done2 2680 Lda putptr 2690 Cmp getptr 2700 Bne done1 2710 Lda putptr+1 2720 Cmp getptr+1 2730 Bne done1 \ If putptr' has caught up with 'getptr', 2740 \ i.e. the buffer is full, then... 2750 Lda putptr 2760 Bne zz1 2770 Dec putptr+1 2780.zz1 2790 Dec putptr \ undo the put operation, 2800 Plp \ disable interrupts, 2810 Sec \ and return 'buffer full' code in carry 2820 Rts 2830.done1 \ Otherwise 2840 Inc Buffer_count_lo \ Increment count of bytes in buffer 2850 Bne qaz1 2860 Inc Buffer_count_hi 2870 .qaz1 2880 Lda Buffer_count_lo 2890 Cmp #XOFFtrigger_lo \ Test trigger value to see if ^S needed 2900 Bne Plenty_room_left 2910 \ in order not to overflow the buffer... 2920 Lda Buffer_count_hi 2930 Cmp #XOFFtrigger_hi 2940 Bne Plenty_room_left 2950 Lda S_sent 2960 Cmp #true 2970 Beq Plenty_room_left \ Oscillating around XOFF trigger, but 2980 \ should stop soon as value is going down... 2990 Lda #3: Ldx #3: Ldy #0: Jsr osbyte 3000 Lda #ASC("S") AND 31 \ Send XOFF if so. 3010 Jsr oswrch 3020 Lda #3: Ldx #0: Ldy #0: Jsr osbyte 3030 Lda #true \ And note the fact so that 'get from buffer' 3040 \ can send the XON when there is room. 3050 Sta S_sent \ (Note that S_sent is a flag, not a semaphore, 3060 \ as this machine does not have processes) 3070.Plenty_room_left 3080 Plp \ Restore interrupts, 3090 Clc \ and return 'buffer not full' code in carry 3100 Rts 3110\########################################################################## 3120\## ## 3130\## GET character from RS423 input buffer ## 3140\## ## 3150\########################################################################## 3160.Hisget JMP (Oget) 3170.Myget CPX #1 3180 Bne Hisget \ Check for RS324 'get from buffer' operation 3190 Php \ Mask interrupts 3200 Sei 3210 Lda getptr 3220 Cmp putptr 3230 Bne L27 3240 Lda getptr+1 3250 Cmp putptr+1 3260 Bne L27 \ If nothing in buffer ('getptr' = 'putptr') 3270 Plp \ then restore interrupts 3280 Sec \ and return 'buffer empty' code in carry 3290 Rts 3300.L27 3310 Ldy #0 3320 Lda (getptr),Y \ else fetch the byte 3330 Tay 3340 Inc getptr 3350 Bne L30 3360 Inc getptr+1 3370.L30 \ and increment the 'get' pointer 3380 Lda getptr 3390 Cmp Top 3400 Bne done10 3410 Lda getptr+1 3420 Cmp Top+1 3430 Bne done10 \ If the 'get' pointer is at the limit 3440 \ of the cyclic buffer, then 3450 Lda Bot 3460 Sta getptr 3470 Lda Bot+1 3480 Sta getptr+1 \ reset it to the other end. 3490.done10 3500 Lda Buffer_count_lo 3510 Bne qaz2 3520 Dec Buffer_count_hi 3530.qaz2 3540 Dec Buffer_count_lo 3550 Lda S_sent 3560 Cmp #true \ Are we holding off input? 3570 Bne No_check_needed 3580 Lda Buffer_count_lo 3590 Cmp #XONtrigger_lo \ Is there enough room yet? 3600 Bne No_check_needed 3610 Lda Buffer_count_hi 3620 Cmp #XONtrigger_hi 3630 Bne No_check_needed 3640\******* Set flag to send ^Q from top level. 3650\******* Top level will set S_sent to false... 3660Lda #true:Sta Q_needed 3670.No_check_needed 3680 Plp \ Restore interrupts 3690 Clc \ Return 'character fetched OK' code in carry 3700 Rts 3710] 3720NEXT 3730END