Jump to content
IGNORED

OS Routine to convert word to atascii #?


Recommended Posts

Atascii is virtually the same as ASCII for the visible non-graphic characters. The main differences are stuff like cursor movement, delete character, line etc. In some cases such codes don't even exist in normal ASCII and when they do they're usually in the 1-31 range.

 

Probably the closest thing to such conversion is in the S: routine to do text mode character output. Since "screen codes" are different to ATASCII in many cases the top 2 bits are used as index into a table where the character is modified so it displays properly.

 

For doing conversion from Atascii to Ascii and back, an efficient way would probably be to do bounds check to whitelist valid characters then a table with Atascii to Ascii values for characters not whitelisted should do for the remainder. The control chars for Atascii are spread around somewhat but most (all?) for plain Ascii are in that 1-31 range.

Link to comment
Share on other sites

If you're looking for a number printing routine, the OS routines would be IFP + FASC in the math pack, though not that fast. You're better off doing it by hand -- either shift bits left out of the word in binary mode while shifting bits in left in decimal mode and then use a hex-to-ATASCII routine, or just count off digits at a time.

Link to comment
Share on other sites

I would venture that if you want to have a status line in a text editor showing things like file position, row and column and free RAM constantly updated after every keystroke and redraw of the screen (the latter usually being expensive enough in itself), calling the OS FP pack to generate integer strings isn't the best use of machine cycles.

Edited by flashjazzcat
Link to comment
Share on other sites

Yup, that worked out well...

 

 

  2006              DISP8   PROC
  2006  A202                LDX #02
  2008  A04C                LDY #$4C
  200A  8C5820      .1      STY .B
  200D  4A                  LSR A
  200E  2A          .2      ROL A
  200F  B005 ^2016          BCS .3
  2011  DD5520              CMP .A,X
  2014  9004 ^201A          BCC .4
  2016  FD5520      .3      SBC .A,X
  2019  38                  SEC
  201A  2E5820      .4      ROL .B
  201D  90EF ^200E          BCC .2
  201F  A8                  TAY
  2020  AD5820              LDA .B
  2023  202D20              JSR OUTPUT
  2026  98                  TYA
  2027  A013                LDY #$13
  2029  CA                  DEX
  202A  10DE ^200A          BPL .1
  202C  60                  RTS
                    
  202D  48          OUTPUT  PHA             ; PUSH A
  202E  8A                  TXA
  202F  48                  PHA             ; PUSH X
  2030  98                  TYA
  2031  48                  PHA             ; PUSH Y 
                    
  2032  A200                LDX #$00        ; IOCB 0
  2034  A90B                LDA #$0B        ; PUTCHR
  2036  9D4203              STA ICCOM,X
  2039  A908                LDA #$08        ; OWRITE
  203B  9D4A03              STA ICAX1,X
  203E  A900                LDA #$00
  2040  9D4B03              STA ICAX2,X
  2043  9D4803              STA ICBLL,X
  2046  9D4903              STA ICBLH,X
  2049  AD5820              LDA .B          ; DIGIT IN A
  204C  2056E4              JSR CIOV
                    
  204F  68                  PLA             ; PULL Y
  2050  A8                  TAY
  2051  68                  PLA             ; PULL X
  2052  AA                  TAX
  2053  68                  PLA             ; PULL A
  2054  60                  RTS
                    
  2055  80A0C8      .A      DB 128,160,200
  2058  = 0001      .B      DS 1
                            EPROC   ; END DISP8
  • Like 1
Link to comment
Share on other sites

Anyone have a favorite for outputting ascii from a 16-bit value in registers?

 

-Thom

16 bit value? ASCII is 8 bit. That's either two characters or you need to dump the most significant byte.

As for output on the Atari... someone else will have to answer that.

One question... output how? To the screen? Or to a device?

 

Link to comment
Share on other sites

Found this, but have been unable to get it to work properly...

 

 

OUTDEC16Z
    LDX #4
    LDY #$26
.1  LDA VALUELO
    CMP TABLO,X
    LDA VALUEHI
    SBC TABHI,X
    BCC .3
.2  LDA VALUELO
    SBC TABLO,X
    STA VALUELO
    LDA VALUEHI
    SBC TABHI,X
    STA VALUEHI
    SEC
.3  TYA
    ROL A
    BCS .4
    TAY
    ASL VALUELO
    ROL VALUEHI
    BCS .2
    BCC .1
.4  JSR OUTPUT
    LDY #$13
    DEX
    BPL .1
    RTS

.VALUELO DB 0
.VALUEHI DB 0
.TABLO   DB $00,$00,$00,$00,$40
.TABHI   DB $40,$50,$64,$7D,$9C
Link to comment
Share on other sites

Works fine for me - you need to supply an OUTPUT sub. It then stores or prints the digits (high thru low without stripping leading zeros). The sub needs to preserve registers and not otherwise disturb the main part.

 

I pasted into a Mac-65 emulated instance and adjusted to work there.

I've used locations $4000-1 to hold the 16-bit input value (lo/hi).

 

 

         *=  $8000
         .OPT OBJ,NO LIST
