******************************** * Start regular words 2 ******************************** * * Word "abs" - return absolute value of top stack item * WORD63 ASC 'abs ' DW ABS ABS JSR POPDATA TXA BPL GLOB_PUSH NEGATSUB TYA EOR #$FF CLC ADC #01 TAY TXA EOR #$FF ADC #00 TAX GLOB_PUSH JMP PUSHDATA * * Word "negate" - negate top value on stack * WORD64 ASC 'negate ' DW NEGATE NEGATE JSR POPDATA BRA NEGATSUB * * Word "<" - comparison operator * WORD65 ASC '< ' DW LESSTHAN LESSTHAN JSR POPDATA ; Fetch first signed integer STY PNTR STX PNTR+1 JSR POPDATA ; Fetch second signed integer TXA ; Actual comparison done here EOR PNTR+1 AND #$80 BEQ :SAMESGN TXA BMI :TRUE BRA :FALSE :SAMESGN CPX PNTR+1 BNE :NOCHKLO CPY PNTR :NOCHKLO BCC :TRUE :FALSE LDY #$00 LDX #$00 JMP PUSHDATA :TRUE LDY #$FF LDX #$FF JMP PUSHDATA * * Word ">" - comparison operator * WORD66 ASC '> ' DW MORETHAN MORETHAN JSR POPDATA ; Fetch first signed integer STY PNTR STX PNTR+1 JSR POPDATA ; Fetch second signed integer TXA ; Actual comparison done here EOR PNTR+1 AND #$80 BEQ :SAME TXA BPL :TRUE BRA :FALSE :SAME CPX PNTR+1 BNE :NOCHKLO CPY PNTR :NOCHKLO BCC :FALSE BEQ :FALSE :TRUE LDY #$FF LDX #$FF JMP PUSHDATA :FALSE LDY #$00 LDX #$00 JMP PUSHDATA * * Word "=" - comparison operator * * Note: bypasses POPDATA, PUSHDATA for speed * WORD67 ASC '= ' DW EQUAL EQUAL LDA DATITEMS ; Make sure there's at least CMP #02 ; two items on stack BCC :ERROR LDY DATSTACK LDA DATAAREA+1,Y CMP DATAAREA+3,Y BNE :FALSE LDA DATAAREA+2,Y CMP DATAAREA+4,Y BNE :FALSE LDA #$FF HEX 2C :FALSE LDA #00 STA DATAAREA+3,Y STA DATAAREA+4,Y INY ; Adjust data stack pointer INY STY DATSTACK :SKIPINC DEC DATITEMS ; Adjust data items pointer RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "<>" - comparison operator * * Note: bypasses POPDATA, PUSHDATA for speed * WORD68 ASC '<> ' DW NOTEQUAL NOTEQUAL LDA DATITEMS ; Make sure there's at least CMP #02 ; two items on stack BCC :ERROR LDY DATSTACK LDA DATAAREA+1,Y CMP DATAAREA+3,Y BNE :TRUE LDA DATAAREA+2,Y CMP DATAAREA+4,Y BNE :TRUE LDA #00 HEX 2C :TRUE LDA #$FF STA DATAAREA+3,Y STA DATAAREA+4,Y INY ; Adjust data stack pointer INY STY DATSTACK :SKIPINC DEC DATITEMS ; Adjust data items pointer RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "U<" - unsigned compare * WORD69 ASC 'u< ' DW ULESS ULESS JSR POPDATA STY PNTR STX PNTR+1 JSR POPDATA CPX PNTR+1 BCC :TRUE BEQ :CHKLOW BCS :FALSE :CHKLOW CPY PNTR BCC :TRUE :FALSE LDY #00 LDX #00 JMP PUSHDATA :TRUE LDY #$FF LDX #$FF JMP PUSHDATA * * Word "0=" - compare to zero * WORD70 ASC '0= ' DW ZEROEQUA ZEROEQUA JSR POPDATA TXA BNE :FALSE TYA BNE :FALSE LDA #$FF HEX 2C ; BIT trick :FALSE LDA #00 TAX TAY JMP PUSHDATA * * Word "0<" - compare negative * WORD71 ASC '0< ' DW NEGATIVE NEGATIVE JSR POPDATA TXA BPL :FALSE LDA #$FF HEX 2C ; BIT trick :FALSE LDA #00 TAX TAY JMP PUSHDATA * * Word "0>" - check positive * WORD72 ASC '0> ' DW POSITIVE POSITIVE JSR POPDATA TXA BNE :NOTZERO TYA BNE :NOTZERO BRA :FALSE :NOTZERO TXA BMI :FALSE LDA #$FF HEX 2C ; BIT trick :FALSE LDA #00 TAX TAY JMP PUSHDATA * * Word "false" - push 0 on stack * WORD73 ASC 'false ' DW FALSE FALSE LDY #$00 LDX #$00 JMP PUSHDATA * * Word "true" - push -1 on stack * WORD74 ASC 'true ' DW TRUE TRUE LDY #$FF LDX #$FF JMP PUSHDATA * * Word "1+" - increment top item on stack * * Note: bypasses POPDATA, PUSHDATA for speed * WORD75 ASC '1+ ' DW ONEPLUS ONEPLUS LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to increment LDX DATSTACK INC DATAAREA+1,X BNE :SKIPINC INC DATAAREA+2,X :SKIPINC RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "1-" - decrement top item on stack * * Note: bypasses POPDATA, PUSHDATA for speed * WORD76 ASC '1- ' DW ONEMINUS ONEMINUS LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to decrement LDX DATSTACK LDA DATAAREA+1,X BNE :SKIPDEC DEC DATAAREA+2,X :SKIPDEC DEC DATAAREA+1,X RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "2+" - increment top item on stack by 2 * * Note: bypasses POPDATA, PUSHDATA for speed * WORD77 ASC '2+ ' DW TWOPLUS TWOPLUS LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to increment LDX DATSTACK LDA DATAAREA+1,X INC INC STA DATAAREA+1,X BNE :SKIPINC INC DATAAREA+2,X :SKIPINC RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "2-" - decrement top item on stack by 2 * * Note: bypasses POPDATA, PUSHDATA for speed * WORD78 ASC '2- ' DW TWOMINUS TWOMINUS LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to decrement LDX DATSTACK LDA DATAAREA+1,X SEC SBC #02 STA DATAAREA+1,X BCS :SKIPDEC DEC DATAAREA+2,X :SKIPDEC RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "2*" - do arithmetic shift left on top stack item * * Note: bypasses POPDATA, PUSHDATA for speed * WORD79 ASC '2* ' DW TWOMULT TWOMULT LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to multiply LDX DATSTACK ASL DATAAREA+1,X ROL DATAAREA+2,X RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "2/" - do logical shift right on top stack item * * Note: bypasses POPDATA, PUSHDATA for speed * WORD80 ASC '2/ ' DW TWODIV TWODIV LDA DATITEMS ; Make sure there's something on stack BEQ :ERROR ; to multiply LDX DATSTACK LSR DATAAREA+2,X ROR DATAAREA+1,X RTS :ERROR LDA #04 ; "Data stack underflow" JMP PRTERR * * Word "b.and" - performs binary AND * WORD81 ASC 'b.and ' DW B_AND B_AND JSR POPDATA STY PNTR STX PNTR+1 JSR POPDATA TYA AND PNTR TAY TXA AND PNTR+1 TAX JMP PUSHDATA * * Word "b.or" - performs binary OR * WORD82 ASC 'b.or ' DW B_OR B_OR JSR POPDATA STY PNTR STX PNTR+1 JSR POPDATA TYA ORA PNTR TAY TXA ORA PNTR+1 TAX JMP PUSHDATA * * Word "b.clr" - performs twos complement then AND * WORD83 ASC 'b.clr ' DW B_CLR B_CLR JSR POPDATA TYA EOR #$FF STA PNTR TXA EOR #$FF STA PNTR+1 JSR POPDATA TYA AND PNTR TAY TXA AND PNTR+1 TAX JMP PUSHDATA * * Word "page" - Clears screen * WORD84 ASC 'page ' DW HOME HOME LDA #" " ; Damn $C300 outputs whatever JSR $C300 ; is in accumulator STZ CH RTS * * Word "cv" - Sets cursor vertical position * WORD85 ASC 'cv ' DW SETCV SETCV JSR POPDATA STY CV TYA JMP BASCALC * * Word "ch" - Sets cursor horizontal position * WORD86 ASC 'ch ' DW SETCH SETCH JSR POPDATA STY CH RTS * * Word "key" - Wait for a key * WORD87 ASC 'key ' DW KEY KEY JSR GETKEY TAY LDX #00 JMP PUSHDATA * * Word "key?" - Check for keypress * WORD88 ASC 'key? ' DW KEY? KEY? BIT KYBD BMI :TRUE LDA #00 ; Speed not crucial here HEX 2C ; BIT trick :TRUE LDA #$FF TAY TAX JMP PUSHDATA * * Word "expect" - awaits characters from keyboard * WORD89 ASC 'expect ' DW EXPECT EXPECT JSR POPDATA ; Get number of characters max STY PNTR2 STX PNTR2+1 JSR POPDATA ; Get address to store characters STY PNTR STX PNTR+1 STZ SPANVAL ; Current number of keys STZ SPANVAL+1 :LOOP JSR GETKEY ; Get a key CMP #$08 BEQ :BACK CMP #$7F BNE :NOTBACK :BACK LDA SPANVAL ; Make sure we have characters to erase ORA SPANVAL+1 BEQ :LOOP LDA SPANVAL ; Decrement number of characters BNE :SKIPDEC DEC SPANVAL+1 :SKIPDEC DEC SPANVAL LDA #$08 ; Erase previous character on screen JSR COUT LDA #' ' JSR COUT LDA #$08 JSR COUT BRA :LOOP :NOTBACK CMP #$0D BNE :NOTRETN RTS :NOTRETN LDY SPANVAL ; Make sure we haven't reached CPY PNTR2 ; maximum # of characters yet BNE :OK LDY SPANVAL+1 CPY PNTR2+1 BEQ :LOOP :OK TAY ; Store character at address LDA PNTR CLC ADC SPANVAL STA PNTR3 LDA PNTR+1 ADC SPANVAL+1 STA PNTR3+1 TYA STA (PNTR3) JSR COUT ; Echo key to screen INC SPANVAL ; Increment character count BNE :SKIPINC INC SPANVAL+1 :SKIPINC BRA :LOOP * * Word "span" - returns number of characters received by expect * WORD90 ASC 'span ' DW SPAN SPAN LDY SPANVAL LDX SPANVAL+1 JMP PUSHDATA SPANVAL HEX 0000 * * Word "emit" - outputs character value on stack, low byte * WORD91 ASC 'emit ' DW EMIT EMIT JSR POPDATA TYA JMP COUT * * Word "space" - outputs space * WORD92 ASC 'space ' DW SPACE SPACE LDA #' ' PRT JMP COUT * * Word "spaces" - outputs multiples spaces * WORD93 ASC 'spaces ' DW SPACES SPACES JSR POPDATA STY PNTR STX PNTR+1 LDA #" " :LOOP LDX PNTR BNE :SKIPDEC DEC PNTR+1 LDX PNTR+1 CPX #$FF BEQ :FINIS :SKIPDEC DEC PNTR JSR COUT BRA :LOOP :FINIS RTS * * Word "cr" - outputs return * WORD94 ASC 'cr ' DW CR CR LDA #$8D BRA PRT * * Word "fill" - fills memory with value * WORD95 ASC 'fill ' DW FILL FILL JSR POPDATA ; Fetch fill value STY TEMP FILL2 JSR POPDATA ; Fetch fill counter PHY PHX JSR POPDATA ; Fetch fill address STY PNTR STX PNTR+1 LDA TEMP ; Set up fill value PLX ; Check if any pages BEQ :NOPAGE LDY #00 ; Fill in pages :LOOP STA (PNTR),Y INY BNE :LOOP INC PNTR+1 DEX BNE :LOOP :NOPAGE PLX ; Fill in fractional pages BEQ :FINIS LDY #00 :LOOP2 STA (PNTR),Y INY DEX BNE :LOOP2 :FINIS RTS * * Word "erase" - fills memory with zeros * WORD96 ASC 'erase ' DW ERASE ERASE LDA #00 STA TEMP JMP FILL2 * * Word "close" - closes all open files * WORD97 ASC 'close ' DW CLOSE CLOSE JMP CLOSFILE * * Word "bye" - exits Qforth * WORD98 ASC 'bye ' DW BYE BYE JSR MLI DFB $65 DW :PARMS :PARMS DFB 4 HEX 00 HEX 0000 HEX 00 HEX 0000 ******************************** * End regular words 2 ********************************