/* PDL ********************************************* BEGIN ReadLine DO GET char IF char is Control THEN IF char is EOF THEN SET end-of-string SET length to end flag RETURN ELSE IF char is EOL THEN SET end-of-string RETURN ELSE IF char is BackSpace THEN IF length is not original THEN INCREMENT length DISPLAY blank over last char ENDIF ELSE IF char is EraseLine THEN SET pointer to Buffer RESTORE length to original ELSE SET char in Buffer INCREMENT pointer DECREMENT length PUT char ENDIF WHILE length is not zero RETURN END ***************************************************/ /* Registers used ********************************** a0, d0 ***************************************************/ /* BEGIN ReadLine */ .NOLIST .INCLUDE "..\\Include\\ASCII.i" .LIST .EQU RL_EOF,0x04 | ^D .EQU RL_EOL,0x0D | ENTER .EQU RL_EOS,0x00 .EQU RL_BS,0x08 | ^H .EQU RL_ERASE,0x18 | ^X .EQU RL_CNTL,0x1F .EQU RL_END,-1 .TEXT 1 .EQU RL_ESC,0x1B | implements BS: back up 1, print blank, back up 1 char RL_DOBS: .BYTE RL_ESC,'[','1','D',' ',RL_ESC,'[','1','D',0 | implement ERASE: move to start of input and blank RL_DOERASE: .BYTE RL_ESC,'[','u',RL_ESC,'[','K',0 | need to save original cursor for DOERASE RL_DOSAVE: .BYTE RL_ESC,'[','s',0 | show EOF RL_EOFMsg: .BYTE '^','D',CR,LF,0 .TEXT 0 .GLOBAL ReadLine /* DO */ ReadLine: cmp.w #0,d0 | empty buffer? bne.b RL_OK | no, carry on rts | yes, just go RL_OK: movem.l a1-a2/d1-d2,-(a7) | save a1, a2, d1, d2 move.w d0,d1 | save original length move.w d0,d2 | and remainder in buffer movea.l a0,a1 | save original pointer movea.l a0,a2 | twice lea RL_DOSAVE,a0 jsr PrintMsg | save cursor location /* GET char */ RL_Top: jsr ConsoleIn | get a char /* IF char is Control THEN */ cmp.b #RL_CNTL,d0 | a control char? bhi.b RL_Normal | nope /* IF char is EOF THEN */ cmp.b #RL_EOF,d0 | end-of-file? bne.b RL_NotEOF | nope /* SET end-of-string */ move.b #RL_EOS,(a1) | yes, mark buffer end /* SET length to end flag */ move.w #RL_END,d0 | and set flag /* PUT EOF message */ lea RL_EOFMsg,a0 jsr PrintMsg /* RETURN */ bra.b RL_EOFExit | for return /* ELSE IF char is EOL THEN */ RL_NotEOF: cmp.b #RL_EOL,d0 | end of line? bne.b RL_NotEOL | nope /* SET end-of-string */ move.b #RL_EOS,(a1) | yes, mark buffer end move.w d2,d0 | and bytes read /* PUT new line */ jsr NewLine /* RETURN */ bra.b RL_Exit | for return /* ELSE IF char is BackSpace THEN */ RL_NotEOL: cmp.b #RL_BS,d0 | backspace? bne.b RL_NotBS | nope /* IF length is not original THEN */ cmp.w d1,d2 | already at start? beq.b RL_NotBS | yes, skip /* INCREMENT length */ addq.w #1,d1 | take char from buffer subq.w #1,a1 /* DISPLAY blank over last char */ lea RL_DOBS,a0 | show bs jsr PrintMsg | on screen /* ENDIF */ bra.b RL_Top /* ELSE IF char is EraseLine THEN */ RL_NotBS: cmp.b #RL_ERASE,d0 | erase line? bne.b RL_NotErase | nope /* SET pointer to Buffer */ movea.l a2,a1 | point to start /* RESTORE length to original */ move.l d2,d1 | and empty buffer /* DISPLAY blank over line */ lea RL_DOERASE,a0 | erase line jsr PrintMsg | on screen lea RL_DOSAVE,a0 | re-save cursor location jsr PrintMsg bra.b RL_Top | keep looping /* ELSE */ RL_NotErase: /* SET char in Buffer INCREMENT pointer */ RL_Normal: move.b d0,(a1)+ | store char /* DECREMENT length */ subq.w #1,d1 | and count it /* PUT char */ jsr ConsoleOut | put it on the screen /* ENDIF WHILE length is not zero */ cmp.w #0,d1 | buffer full? bne.w RL_Top | no, keep going /* RETURN */ RL_Exit: sub.w d1,d2 | calc len read move.w d2,d0 | for return RL_EOFExit: movea.l a2,a0 | get saved a0 and movem.l (a7)+,a1-a2/d1-d2 | restore a1, a2, d1, d2 rts /* END */