TRS-80 printf() behavior

Discussion about other targets
Post Reply
Calphool
Member
Posts: 13
Joined: Fri May 31, 2019 2:21 pm

TRS-80 printf() behavior

Post by Calphool »

Hello,

I'm puzzling a bit over the TRS-80's printf() implementation. I'm guessing this probably applies to whatever lower level functions printf() is using as well... Basically it *appears* that printf() isn't keeping the TRS-80's cursor location RAM addresses up to date. That wouldn't be a big deal, but it causes weird behavior when your code exits if you've got stuff on the screen that you intend to stay on the screen when you go back to DOS. The classic example would be a command line utility. Basically, since the cursor position RAM locations aren't up to date (addresses 0x4020 and 0x4021), when you exit and return to DOS, DOS stomps over whatever is on the screen at the time instead of gracefully giving you a prompt just below the last thing your program printed.

I was able to hack around this issue by changing trs80_crt0.asm to add these lines in the cleanup: block.

Code: Select all

       push    hl
        ld      hl, $3f00   ; put cursor toward bottom of screen
        ld      ($4020), hl
        pop     hl
This is however a hack, because it causes the cursor to always be around the 12th line down the screen, even if your program just put one line of text on the screen. Normal behavior for a C compiler would be for the cursor to be at the end of the last line printed.

I guess another way to do it would be in the cleanup: routine to examine the contents of the screen buffer, and place the cursor at the line immediately following the lowest non-whitespace thing on the screen. I guess this would still be sort of a hack, since it's non-standard behavior (what if the last thing I did was put the cursor in the middle of the screen with my printf, but there was already stuff below the middle?) Still, it would be better than current behavior, less hacky than the thing above, and wouldn't require diving deeply into the printf() implementation.

My assembler skills are a little rusty, but I'll see if I can figure out how to do that... Stay tuned if you're targeting TRS-80.
Calphool
Member
Posts: 13
Joined: Fri May 31, 2019 2:21 pm

Post by Calphool »

Okay, well, this code works... it's a change to trs80_crt0.asm. Not altogether sure how to submit it as a pull request.

Code: Select all

cleanup:



find_bottom_character_on_screen:
        push    de          ; defensive programming...
        push    hl          ; defensive programming...
        push    bc          ; defensive programming...
        push    af          ; defensive programming...

        ld      de, $3c00   ; set DE to the top of screen -- DE will contain last position with data
        ld      hl, $3c00   ; set HL to the top of the screen

crslp:  and     a           ; clear flags
        ld      a,(hl)      ; load whatever is sitting at address in HL to A register
        ld      b,$21       ; load b register with 0x21
        cp      b           ; subtract b from a and set flags without changing a
        jp      c,isspce    ; jump if it's a space
        ld      d,h         ; since it's not a space, move HL to DE (yeah, probably a better way... I'm rusty, okay?)
        ld      e,l
isspce:
        inc     hl          ; move HL forward one byte on the screen
        and     a           ; clear flags
        ld      bc,$3fff    ; load BC with the end of the screen location
        sbc     hl,bc       ; subtract HL and BC setting flags
        jr      z,endOfScreen  ; HL is at the end of the screen?
        jp      crslp       ; nope, jump to top, keep scanning screen
endOfScreen:
        ld      ($4020),de  ; load DE's contents into cursor location address
crsdone:
        pop     af          ; defensive programming...
        pop     bc          ; defensive programming...
        pop     hl          ; defensive programming...
        pop     de          ; defensive programming...
Calphool
Member
Posts: 13
Joined: Fri May 31, 2019 2:21 pm

Post by Calphool »

Well, strike that... it works okay in an emulator (sdltrs), but not in real hardware... not sure what to do at this point.
User avatar
dom
Well known member
Posts: 1195
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I've just merged some code to copy the "C generic console cursor" position to the OS cursor position on exit. Could you can test tomorrow on real hardware and let me know how it goes?
Post Reply