OUTDEC16Z
         LDX $4000
         LDY $4001
         STX VALUELO
         STY VALUEHI
         LDA #0
         STA OUTIND
         LDX #4
         LDY #$26
BR1      LDA VALUELO
         CMP TABLO,X
         LDA VALUEHI
         SBC TABHI,X
         BCC BR3
BR2      LDA VALUELO
         SBC TABLO,X
         STA VALUELO
         LDA VALUEHI
         SBC TABHI,X
         STA VALUEHI
         SEC
BR3      TYA
         ROL A
         BCS BR4
         TAY
         ASL VALUELO
         ROL VALUEHI
         BCS BR2
         BCC BR1
BR4      JSR OUTPUT
         LDY #$13
         DEX
         BPL BR1
         RTS
         BRK
OUTPUT
         STY SAVEY
         LDY OUTIND
         STA RESULT,Y
         INC OUTIND
         LDY SAVEY
         RTS
VALUELO  .BYTE 0
VALUEHI  .BYTE 0
TABLO    .BYTE $00,$00,$00,$00,$40
TABHI    .BYTE $40,$50,$64,$7D,$9C
OUTIND   .BYTE 0
SAVEY    .BYTE 0
         *=  $8100
RESULT   .BYTE "00000"
Edited by Rybags
Link to comment
Share on other sites

David_P: Well, these are for user outputs, such as row, column so.. ;)

Rybags: oh, thanks, I was close...

 

I just find it odd that given that you often need to display numbers etc in a routine that more individuals wouldn't have fast outputs for 8 or 16-bit quantities to ASCII (ATASCII).

 

Meanwhile, I am in the middle of studying buffer gap implementations, so I can fully understand what I need to do.

 

-Thom

Link to comment
Share on other sites

Doing hex output is easy given that it's directly related to powers of 2, but of course not real user-friendly.

 

For most applications it's just easier to do calculations in BCD which is easy to convert and output. Some games in fact just work directly with ASCII or even screen codes.

Binary not necessarily as useful as you'd think - additional to the pain of converting to decimal, you don't get much range with only a 16-bit value. So really it's just easier to use 3 bytes worth of BCD which gives a 1 million range. It's only if you're dealing with big arrays of data that you'd worry about the storage disadvantage.

Link to comment
Share on other sites

I would venture that if you want to have a status line in a text editor showing things like file position, row and column and free RAM constantly updated after every keystroke and redraw of the screen (the latter usually being expensive enough in itself), calling the OS FP pack to generate integer strings isn't the best use of machine cycles.

What I mainly mean is that the slowness of the FP package is often greatly (or even grossly) overestimated. Roughly estimating, a call to IFP/FASC occupies about 30 scanlines - not specially fast, but at the other hand, how many times per second one needs to do that conversion? After a keystroke it would not be noticeable, and why it should be called after every screen redraw, I cannot see.

 

But even if, IFP/FASC is fast enough for most applications, and certainly it is not worth to waste RAM for a custom routine which is faster while 99% of the time the program spends waiting for a keystroke.

Link to comment
Share on other sites

I feel that if effort has been expended making the editor's screen redraw as efficient as possible, it's worth ensuring that re-displaying - say - four numbers after each keystroke (totalling 120 scan lines plus rendering overhead using your FP package estimate) doesn't introduce unnecessary lag. It's rather like the adage "look after the pennies and the pounds will look after themselves", which is to say that if the worker routines (display, number conversion) are kept efficient, code which repeatedly calls this stuff from higher up will stay responsive.

 

In addition, my perception is that it seems wasteful to convert an integer to FP, then an FP value to a string when all we want to do is display an 8 or 16-bit integer value. I realise that saving cycles isn't the only concern, but a text editor is a good example of an application which does a sufficient amount of heavy redrawing that it's wise to spend a lot of time optimising anything which might introduce unnecessary lag.

 

EDIT: Another bonus when using the table approach is that you can employ a couple of simple flags and get leading zeros and/or right justification for free, while with the INT/FP/ASCII conversion you need to scan the buffer to get the length of the string and then pad it after the event.

Edited by flashjazzcat
Link to comment
Share on other sites

This is only important when someone is truly short of the 84 free bytes at $80-$d3. It is not a problem in most programs, though.

 

I do realize that IFP/FASC is not the fastest, but my point is that its use is very simple (two jsr calls and you are done with the conversion) and really few programs are so time critical to need such a routine faster.

 

I may be wrong, but I think that even in a text editor in a really bad case when a keystroke causes the entire screen to be redrawn (inserting a character in the first line of the screen, which causes re-folding all the remaining lines being displayed) calling the IFP/FASC should not cause a noticeable effect, because hardly anyone can type more than 4-5 characters per second, and the IFP/FASC pair can do 500 conversions per second. So in any case most CPU time will be consumed by the screen redraw and only a tiny fraction of it by the numeric conversion through FP.

 

PS. Speaking of folding: why the AAge reply field does not fold lines? It is a bit annoying.

Edited by drac030
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...