General Category > LisaList2

Problems With The Boot ROM "Display Message" Routine

(1/2) > >>

AlexTheCat123:
Over the past few days, I've been trying to familiarize myself with 68K assembly language for a couple of Lisa-related projects that I want to undertake in the future and on the whole it's been going pretty great so far! I've just been messing around and doing things like filling the entire screen with black or white and beeping the speaker and all of that is working great, but then I decided to do something a little more complicated and I'm running into some problems.

I'm trying to write a program that fills the entire screen with white and then prints a string repeatedly (with a space in between repetitions of the string so that they don't all run together) until every row and column is full. The code to clear the screen and count the number of characters in the string to determine how much to advance the cursor after each printing seems to be working great, but I'm having a weird problem with the code that actually prints the stuff on the screen. I'm using the "Print Message" routine that's built into the ROM, which expects a pointer to the null-terminated string in A3, the row number in D5, and the column number in D6. I think it also expects the address of screen memory to be stored in $110. The first time that it gets called, everything works fine, but whenever the program tries to call it again with a new row and/or column number to print another occurance of the string, nothing happens.

I originally thought that something was wrong with my loop that prints multiple occurances of the string in each row, but the EASy68K simulator seemed to show that the loop was working exactly as expected, so I figured that it had to be something else. I decided to write a simple program that just prints the string at row 0, column 1 and then at row 0, column 7 without any loops or other weirdness and, to my surprise, the exact same thing happened: the first string was printed, but the second occurance was not.


--- Code: ---MESSAGE EQU $FE0088 ;The address of the message routine in the ROM
SCREENBASE EQU $F8000 ;The base address of the screen memory
SCREENLOCROM EQU $110 ;Where the message routine can expect to find a pointer to the screen memory base address
MSGLOC EQU $86C ;The location of the string in memory

    ORG    MSGLOC ;Put the message in the desired location
    DC.B 'MEOW',0 ;I really like cats, so of course the string is cat-related!
    ORG    $0800 ;Program starts at $800

START:
     MOVEA.L #MSGLOC,A3 ;Load A3 with the pointer to our string
     MOVE.L #$0,D4 ;Zero out D4; it's only used if we have a string with a CR in it
     MOVE.L #SCREENBASE,SCREENLOCROM ;Put the screen base address in $110
     MOVE.L #$0,D5 ;Select row 0
     MOVE.L #$1,D6 ;and column 1 for the first printing of our string
     JSR MESSAGE ;Go print the string
     MOVE.L #$0,D5 ;Now select row 0
     MOVE.L #$7,D6 ;and column 7 for the second printing
     JSR MESSAGE ;Print it again
     BRA DONE ;And go into an infinite loop when done

DONE:
    BRA DONE ;Infinite loop

--- End code ---

This is a really strange and confusing problem. Am I missing something obvious here?

stepleton:
I didn't look too closely, but don't forget that there's only one set of registers, and MESSAGE has to use them, too. You've set D5 and D6 to the new screen location for the second round of printing, but what might MESSAGE have done with A3 when you called it the first time?  :)

D.Finni:
General note: whenever you use MOVE.L #$0, you can use MOVEQ instead. This instruction clears the entire long word.

My question: do you need to reset A3 before you call MESSAGE again?

rayarachelian:
My guess, and it's just a guess, would be that the DSPMSG subroutine that gets called likely clobbers some of the parameters, so on the 2nd call, it won't do it again. I'd try to reload those regs, such as A3 before the call.

From what I do see, this opcode does in fact increment A3, so it would wind up at the NUL byte after "MEOW" the 2nd time around:


--- Code: ---370E| 101B                          MOVE.B  (A3)+,D0                ;get a char to display

--- End code ---



--- Code: ---
3700|                       ;---------------------------------------------------------------------------
3700|                       ; Subroutine to display message on screen.
3700|                       ; Requires inputs:
3700|                       ;       A3 - ptr to ASCII character string ended by 0 byte
3700|                       ;       D4 = left margin if message has a CR
3700|                       ;       D5 = cursor row position (0 - 32 decimal)
3700|                       ;       D6 = cursor column position (1 - 88 decimal)
3700|                       ; Uses regs:
3700|                       ;       D0 - for character to display
3700|                       ;
3700|                       ; NOTE: ONLY UPPER CASE ALPHA, NUMERIC AND CERTAIN SPECIAL CHARS SUPPORTED!
3700|                       ;---------------------------------------------------------------------------
3700|
3700| 2F00                  DSPMSG  MOVE.L  D0,-(SP)                ;save reg
3702|
3702|                               .IF     ROM4K = 0
3702| 0C45 014C             @1      CMPI    #LASTROW,D5             ;check if out of bounds
3706| 6F04                          BLE.S   @2                      ;skip if OK
3708| 6100 F3FE                     BSR     SCROLL                  ;else scroll page
370C|                               .ENDC
370C|
370C| 4280                  @2      CLR.L   D0                      ;clear for use
370E| 101B                          MOVE.B  (A3)+,D0                ;get a char to display
3710| 6704                          BEQ.S   DSPDONE                 ;exit if done
3712| 6126                          BSR.S   DSPVAL                  ;go do display
3714| 60EC                          BRA.S   @1                      ;continue until done
3716| 201F                  DSPDONE MOVE.L  (SP)+,D0                ;restore and exit
3718| 4E75                          RTS

--- End code ---

AlexTheCat123:
Thanks guys! Reloading A3 with the pointer to the string did the trick. I guess I should have looked at the ROM code more closely! I thought that the comments in the ROM code would always tell you which registers, if any, are trashed as a result of calling a routine, but I guess that's not the case for the message display routine.

Navigation

[0] Message Index

[#] Next page

Go to full version