LisaList2

Advanced search  

News:

2022.06.03 added links to LisaList1 and LisaFAQ to the General Category

Pages: [1]   Go Down

Author Topic: Problems With The Boot ROM "Display Message" Routine  (Read 4106 times)

AlexTheCat123

  • Sr. Member
  • ****
  • Karma: +59/-0
  • Offline Offline
  • Posts: 196
Problems With The Boot ROM "Display Message" Routine
« on: April 18, 2022, 02:42:58 pm »

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: [Select]
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

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

stepleton

  • Sr. Member
  • ****
  • Karma: +109/-0
  • Online Online
  • Posts: 384
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #1 on: April 18, 2022, 04:25:18 pm »

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?  :)
Logged

D.Finni

  • Sr. Member
  • ****
  • Karma: +37/-0
  • Offline Offline
  • Posts: 135
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #2 on: April 18, 2022, 04:29:32 pm »

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?
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +101/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #3 on: April 18, 2022, 04:51:57 pm »

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: [Select]
370E| 101B                          MOVE.B  (A3)+,D0                ;get a char to display


Code: [Select]

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
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

AlexTheCat123

  • Sr. Member
  • ****
  • Karma: +59/-0
  • Offline Offline
  • Posts: 196
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #4 on: April 18, 2022, 05:10:13 pm »

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.
Logged

sigma7

  • Administrator
  • Sr. Member
  • *****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 310
  • Warning: Memory errors found. Verify comments.
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #5 on: April 18, 2022, 06:26:10 pm »

Code: [Select]
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
...
MOVE.L #SCREENBASE,SCREENLOCROM ;Put the screen base address in $110

FYI & HTH: ScreenBase varies according to the amount of RAM in the machine, so you probably don't want to change it from what was already in $110
Logged
Warning: Memory errors found. ECC non-functional. Verify comments if accuracy is important to you.

AlexTheCat123

  • Sr. Member
  • ****
  • Karma: +59/-0
  • Offline Offline
  • Posts: 196
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #6 on: April 18, 2022, 06:29:04 pm »

Quote
FYI & HTH: ScreenBase varies according to the amount of RAM in the machine, so you probably don't want to change it from what was already in $110

Thanks for letting me know! I didn't know that the Lisa automatically puts the screen base address there; I thought that you had to do it manually.
Logged

sigma7

  • Administrator
  • Sr. Member
  • *****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 310
  • Warning: Memory errors found. Verify comments.
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #7 on: April 18, 2022, 06:51:47 pm »

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

Another obscure reason to use MOVEQ...

68K assemblers will sometimes optimize <MOVE.s #0, ea> into <CLR.s ea> to save bytes.

(Where .s is the data size [.B, .W, .L] and ea represents the effective address)

However, there is a 68000 quirk with the CLR instruction in that it will read from the target address before writing 0.

In most cases this is harmless (although it takes more cycles), but in cases where one is accessing hardware, sometimes that dummy read can have unexpected consequences (such as generating an unintended handshake pulse -- as can be observed when the ROMs ProFile code loads boot blocks, or potentially discarding data from the SCC FIFO, etc.).

<SF.B ea> operates the same as <CLR.B ea> and also reads before writing.

So, using <MOVEQ #0, ea> may be helpful to minimize code space, maximize speed, and avoid obscure bugs.
Logged
Warning: Memory errors found. ECC non-functional. Verify comments if accuracy is important to you.

AlexTheCat123

  • Sr. Member
  • ****
  • Karma: +59/-0
  • Offline Offline
  • Posts: 196
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #8 on: April 18, 2022, 08:09:45 pm »

Quote
So, using <MOVEQ #0, ea> may be helpful to minimize code space, maximize speed, and avoid obscure bugs.

Good to know! Thanks for all the help guys!
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +101/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Problems With The Boot ROM "Display Message" Routine
« Reply #9 on: April 19, 2022, 09:34:16 am »

Quote
FYI & HTH: ScreenBase varies according to the amount of RAM in the machine, so you probably don't want to change it from what was already in $110

Thanks for letting me know! I didn't know that the Lisa automatically puts the screen base address there; I thought that you had to do it manually.

To clarify this a bit, the display is set to the highest available RAM-32K since the screen size is 32K. Also note that it's set to the physical RAM page, which can differ from the MMU mapping should the running OS choose to do that.

But the Boot ROM itself will set the all RAM in context 0 (seg1=0, seg2=0) to be continuous and then the very last 32KB is set to the video display page. Note that MMU context 0 is special as well. When supervisor mode is turned on due to a trap, or any transition to supervisor mode, the MMU context automatically switches to context 0.

There are also context 1,2,3 which you can get by playing with seg1, seg2 - these are used for when the CPU is in UserMode, however the Boot ROM does not set these up, so your OS needs to set them up.

There is a special SETUP mode which allows you to setup the MMU, this is enabled or disabled through two latches, just like seg1, seg2. however, you have to be careful because not all memory is available in SETUP mode and it's kind of tricky. The Boot ROM is mapped in SETUP mode, so its MMU setup routines are available, which means you can use those addresses to setup contexts 1-3 if you want, though some RAM is also available that way.

Another thing to know is that all of these latches, seg1, seg2, setup, as well as the soft/hard memory error latches can be turned on by just *reading* from memory! This is some sort of cost cutting method that the Lisa engineers did. If you read from one address, you enable a latch, but if you read from the other address associated with that latch, you turn it off. So yes, even reads can behave like writes!

Another thing to know is that in contexts 1-3, it's possible to have a program that starts at address zero - infact UniPlus and Xenix do exactly that. Now, normally interrupt vectors live in low memory, however this is not the case when you're in User mode on the Lisa. You can map memory to this space, and put a program at 0.

When an interrupt or exception occurs, because of the switch to supervisor mode during exception/interrupt processing, the CPU will switch to supervisor mode, which automatically then switches to context zero, handle the exception processing, and then when it exits supervisor mode, it will return to the original MMU context, allowing that user mode program to continue.

(This also means that when doing process scheduling, you should store the current process's context number somewhere so you can schedule between contexts 1,2, and 3 if you're doing pre-emptive multitasking - and you can use one of the VIA timers to drive pre-emptive multi-tasking. However, if you're just doing interrupt handling, you don't need to worry about it, because at the end of the RTE, it will return to whatever process in whatever context it was running in, and you can do either TRAP, or A-Line, or F-Line handling without issue. Normally A-LINE traps are allowed, but F-Line traps are reserved for a PMMU or FPU. But the Lisa does not support these, so it's possible to also use F-Line traps as well on a Lisa - example, I use them inside of LisaEm to handle High Level Emulation code.)

Weirdly enough the CLR opcode does both a read and a write, but luckily if you use it against these latches it won't cause issues since it will do both a read and a write and since the address is the only thing that matters for these latches, it won't hurt anything. But as @sigma7 mentioned, the CLR opcode should never be used with I/O as that will access the same address 2x and this will cause issues for things like VIA6522s.

(Perhaps the CLR and SF.b opcodes might be used in a multiprocessor system as some kind of semaphore/locking mechanism by doing a read before a write if you setup a latch on the bus the right way, not sure, but this won't apply to the Lisa since it has a single CPU, but might have been useful for something like the Big Little Machine. In general though, an increment is used for semaphore locking in most unixy system rather that set/clear.)

These bits of info are useful for when you decide to write your own OS from scratch. Hint, hint.
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code
Pages: [1]   Go Up