Lisa_Boot_ROM_RM248
.PAGE
.IF EXTERNAL = 1
.LIST
.ENDC
.IF USERINT = 1
;**********************************
; Mini-Graphics Package *
; Contributed by Mike Urquhart *
; Copyright 1983, 1984 Apple *
;**********************************
;________________________________________________________________________________
;
; DRAWDESK:
;
; this routine performs the following sequences:
;
; 1. clears the screen to a white background.
; 2. makes a menu bar by drawing a single pixel horizontal
; line across the screen.
; 3. fills the screen area below the menu bar with the stantard
; gray shade.
;
; Also has an entry point called CLRDESK that only does item (3).
;
; Destroys regs D0-D2,A1,A5-A6
;________________________________________________________________________________
;
; 1. clear screen to white background
DRAWDESK
clr.l d2
bsr.s whiten
;
; 2. make menu bar border
CLRDESK moveq #ROWBYTES,d0 ;set length of line = 90 bytes
moveq #-1,d2 ;draw a black pattern
move.w #MENULINE,A1 ;start at offset 1440 address
moveq #1,d1 ;draw only 1 pixel line
bsr.s paint_box
;
; set a6 to starting pixel address for grey routine below
; set a5 to limit
;
move #DESKLINE,a6
move #DESKLMT,a5 ;set limit
;
; 3. make the grey background: to make the gray background, alternating
; rows of $5555 and $AAAA starting with $AAAA are written to the
; screen area.
;
gray MOVE.L #DESKPATRN,D2 ;set up grey pattern
gray1 swap d2 ;start with the $AAAA pattern
moveq #1,d1 ;draw a one pixel high line
move.l a6,a1 ;starting pixel address must be in a1 for call
bsr paint_box
@1 add d0,a6 ;bump to next pixel line
cmp.w a5,a6 ;is a6 less then max?
blt.s gray1 ;loop if yes
rts ;else done
;_________________________________________________________________________
;
; subroutine blacken and whiten: clears full screen to black or white
;
; Calls: bsr blacken (no parameters)
;
; clr.l d2
; bsr whiten
;
; registers used: d2.l - contains either FFFFFFFF or 0 on return
; d0.b - destroyed but contains $5A (90) on return
; d1.w - destroyed-->should contain 0 on return
; a1.l - destroyed
;
;
; This routine calls paint_box, so other registers may be destroyed.
;
;
;_________________________________________________________________________
BLACKEN
moveq #-1,d2 ;black fill pattern
whiten
move.w #MaxY-1,d1 ;number of pixels in screen box heigth
moveq #ROWBYTES,d0 ;length of screen box is 90 bytes
suba.l A1,A1 ;clear A1
bsr.s paint_box
rts
;------------------------------------------------------------------------
; Subroutine to clear only menu bar on desktop
; Inputs:
; None
; Outputs:
; None
; Side Effects:
; None
;------------------------------------------------------------------------
CLRMENU MOVEM.L D0-D2/A1,-(SP) ;save regs
MOVEQ #ROWBYTES,D0 ;width of menu bar is 90 bytes
MOVEQ #MBARLEN,D1 ;heigth is 15 pixels
MOVEQ #0,D2 ;set fill pattern
SUBA.L A1,A1 ;upper left corner is at offset 0
BSR.S PAINT_BOX ;go do it
MOVEM.L (SP)+,D0-D2/A1 ;restore and
RTS ; exit
;________________________________________________________________________________
;
; Routine paint_box
;
; Call: BSR paint_box
; or
; BSR paintb2
;
; register setup:
;
; D2 must contain a one word fill pattern.
; D0 must contain the width of the box(horizontally) or the length of
; the line.
; D1 must contain the heigth(vertically of the box) in horizontal pixel
; rows:
; A1 must contains the screen displacement in the range 0..32670
;
; __________________________________
; . .
; . fill pattern . <-------heigth in pixels
; __________________________________
; ^
; ........... length horizontally
;
; Assumptions: location SCRNBASE contains the video address
;
; registers used-->D0-D3,A0-A2
;________________________________________________________________________________
PAINT_BOX
paintb1 lea movinst,A4
bra.s cont
inverse lea exclusive,A4
cont ADD.L SCRNBASE,A1 ;add video address to starting pixel address offset.
paintb2
MOVE.L A2,-(SP) ;save reg
; do some setup steps
;
CLR.L D3 ;clear for use
MOVE.W D0,D3 ;modify width/length
NEG.l D3 ;negate the width/length (D3 = -width/length)
;
; add the length of one horizontal pixel row-2 to the -width/length
; to derive an offset which can be added to the updated address pointer
; (when it reflects the right corner or end point of the box/line)
; in order to arrive at the next row starting address.
;
ADDI.l #ROWBYTES,D3 ;create displacement for following sequence
;
;
;
MOVE.L A1,A2 ;create ending column check address
ADD.L D0,A2 ;add length of line to obtain ending column address
;
; A1 now points to the left top coordinate of the box or line.
; A2 now points to the right top coordinate of the box or line.
;
startop
jmp (A4) ;execute the correct operation (EOR or MOVE)
movinst
MOVE.w D2,(A1)+ ;start the sequence
bra.s compare
exclusive
eor.w D2,(A1)+
compare CMP.L A1,A2 ;reached the right most point?
BEQ.S nextline ;yes
BRA.S startop
;
; YES
;
nextline
ADD.L D3,A1 ;add 1 horizontal line length (5A) minus line length
ADDA #ROWBYTES,A2 ;to reach the left most point of the box on the RM000
SUBQ.W #1,D1 ;next horizontal scan line.
BNE.S startop ;loop until done.
;
MOVE.L (SP)+,A2 ;restore and
RTS ;return
;------------------------------------------------------------------------
; Entry point to set cursor ptrs and make alert box for power cycling
;------------------------------------------------------------------------
MAKEPCALRT
MOVEQ #PCROW,D5 ;set row ptr
MOVEQ #PCCOL,D6 ;and col ptr
;then drop into alert box routine
;________________________________________________________________________
;
; MAKEALERT
;
; This routine creates an alert box with no title.
;________________________________________________________________________
MAKEALERT
movem.l d0-d1/a1,-(sp)
MOVEQ #ALRTWIDTH,D0 ;set parameters for box
MOVE.L #ALRTHIGH,D1
MOVEA #ALRTSTRT,A1
bsr.s makebox
movem.l (sp)+,d0-d1/a1
rts
;________________________________________________________________________
;
; MAKETEST
;
; This routine creates an alert box for test icon display.
;________________________________________________________________________
MAKETEST
movem.l d0-d1/a1,-(sp)
MOVEQ #TSTWWIDTH,D0 ;set parameters for alert box
MOVEQ #TSTWHIGH,D1
MOVEA #TSTWSTRT,A1
BSR.S MAKEBOX ;go draw box
MOVEQ #TSTMROW,D5 ;set cursor ptrs
MOVEQ #TSTMCOL,D6
LEA CHKMSG,A3 ;set message ptr
MOVEQ #-1,D1 ;append '...' string
BSR DSPSTRING ;and go display it
BSR DSPCPU ;display test icons
BSR DSPIOB
BSR DSPMBRD
BSR DSPXCRD
movem.l (sp)+,d0-d1/a1
rts
;________________________________________________________________________
;
; MAKEDBOX
;
; This routine creates a dialog box.
;________________________________________________________________________
MAKEDBOX
movem.l d0-d1/a1,-(sp)
MOVEQ #DBOXWIDTH,D0 ;set parameters for dialog box
MOVEQ #DBOXHIGH,D1
MOVEA #DBOXSTRT,A1
bsr.s makebox
movem.l (sp)+,d0-d1/a1
rts
;________________________________________________________________________
;
; routine makewindow
;
; This routine creates a fixed window of the folder type.
; The calling routine must provide the address of the
; string which will be used to fill in the title box.
;
; Call:
; move ,d0
; move ,d1
; move ,a1
; lea ,a3
; bsr makewindow
;
; This routine calls makebox
;
;________________________________________________________________________
MAKEWINDOW
movem.l d0-d1/a1,-(sp)
bsr.s makebox
;
; now draw the title box by drawing a single black line across
; the width of the window about 17 pixels from the top edge
;
MOVE.L A1,-(SP) ;save start point
add.w #MENULINE,a1
moveq #1,d1 ;set heigth of one pixel
moveq #-1,d2
bsr.s paint_box
MOVE.L (SP)+,A1 ;restore start point
bsr writetitle
movem.l (sp)+,d0-d1/a1 ;restore and return
rts
;________________________________________________________________________
;
; Routine makebox;
;
; This routine creates a window of either the folder type
; or the dialog box type. Is is the responsibility of
; the calling process to append the title box and title
; to the window if it is the folder type.
;
; Call:
; move.w ,d0 (range 0..90) even
; move.w ,d1 (range 0..364)
; move.w ,a1 (range 0..32670)
; bsr makebox
;
; registers used: d0,d1,d2,d3,d4,a1,a2
;________________________________________________________________________
MAKEBOX
;
; make the basic window--->no edges D2 must be set to 0 on call
; d0 must be set to the width (90 maximum)
; d1 must be set to the heigth (364 maximum)
; A1 must be the offset address (0..32670)
;
;
movem.l d0-d4/a1-a4,-(sp)
movem.l d0-d1/a1,-(sp) ;save the heigth and the starting pixel address
clr.l d2 ;the pattern
bsr paint_box
;
; now draw the individual edges including the shadow edges on the right
; and bottom of the window
;
;
; draw bottom horizontal edge
;
sub.l d3,a1
sub.l d0,a1 ;a1 is currently equal to the lower right point
; of the box so we can subtract the width to
; calculate the lower left point of the box.
moveq #1,d1 ;set 1 pixel heigth
moveq #-1,d2 ;set the line pattern
bsr paintb2 ;remember a4 is set up to point to the move.w
; instruction
;
; draw bottom horizontal shadow
;
@1 addq #2,a1 ;shadow begin offset by 2
moveq #1,d1 ;draw a one pixel line
subq #2,d0
bsr paintb2 ;go
;
; draw top horizontal edge
;
@2 movem.l (sp)+,d0-d1/a1 ;restore original parameters
movem.l d1/a1,-(sp)
moveq #1,d1 ;draw a 1 pixel line
bsr paint_box
;
; now draw the right edge plus the right edge's shadow, use a1
; with a column parameter of 0
;
movem.l (sp)+,d4/a2
moveq #1,d2
subq #2,d4
subq #2,d0
add.l d0,a1
move.l d4,d1
clr.l d0
bsr.s paint_v
move.w #182,d0 ;set one byte offset from right edge
moveq #7,d2
move.l d4,d1
bsr.s paintbit ;draw first pixel line of the right shadow
move.w #272,d0
moveq #6,d2
move.l d4,d1
subq #1,d1 ;reduce heigth by 1 to compensate for shadow offset
bsr.s paintbit
;
; now draw the left vertical edge of the box
;
move.l a2,a1 ;restore the starting pixel address
add.l SCRNBASE,a1 ;add in video address
moveq #90,d0
add.l d0,a1
move #32768,d2 ;set the pattern
move.l d4,d1 ;the heigth minus two
clr.l d0 ;column 0 offset
bsr.s paint_v
movem.l (sp)+,d0-d4/a1-a4
rts
;_________________________________________________________________________
;
; Routine paint_v
;
; This routine "paints" a vertical column one word wide.
;
; Call: BSR paint_v
;
; register setup:
;
; A1 must contain the screen base address.
; D2 must contain a one word pattern.
; D1 must contain the number of pixels in the vertical length of the line
; in the range 1..364
; D0 must contain the screen word column in the range 0..44
;
; Assumptions: location SCRNBASE contains the video address
;
; registers used: D0-D1
;________________________________________________________________________
;
PAINT_V
paintv1
@1 MOVE.W D2,0(A1,D0.W) ;write to screen
SUBQ.W #1,D1 ;decrement count
BEQ.S @2 ;return
ADDI.W #ROWBYTES,D0 ;bump to next horizontal line
BRA.S @1 ;loop to continue writing vertical.
;
@2 RTS ;return
;_________________________________________________________________________
;
; Routine paintbit
;
; This routine "paints" a vertical line one bit wide.
;
; Call: BSR paintbit
;
; register setup:
;
; A1 must contain the screen base address.
; D2 must contain the bit number to set
; D1 must contain the number of pixels in the vertical length of the line
; in the range 1..364
; D0 must contain the screen word column in the range 0..44
;
; Assumptions: location SCRNBASE contains the video address
;
; registers used: D0-D1
;________________________________________________________________________
PAINTBIT
@1 bset d2,0(a1,d0.w)
subq.w #1,d1 ;subtract one from heigth
beq.s @2 ;done
addi.w #ROWBYTES,d0 ;increment to next pixel row.
bra.s @1
@2 RTS ;return
;______________________________________________________________________
;
; Routine makebutton --> creates a black lined box of the size
; specified by the parameters with button
; "label" and description if specified.
; Also makes entries in active rectangle
; table for later use with mouse.
;
; the left top corner is addressed by a1,
; the alternate keycode is contained in d0.
; the description is in A3.
; description location is in A2.
; '...' string appended to message if d1 nonzero
;
;
; Call:
;
; move.w ,a1
; move.b ,d0
; lea ,a3
; move.l ,a2
;
; bsr makebutn
;
; Destroys regs D0-D2,D5,D6,A3
;______________________________________________________________________
MAKEBUTN
MOVEM.L D1/A2,-(SP) ;save string indicator and location ptr
LEA RectTable,A2 ;get ptr to active rect table
MOVE (A2),D2 ;get current count of rect's
MULU #5,D2 ;five entries per rect
ADD D2,D2 ;double for word index
ADDQ #1,(A2)+ ;incr for new rect
MOVE D0,0(A2,D2.W) ;save keycode id for new rect
BSR KeyToAscii ;convert keycode to Ascii
MOVE D0,D4 ;save for later display
; compute X,Y pixel coordinates from starting address
BSR GETROWCOL ;get pixel row, byte col
MULU #8,D6 ;convert to pixel col
MOVE D6,2(A2,D2.W) ;save upper left X
MOVE D5,4(A2,D2.W) ; and Y coordinates
MOVEQ #BTNWIDTH,D0 ;set button parameters
MOVEQ #BTNHIGH,D1
BSR.S DRAWBUTN ;draw the button
MOVE.L A1,-(SP) ;save original val
MOVE LwrRight,a1 ;compute lower right coordinates
BSR GETROWCOL ;get pixel row
MULU #8,D6 ;and pixel col
MOVE D6,6(A2,D2.W) ;save as X and
MOVE D5,8(A2,D2.W) ; Y coordinates
MOVE.L (SP)+,A1 ;restore starting value
; Add the button label and description
movem.l d0-d4/a1-a3,-(sp) ;save parameters
lsr.l #1,d0 ;divide window width
bsr getrowcol ;get the row and column coordinate of
;the window corner point
add.l d0,d6 ;adjust column pointer
lsr.l #1,d1 ;divide window heigth
subq.l #4,d1 ;decrement by half font heigth
add.l d1,d5 ;adjust row coordinate
SUBQ #1,D6 ;go back 1 and
CLR D0 ;display apple icon
BSR DSPVAL
MOVE.L D4,D0 ;get char to display
bsr dspval ;and go display alternate keycode
movem.l (sp)+,d0-d4/a1-a3 ;retrieve parameters
MOVEM.L (SP)+,D1/A2 ;retrieve location and string indicator
MOVE.L A2,A1 ;compute output pt for description
BSR GETROWCOL
BSR DSPSTRING ;and display it
RTS
;______________________________________________________________________
;
; Routine drawbutton --> creates a black lined box of the size
; specified by the parameters.
;
; the left top corner is addressed by a1,
; the width is indicated by d0.
; the heigth is indicated by d1.
;
;
; this routine calls paint_box, and paintbit.
;
; inputs: d0=window width in bytes (should be even)
; d1=heigth in pixels
; a1=window left/top corner point as a
; 0..32670 screen offset address.
;
; Call:
;
; move.w ,a1
; move.w ,d0
; move.w ,d1
; bsr drawbutn
;______________________________________________________________________
DRAWBUTN
movem.l d0-d4/a1-a3,-(sp) ;stack the arguments
;
;
; draw the top edge of the button
;
moveq #-1,d2 ;set the black bit pattern for paint_box
moveq #1,d1 ;set a 1 pixel line
bsr paint_box
;
; draw the right vertical edge of the button
;
sub.l d3,a1 ;on return from paint_box, a1 points to the
;real address of the left point of the next
;horizontal pixel line of the button, so d3,
;which contains the displacement to the prior
;lines right edge is added to the
;left point to obtain the correct
;address for the right edge.
move.l 4(sp),d1 ;momentarily restore the heigth
clr.l d0
moveq #7,d2 ;set the 1 bit mask for paintbit
bsr.s paintbit ;draw the right edge
;
; now draw the left edge of the button
;
move.l 20(sp),a1 ;restore the original corner point
add.l SCRNBASE,a1 ;add in the screen window address
move.l 4(sp),d1 ;restore the heigth
clr.l d0
moveq #7,d2 ;set the 1 bit mask for the left edge
bsr.s paintbit
;
; now draw the bottom edge of the button
;
add.l d0,a1 ;add the displacement to the corner point to arrive
;at the correct address of the bottom left corner
move.l (sp),d0 ;restore the width
moveq #1,d1 ;set the heigth at 1.
moveq #-1,d2 ;set the line pattern to black
bsr paintb2
;
; done - save lower right coordinate
;
sub.l d3,a1 ;get offset address for lower right corner
sub.l SCRNBASE,a1
move a1,LwrRight ;save it
movem.l (sp)+,d0-d4/a1-a3
rts
;____________________________________________________________________
;
; Routine to redraw the sides of a pulldown menu item.
;
; Call: move.w ,d0
; move.w ,d1
; move.l ,a1
; jsr inversmenuitem
;
;____________________________________________________________________
DRAWSIDES
movem.l d0-d1/a1,-(sp)
; redraw the left vertical edge of the pull down menu
add.l SCRNBASE,a1 ;add in the real video window address
moveq #7,d2 ;set the bit for paintbit
clr.l d0 ;remember to clear d0.
jsr paintbit
; redraw the right vertical edge of the pulldownmenu
move.l (sp),d0 ;restore the width
move.l 4(sp),d1 ;restore the heigth
add.l d0,a1 ;point the pixel address to the top edge of the right side
subq #1,a1 ;adjust address to point to byte with actual right edge
clr.l d0 ;remember to clear d0 on call.
clr.l d2 ;set bit
jsr paintbit
movem.l (sp)+,d0-d1/a1 ;restore the parameters
rts
;______________________________________________________________________
;
; MAKEMENU
; Displays pull down menu when called. Also makes
; entries in active rectangle table for each entry.
;
; Inputs: A1 = starting pixel address for menu "box"
; A2 = starting pixel address for menu option message
; A3 = ptr to menu strings
; A4 = ptr to menu id's
; D0 = menu "box" width
; D1 = menu "box" heigth
; D4 = # of menu entries
;
;______________________________________________________________________
MAKEMENU
MOVEM.L D0-D3/A0,-(SP)
.IF BMENU = 0
BSR MAKEBOX ;go make menu "box"
.ENDC
MULU #8,D0 ;convert width to pixel count
LEA RectTable,A0 ;get ptr to active rectangle table
MOVE (A0)+,D1 ;get rectangle count
CLR.L D2 ;clear for use
MOVE.L #MENUSPC,D3 ;space between menu entries
@1 ADDQ #1,D1 ;incr rectangle count
MOVE.B (A4)+,D2 ;get menu entry id
MOVE D2,(A0)+ ;save in table
BSR.S GETROWCOL ;convert address to X,Y coordinates
MULU #8,D6 ;convert to pixels
MOVE D6,(A0)+ ;save upper X coordinate
MOVE D5,(A0)+ ;save upper Y coordinate
ADD D0,D6 ;compute and save
MOVE D6,(A0)+ ; lower X coordinate
ADD #MENUSPC/90,D5 ;compute and save
MOVE D5,(A0)+ ; lower Y coordinate
MOVE.L A1,-(SP) ;save "box" address
MOVE.L A2,A1 ;get address for menu message
BSR.S GETROWCOL ;compute msg output pt
BSR DSPMSG ;do display
MOVE.L (SP)+,A1 ;restore address for box
ADD.L D3,A1 ;incr to next start pt for rectangle
ADD.L D3,A2 ;also incr message address
SUBQ #1,D4 ;loop until done
BNE.S @1
MOVE D1,RectCnt ;save new rectangle count
MOVEM.L (SP)+,D0-D3/A0 ;restore regs and exit
RTS
;______________________________________________________________________
;
; routine writetitle --> writes the title for the window whose
; left top corner is addressed by a1,
; whose width is indicated by d0.
;
; To arrive at the correct address to write the title string,
; the window width and string length must be divided by 2, the
; result of the string division is subtracted from the width
; division to arrive at the general byte column position to
; begin writing the title.
;
;
; inputs: d0=window width
; a1=window left/top corner point as a
; 0..32670 screen offset address.
; a3=title string address
;
; output: all registers used are restored.
;______________________________________________________________________
WRITETITLE
movem.l d0-d6/a0-a6,-(sp) ;save as many registers as possible
bsr.s getlength ;calculate the length of the string
lsr.l #1,d0 ;divide window width
lsr.l #1,d2 ;divide string length
sub.l d2,d0 ;1/2 width - 1/2 length --->d0
bsr.s getrowcol ;get the row and column coordinate of
;the window corner point
addq #4,d5 ;adjust for 4 pixel rows
add.l d0,d6 ;adjust column pointer
movem.l d5/d6,-(sp) ;stack line/column pointers for later ref
bsr dspmsg
movem.l (sp)+,d5/d6 ;restore the parameters
subq #4,d5 ;reduce the pixel pointer by 4
subq #2,d6 ;backspace the column pointer by 2
andi.w #$FFFE,d6 ;round off to nearest word
sub.l a6,a6 ;clear a6
bsr setcrsr2 ;convert standard row/col to pixel offset
move.l a6,a1 ;move to a1
;
; restore the string pointer so that its length can be recalculated.
;
move.l 40(sp),a3
bsr getlength ;the length is returned in a2 and d2
addq #1,d2 ;must round off the length to a word boundary
andi.w #$FFFE,d2
move.l d2,d0 ;set width of inverted window to length..
addq #4,d0 ;..of string plus 4
moveq #15,d1 ;set the heigth of the window
moveq #-1,d2 ;set the mask
bsr inverse ;invert the title
movem.l (sp)+,d0-d6/a0-a6
rts
;______________________________________________________________________
;
; routine getrowcol --> converts a screen address displacement
; to row and column coordinates.
;
; inputs: a1=screen address in the range 0..32759
; outputs: d5 set to row
; d6 set to byte col (the remainder)
;
; registers used: d2 (but saved and restored)
; registers destroyed: d5,d6 (set to new values)
;______________________________________________________________________
GETROWCOL
move.l d2,-(sp) ;save d2
move.l a1,d2 ;move the address to d2
divu #ROWBYTES,d2 ;divide the address by 90 bytes
move d2,d5 ;new row
swap d2
move.w d2,d6 ;remainder is column
; MOVE.L A1,D2 ;now calculate row
; SUBI.L #TOPOFFSET,D2 ;decr for offset
; DIVU #RBYTES,D2 ;divide by bytes per char row
; MOVE D2,D5
; ADDQ #1,D5 ;incr to next row
move.l (sp)+,d2 ;restore d2
rts ;return
;______________________________________________________________________
;
; routine getlength --> returns a value which is the length of
; the string referenced by a3. The
; string is assumed to be terminated by
; the null character value.
;
; inputs: a3=string address
; outputs: d2,a2: string length
;
; registers destroyed: d2,a2 (set to new values)
;______________________________________________________________________
GETLENGTH
move.l a3,a2
@1 move.b (a2)+,d2 ;read a byte
bne.s @1 ;continue
sub.l a3,a2 ;subtract the beginning from the end.
move.l a2,d2 ;move it to d2 for reference
rts ;return
;---------------------------------------------------------------------
;
; Routine to display uncompressed icon. CHG008
;
; INPUTS:
; A2 = pointer to uncompressed icon (48 x 32 bitmap)
; A6 = pointer to (even!) screen address for upper left hand
; corner of icon
; SIDE EFFECTS:
; D0-D1 are trashed
;---------------------------------------------------------------------
DSPRGICON
MOVEQ #ICONWIDTH-1,D0 ;set default width CHG008
MOVEQ #ICONHIGH-1,D1 ; and heigth CHG008
BSR.S OUTPUT ;and do display CHG008
RTS ; CHG008
;______________________________________________________________________
;
; Subroutine to display message or icon.
;
; The calling routine must provide the pointer to the raw bit map.
;
; Call: load d0 with number of bytes - 1 in the x axis
; load d1 with the number of pixels - 1 in the y axis
;
; lea sourcebytes,a2
; lea destination,a6
; jsr or bsr output
;
; Returns with d6 updated.
;
;----------------------------------------------------------------------
OUTPUT
MOVEM.L D2-D4/A6,-(SP) ;save regs
moveq #90,d3
loop0 clr.l d4
move.w d0,d2
bra.s loop2
loop1 addq #1,d4
loop2 move.b (a2)+,0(a6,d4)
dbf d2,loop1
add.l d3,a6
dbf d1,loop0
addq #1,d6
MOVEM.L (SP)+,D2-D4/A6 ;restore
rts
.PAGE
;---------------------------------------------------------------------
;
; Routine to display error icon with id #.
;
; INPUTS:
; D1 = id # to display
; A2 = pointer to compressed icon
; A5 = upper left corner address for icon as
; offset from screen address
;
; SIDE EFFECTS:
; D5-D6 are trashed
;---------------------------------------------------------------------
DSPNUMICON
BSR DSPALRTICON ;display the icon
MOVE #ERRSTRT,A5 ;get icon address offset
BSR.S DSPNUM ;display id # on icon
ADD.L SCRNBASE,A5 ;get screen address
BSR DSPBAD ;display bad mark over icon
RTS
;---------------------------------------------------------------------
;
; Routine to display icon id #.
;
; INPUTS:
; D1 = id # to display
; A2 = pointer to compressed icon
; A5 = upper left corner address for icon as
; offset from screen address
;
; SIDE EFFECTS:
; D1/D5-D6/A2-A3 are trashed
;---------------------------------------------------------------------
DSPNUM MOVE.L D0,-(SP) ;save reg
MOVE.L A5,A1 ;convert icon address to row, col
BSR GETROWCOL
LEA XCARD,A3 ;slot card icon?
CMPA.L A2,A3
BNE.S @1 ;skip if not
ADD #SLOTROW,D5 ;add offsets for card id to cursor ptrs
ADDQ #SLOTCOL,D6
BRA.S @6
@1 LEA MEMBRD,A3 ;memory board?
CMPA.L A2,A3 ;
BNE.S @2 ;skip if not
ADD #MEMROW,D5 ;add offsets for card id
ADDQ #MEMCOL,D6
BRA.S @6 ;and go display
@2 TST.B SYSTYPE ;Lisa 2 system? CHG009
BNE.S @99 ;exit if yes - no id #'s CHG009
LEA DISKETTE,A3 ;diskette icon?
CMPA.L A2,A3
BNE.S @3
ADD #DISKROW,D5 ;compute posn for id #
ADDQ #DISKCOL,D6
BRA.S @6
@3 LEA DRIVEN,A3 ;drive icon? CHG009
CMPA.L A2,A3 ; CHG009
BNE.S @4 ;skip if not CHG009
ADDQ #DRVROW,D5 ;add offsets for id # CHG009
ADDQ #DRVCOL,D6 ; CHG009
BRA.S @6 ;and go display CHG009
@4
SUBQ #INSRTROW,D5 ;must be insert icon CHG009/CHG024
ADDQ #INSRTCOL,D6 ; CHG009
@6 BSR SETCRSR ;get screen address in A6
SUBQ #1,D1 ;check number to display
BNE.S @7
LEA ONE,A2 ;set ptr to # icon
BRA.S @9
@7 SUBQ #1,D1 ;is it 2?
BNE.S @8
LEA TWO,A2
BRA.S @9
@8 LEA THREE,A2 ;must be 3
@9 MOVEQ #0,D0 ;set width - 1
MOVEQ #4,D1 ;and heigth - 1
BSR.S OUTPUT ;display it
@99 MOVE.L (SP)+,D0 ;restore reg
RTS ;and exit
;---------------------------------------------------------------------
;
; Routine to display error icon.
;
; INPUTS:
; A2 = pointer to compressed icon
;
; SIDE EFFECTS:
; A2/A6, D5-D6 are trashed
;---------------------------------------------------------------------
DSPERRICON
BSR MAKEALERT ;open alert box
MOVEQ #ERRROW,D5 ;set screen ptrs
MOVEQ #ERRCOL,D6
BSR SETCRSR ;get screen address in A6
MOVE.L A6,A5 ;save it
BSR DSPICON ;go do display of component icon
DSPBAD
LEA CHECKMRK,A2 ;get ptr to check icon
BSR.S MRGICON ;do the merge
LEA BADMRK,A2 ;get ptr to slash icon
BSR.S MRGICON ;merge it
RTS ;and exit
;---------------------------------------------------------------------
;
; Routine to merge two icons, one over the other.
;
; INPUTS:
; A2 = ptr to icon to be merged
; A5 = pointer to base icon
;
; SIDE EFFECTS:
; None
;---------------------------------------------------------------------
MRGICON MOVEM.L D0-D3/A5-A6,-(SP) ;save regs
MOVE.L A5,A6 ;get start address
ADDQ #6,A6 ;first display new icon next to other icon
MOVEM.L A5-A6,-(SP) ;save ptrs
BSR DSPICON
MOVEM.L (SP)+,A5-A6 ;restore ptrs
MOVEQ #ROWBYTES-6,D3 ;set up row offset constant
MOVEQ #32-1,D2 ;icon heigth in pixel lines - 1
@1 MOVEQ #3-1,D1 ;icon width in words - 1
@2 MOVE (A6),D0 ;get from byte
OR D0,(A5)+ ;do the merge
CLR (A6)+ ;erase the old
DBF D1,@2 ;do full row
ADDA.L D3,A5 ;bump ptrs to next row
ADDA.L D3,A6
DBF D2,@1 ;go to next row
MOVEM.L (SP)+,D0-D3/A5-A6 ;restore and exit
RTS
;---------------------------------------------------------------------
;
; Routine to display alert icon.
;
; INPUTS:
; A2 = pointer to icon
; MSB set if uncompressed icon, else compressed assumed CHG008
;
; SIDE EFFECTS:
; A6, D5-D6 are trashed
;---------------------------------------------------------------------
DSPALRTICON
MOVEM.L D0-D1/A2,-(SP) ;save regs CHG008
BSR MAKEALERT ;open alert box
MOVEQ #ALRTROW,D5 ;set screen ptrs
MOVEQ #ALRTCOL,D6
BSR SETCRSR ;get screen address in A6
MOVE.L A2,D1 ;check icon address CHG008
BPL.S @1 ;skip if for compressed icon CHG008
BCLR #31,D1 ;clear indicator bit CHG008
MOVE.L D1,A2 ;and restore ptr CHG008
BSR DSPRGICON ;display an uncompressed icon CHG008
BRA.S @2 ;skip to exit CHG008
@1 BSR DSPICON ;go do display CHG008
@2 MOVEM.L (SP)+,D0-D1/A2 ;restore regs CHG008
RTS ; CHG008
;---------------------------------------------------------------------
;
; Routine to display icon with question mark along side.
;
; INPUTS:
; A2 = pointer to compressed icon
; OUTPUTS:
; A5 = icon screen address
; SIDE EFFECTS:
; A2/A6, D5-D6 are trashed
;---------------------------------------------------------------------
DSPQICON
BSR MAKEALERT ;open alert box
MOVEQ #ERRROW,D5 ;set screen ptrs
MOVEQ #ERRCOL,D6
BSR SETCRSR ;get screen address in A6
MOVE.L A6,A5 ;save it
BSR.S DSPICON ;go do display of component icon
LEA QUESTION,A2 ;get ptr to ? icon
MOVE.L A5,A6 ;restore start address
ADDA #6,A6 ;display next to component RM000
BSR.S DSPICON
RTS
;---------------------------------------------------------------------
;
; Routine to hilite (invert) a test icon.
;
; INPUTS:
; A1 = address of icon
;
; SIDE EFFECTS:
; None
;---------------------------------------------------------------------
INVICON MOVEM.L D0-D2,-(SP) ;save regs
MOVEQ #ICONWIDTH,D0 ;set parms for icon
MOVEQ #ICONHIGH,D1
MOVEQ #-1,D2 ;set fill pattern
BSR INVERSE ;and go invert selected one
MOVEM.L (SP)+,D0-D2 ;restore
RTS
;---------------------------------------------------------------------
;
; Routine to display test icons.
;
; INPUTS:
; None
;
; SIDE EFFECTS:
; A2/A6 trashed
;---------------------------------------------------------------------
DSPCPU
LEA CPUBRD,A2 ;set ptr for CPU board icon
MOVEA #CPUSTRT,A6 ;and address
BRA.S DODSPLY ;go do display
DSPMBRD
LEA MEMBRD,A2 ;set ptr for Memory board icon
MOVEA #MEMSTRT,A6 ;and address
BRA.S DODSPLY ;go do display
DSPIOB
LEA IOBRD,A2 ;set ptr for I/O board icon
MOVEA #IOSTRT,A6 ;and address
BRA.S DODSPLY ;go do display
DSPXCRD
LEA XCARD,A2 ;set ptr for I/O slot card icon
MOVEA #XCRDSTRT,A6 ;and address
DODSPLY
ADDA.L SCRNBASE,A6 ;compute screen address for display
BSR.S DSPICON ;go do display
RTS
;---------------------------------------------------------------------
;
; Routine to display icon with check mark.
;
; Inputs:
; None
; Outputs:
; None
; Side Effects:
; A6 trashed
;---------------------------------------------------------------------
CHKCPU
BSR.S DSPCPU ;redisplay CPU icon
MOVEA #CPUSTRT,A5 ;get start address for it
BRA.S DSPCHECK ;and go add check mark
CHKMBRD
BSR.S DSPMBRD ;redisplay Memory board icon
MOVEA #MEMSTRT,A5 ;get start address for it
BRA.S DSPCHECK ;and go add check mark
CHKIOBRD
BSR.S DSPIOB ;redisplay I/O icon
MOVEA #IOSTRT,A5 ;get start address for it
BRA.S DSPCHECK ;and go add check mark
CHKXCRD
BSR.S DSPXCRD ;redisplay I/O slot card icon
MOVEA #XCRDSTRT,A5 ;get start address for it
DSPCHECK
LEA CHECKMRK,A2 ;get ptr to check icon
ADDA.L SCRNBASE,A5 ;compute screen address for display
BSR MRGICON ;and go do merge
RTS
;---------------------------------------------------------------------
;
; Routine to display compressed icon.
;
; INPUTS:
; A2 = pointer to compressed icon
; A6 = pointer to (even!) screen address for upper left hand
; corner of icon
; SIDE EFFECTS:
; A6 is trashed
;---------------------------------------------------------------------
DSPICON
MOVEM.L D0-D2/A0/A2,-(SP) ; CHG009
MOVE.L A6,A0 ; save screen start address
MOVEQ #23,D1 ; There are 24 octals in an icon
MOVEQ #5,D2 ; reset row bytes counter
DLOOP MOVE #$100,D0 ; prime D0 for 8 bit count count
MOVE.B (A2)+,D0 ; load map byte from compressed image
MLOOP LSR.W #1,D0 ; shift off map bit
BEQ.S DONE ; byte done when = 0
BCC.S BLACK ; dispatch on the bit
CLR.B (A6)+ ; store zero in new
BRA.S CHECK ; continue for all 8 bits
BLACK MOVE.B (A2)+,(A6)+ ; store byte in new
CHECK DBF D2,MLOOP ; see if on scanline seam(every 6 bytes)
ADDA #90-6,A6 ; bump to next scanline RM015
MOVEQ #5,D2 ; reset row bytes counter
BRA.S MLOOP ; continue for all 8 bits
DONE DBF D1,DLOOP ; do the rest of the octals in ICON
; Now unXOR the icon on the screen
MOVE.L A0,A6 ; get screen pointer saved above
MOVE.L A6,A2 ; second pointer
ADDA #90,A2 ; scanline pointer RM015
MOVE #30,D1 ; do 31 scanlines
; This is the cause of the even destination restriction
XLOOP MOVE.L (A6)+,D0 ; get long from previous scanline
EOR.L D0,(A2)+ ; xor into this scanline
MOVE.W (A6)+,D0 ; get word from previous scanline
EOR.W D0,(A2)+ ; xor into this scanline
ADDA #90-6,A2 ; next scan line + rowbytes RM015
ADDA #90-6,A6 ; next scan line + rowbytes RM015
DBF D1,XLOOP
MOVEM.L (SP)+,D0-D2/A0/A2 ; CHG009
RTS
.PAGE
;----------------------------------------------------------------------
; Subroutine to display text string according to keyboard id
; Inputs:
; A3 = ptr to message
; D1 = nonzero if '...' string to be appended
; Outputs:
; A2 = ptr to start of string
; A3 = ptr to end of string
; Side Effects:
; D5-D6, A3 trashed
;----------------------------------------------------------------------
DSPSTRING
MOVEM.L D0/D2,-(SP) ;save regs
LEA MENUHDG,A2 ;don't translate service mode messages
CMPA.L A2,A3
BEQ.S DSPOUT ;skip if it is
MOVE.L A3,A2 ;else save starting point
MOVE.B KEYID,D0 ;get keyboard id
BEQ.S DSPOUT ;skip if no id available
ANDI.B #$3F,D0 ;clear mfg code
MOVE.B D0,D2 ;move to working reg
; Search for US, UK or Canadian keyboard
ANDI.B #$F0,D2 ;old US keyboard?
BEQ.S DSPOUT ;yes - go do English display
CMPI.B #$30,D2 ;US or Canadian layout?
BNE.S @1
CMPI.B #$3D,D0 ;Canadian?
BEQ.S DSPALL ;yes - display all languages
BRA.S DSPOUT ;else just English
@1 CMPI.B #$20,D2 ;European keyboard?
BNE.S DSPALL ;no - display all languages
CMPI.B #$2F,D0 ;UK?
BEQ.S DSPOUT ;yes - display English
; Search for German type keyboard
CMPI.B #$2E,D0 ;German?
BEQ.S DSPGERMN
CMPI.B #$26,D0 ;Swiss-German?
BEQ.S DSPGERMN
; Search for French type keyboard
CMPI.B #$2D,D0 ;French?
BEQ.S DSPFRNCH
CMPI.B #$27,D0 ;Swiss-French?
BEQ.S DSPFRNCH
; Display all languages for any other keyboard (e.g., Italian, Spanish, etc.)
DSPALL BTST #MENU,STATFLGS ;doing menu?
BNE.S @1 ;skip if yes
SUB #CHRSPC,D5 ;back up one row
BSR.S DSPIT ;display English string
ADD #CHRSPC,D5 ;incr to next row
BSR.S DSPIT ;display French translation
ADD #CHRSPC,D5 ;bump another row
BRA.S DSPOUT ;go do final display of German
@1 BSR.S DSPMSLSH ;display English followed by /
BSR.S DSPMSLSH ;display French followed by /
BRA.S DSPOUT ;and go do final German display
DSPGERMN
TST.B (A3)+ ;skip two strings before output
BNE.S DSPGERMN
DSPFRNCH
TST.B (A3)+ ;skip one string before output
BNE.S DSPFRNCH
MOVE.L A3,A2 ;save new beginning ptr
DSPOUT BSR.S DSPIT ;do display
MOVEM.L (SP)+,D0/D2 ;restore regs
RTS ; and exit
;----------------------------------------------------------------------
; Subroutine to display text string followed by '...'
; Inputs:
; A3 = ptr to message
; D1 = nonzero if '...' string to be appended
; Outputs:
; None
; Side Effects:
; A3 updated to next location after 0 byte
;----------------------------------------------------------------------
DSPIT MOVEM.L D5-D6,-(SP) ;save cursor ptrs
BSR.S DSPMSG ;output message
MOVE.L A3,-(SP) ;save msg ptr
TST D1 ;check if periods needed
BEQ.S @9 ;skip if not
LEA PERIODS,A3 ;else do display
BSR.S DSPMSG
@9
MOVE.L (SP)+,A3 ;restore regs and exit
MOVEM.L (SP)+,D5-D6
RTS
;----------------------------------------------------------------------
; Subroutine to display text string followed by '/'
; Inputs:
; A3 = ptr to message
; Outputs:
; None
; Side Effects:
; A3 updated to next location after 0 byte
;----------------------------------------------------------------------
DSPMSLSH
BSR.S DSPMSG ;output message
MOVEQ #'/',D0 ;display /
BSR.S DSPVAL
RTS
;----------------------------------------------------------------------
; Subroutine to display alert box message
; Inputs:
; A3 = ptr to message
; Outputs:
; None
;----------------------------------------------------------------------
DSPALRTMSG
MOVEM.L D4-D6,-(SP) ;save regs CHG005
MOVE #MSGROW,D5 ;set screen ptrs
MOVEQ #MSGCOL,D6
MOVE D5,D4 ;set left margin in case of CR CHG005
BSR.S DSPMSG ;go do display
MOVEM.L (SP)+,D4-D6 ;restore regs CHG005
RTS
;----------------------------------------------------------------------
; Routine to convert row coordinate to pixel row coordinate before
; doing message display
;
; Expects D5 = row coordinate from 0-32
;----------------------------------------------------------------------
CONVRTD5
MULU #10,D5 ;multiply by pixel lines per char row
BSR.S DSPMSG ;then go do message
RTS
.ENDC ;{USERINT}
;----------------------------------------------------------------------
; Subroutine to display message followed by a line feed, CR.
; Calls DSPMSG routine, with same assumptions as that routine.
;----------------------------------------------------------------------
DSPMSGR BSR.S DSPMSG ;go display msg
.IF USERINT = 0
ADDQ #1,D5 ;do "line feed"
.ELSE
ADD #CHRSPC,D5 ;do "line feed"
.ENDC
MOVEQ #1,D6 ;and "carriage return"
RTS
;---------------------------------------------------------------------------
; Subroutine to display message on screen.
; Requires inputs:
; A3 - ptr to ASCII character string ended by 0 byte
; D4 = left margin if message has a CR
; D5 = cursor row position (0 - 32 decimal)
; D6 = cursor column position (1 - 88 decimal)
; Uses regs:
; D0 - for character to display
;
; NOTE: ONLY UPPER CASE ALPHA, NUMERIC AND CERTAIN SPECIAL CHARS SUPPORTED!
;---------------------------------------------------------------------------
DSPMSG MOVE.L D0,-(SP) ;save reg
.IF ROM4K = 0
@1 CMPI #LASTROW,D5 ;check if out of bounds
BLE.S @2 ;skip if OK
BSR SCROLL ;else scroll page
.ENDC
@2 CLR.L D0 ;clear for use
MOVE.B (A3)+,D0 ;get a char to display
BEQ.S DSPDONE ;exit if done
BSR.S DSPVAL ;go do display
BRA.S @1 ;continue until done
DSPDONE MOVE.L (SP)+,D0 ;restore and exit
RTS
.PAGE
;----------------------------------------------------------------------
; Subroutine to set cursor position in video page for message display.
; Requires inputs:
; D5 = row position (0 - 32 decimal)
; D6 = column position (1 - 88 decimal)
; location SCRNBASE = base address for video page
; Provides output:
; A6 = address for new cursor location
;----------------------------------------------------------------------
SETCRSR
MOVE.L SCRNBASE,A6 ;get base address for screen
SETCRSR2
MOVE.L D0,-(SP) ;save reg
CLR.L D0 ;use as working reg
.IF USERINT = 0
MOVE.B D5,D0 ;get row coordinate
.ELSE
MOVE D5,D0 ;get pixel row
.ENDC
MULU #RBYTES,D0 ;compute byte offset
; .IF USERINT = 0
ADD #RBYTES,D0 ;add one more
; .ELSE
; ADD #TOPOFFSET,D0 ;adjust for offset from top of screen
; .ENDC
ADD.L A6,D0 ;add in base screen address
MOVE.L D0,A6 ;and save new value
CLR.L D0
.IF USERINT = 0
MOVE.B D6,D0 ;get col coordinate
.ELSE
MOVE D6,D0 ;get pixel col
.ENDC
ADDA.L D0,A6 ;add to cursor address
MOVE.L (SP)+,D0 ;restore and exit
RTS
;------------------------------------------------------------------------
; Subroutine to display single ASCII character.
; Requires input:
; D0 = character to display
; D4 = left margin if CR char
; D5 = cursor row position (0 - 32 decimal)
; D6 = cursor column position (1 - 88 decimal)
; Returns output:
; D6 = new cursor col position (incremented by 1)
;------------------------------------------------------------------------
DSPVAL MOVEM.L A2/A6/D0-D1,-(SP) ;save regs
BSR.S SETCRSR ;set cursor position
ANDI #$7F,D0 ;ensure valid
.IF USERINT = 1
TST.B D0 ;apple icon?
BEQ.S @4
.ENDC
.IF ROM4K = 0
CMPI.B #$20,D0 ;space?
BEQ.S @3 ;skip if yes
CMPI.B #RET,D0 ;carriage return?
BEQ.S @5 ;skip if yes
CMPI.B #QUESTN,D0 ;'?' char?
BEQ.S @6
SUB.B #$2D,D0 ;else check if in table
BLT.S @1
CMPI.B #$C,D0 ;numeric char?
BLE.S @2 ;skip if yes
SUB.B #7,D0 ;else decr for alpha check
CMPI.B #$D,D0 ;check if in alpha range
BLT.S @1 ;skip if invalid
CMPI.B #$26,D0 ;last valid char = 'Z'
BLE.S @2
;skip if OK
.ELSE
SUB.B #$30,D0 ;convert to table index
BMI.S @3 ;skip if space
CMP.B #$11,D0 ;alpha char?
BLT.S @2 ;skip if not
SUB.B #$7,D0 ;else do further conversion
BRA.S @2 ;and go do output
.ENDC
.IF USERINT = 0
@1 LEA INVCHAR,A2 ;else set for invalid character
BRA.S OUTPUT
@3 LEA SPACE,A2 ;set ptr to space char
BRA.S OUTPUT
@5 ADD #CHRSPC,D5 ;set cursor for next row
MOVE D4,D6 ;set to left margin
BRA.S DSPVXIT
@2 LSL #3,D0 ;convert for table
LEA FONTTBL(D0),A2 ;get ptr to char in table
OUTPUT MOVE.B (A2)+,(A6) ;output bits
MOVE.B (A2)+,R1(A6)
MOVE.B (A2)+,R2(A6)
MOVE.B (A2)+,R3(A6)
MOVE.B (A2)+,R4(A6)
MOVE.B (A2)+,R5(A6)
MOVE.B (A2)+,R6(A6)
MOVE.B (A2)+,R7(A6)
ADDQ #1,D6 ;bump cursor col coordinate
.ELSE
@1 LEA INVCHAR,A2 ;else set for invalid character
BRA.S OUT
@3 LEA SPACE,A2 ;set ptr to space char
BRA.S OUT
@4 LEA APPLICON,A2 ; display apple icon
BRA.S OUT
@5 ADD #CHRSPC,D5 ;set cursor for next row
MOVE D4,D6 ;set to left margin
BRA.S DSPVXIT
@6 LEA QUESTCH,A2 ;set ptr to '?' char
BRA.S OUT
@2 MOVE D0,D1 ;convert for table (multiply by 6) CHG017
LSL #3,D0 ;mult by 8
SUB D1,D0 ; then subtract twice
SUB D1,D0 ; CHG017
LEA FONTTBL(D0),A2 ;get ptr to char in table
out clr.l d0 ;set number of bytes-1 in x direction
moveq #5,d1 ;set number of pixels-1 in y direction CHG017
MOVE.B #0,R0(A6) ;first line always 0 CHG017
ADDA.L #RBYTES,A6 ;bump ptr to next row CHG017
bsr output ;output char
MOVE.B #0,R7(A6) ;and add final 0 byte
.ENDC
DSPVXIT
MOVEM.L (SP)+,A2/A6/D0-D1 ;restore and exit
RTS
.IF EXTERNAL = 1
.NOLIST
.ENDC
.PAGE
;----------------------------------------------------------------------
; CHARACTER FONT TABLE
;----------------------------------------------------------------------
SPACE
.BYTE $00,$00,$00,$00,$00,$00 ; (space)
FONTTBL
.IF ROM4K = 0
.BYTE $00,$00,$00,$7C,$00,$00 ; code = 45 '-'
.BYTE $00,$00,$00,$00,$00,$30 ; code = 46 '.'
.BYTE $04,$08,$10,$20,$40,$80 ; code = 47 '/'
.ENDC
.BYTE $38,$44,$44,$44,$44,$38 ; code = 48 '0'
.BYTE $08,$38,$08,$08,$08,$08 ; code = 49 '1'
.BYTE $38,$44,$08,$10,$20,$7C ; code = 50 '2'
.BYTE $38,$44,$18,$04,$44,$38 ; code = 51 '3'
.BYTE $08,$18,$28,$48,$7C,$08 ; code = 52 '4'
.BYTE $7C,$40,$78,$04,$44,$38 ; code = 53 '5'
.BYTE $38,$40,$78,$44,$44,$38 ; code = 54 '6'
.BYTE $7C,$08,$10,$10,$20,$20 ; code = 55 '7'
.BYTE $38,$44,$38,$44,$44,$38 ; code = 56 '8'
.BYTE $38,$44,$44,$3C,$04,$38 ; code = 57 '9'
.BYTE $30,$48,$84,$FC,$84,$84 ; code = 65 'A'
.BYTE $F8,$84,$F8,$84,$84,$F8 ; code = 66 'B'
.BYTE $78,$84,$80,$80,$84,$78 ; code = 67 'C'
.BYTE $F8,$84,$84,$84,$84,$F8 ; code = 68 'D'
.BYTE $FC,$80,$F8,$80,$80,$FC ; code = 69 'E'
.BYTE $FC,$80,$F8,$80,$80,$80 ; code = 70 'F'
.BYTE $78,$84,$80,$9C,$84,$7C ; code = 71 'G'
.BYTE $84,$84,$FC,$84,$84,$84 ; code = 72 'H'
.BYTE $38,$10,$10,$10,$10,$38 ; code = 73 'I'
.BYTE $1C,$08,$08,$08,$88,$70 ; code = 74 'J'
.BYTE $88,$90,$A0,$D0,$88,$84 ; code = 75 'K'
.BYTE $80,$80,$80,$80,$80,$FC ; code = 76 'L'
.BYTE $84,$CC,$B4,$84,$84,$84 ; code = 77 'M'
.BYTE $84,$C4,$A4,$94,$8C,$84 ; code = 78 'N'
.BYTE $78,$84,$84,$84,$84,$78 ; code = 79 'O'
.BYTE $F8,$84,$84,$F8,$80,$80 ; code = 80 'P'
.BYTE $78,$84,$84,$84,$94,$78 ; code = 81 'Q'
.BYTE $F8,$84,$84,$F8,$88,$84 ; code = 82 'R'
.BYTE $78,$84,$60,$18,$84,$78 ; code = 83 'S'
.BYTE $FE,$10,$10,$10,$10,$10 ; code = 84 'T'
.BYTE $84,$84,$84,$84,$84,$78 ; code = 85 'U'
.BYTE $44,$44,$28,$28,$10,$10 ; code = 86 'V'
.BYTE $82,$82,$92,$AA,$44,$44 ; code = 87 'W'
.BYTE $44,$28,$10,$28,$44,$82 ; code = 88 'X'
.BYTE $82,$44,$28,$10,$10,$10 ; code = 89 'Y'
.BYTE $FC,$08,$10,$20,$40,$FC ; code = 90 'Z'
.IF ROM4K = 0
QUESTCH
.BYTE $38,$44,$08,$10,$00,$10 ; code = 63 '?'
.ENDC
INVCHAR
.BYTE $C7,$BB,$F7,$EF,$FF,$EF ; inverse of ?
.IF ROM4K = 0
APPLICON
.BYTE $08,$77,$FE,$FE,$7F,$3E ; apple icon
.PAGE
.ALIGN 2
;----------------------------------------------------------------------
; Keycode to Ascii Table (assumes alpha-lock so upper case only)
;----------------------------------------------------------------------
AsciiTable ; RM000
.BYTE $1B,$2D,$11,$12,$37,$38,$39,$14 ;Pad : Clear - Left Right 789 Up
.BYTE $34,$35,$36,$13,$2E,$32,$33,$03 ;Pad : 456 Down .23 Enter
.BYTE $00,$00,$00,$00,$00,$00,$00,$00 ;unused
.BYTE $00,$00,$00,$00,$00,$00,$00,$00 ;unused
.BYTE $2D,$3D,$00,$00,$50,$08,$00,$00 ;- = 2*unused P BackSp 2*unused
.BYTE $0D,$30,$00,$00,$2F,$31,$00,$00 ;Ret Pad:0 2*unused / Pad:1 2*unused
.BYTE $39,$30,$55,$49,$4A,$4B,$5B,$5D ;90UIJK[]
.BYTE $4D,$4C,$3B,$27,$20,$2C,$2E,$4F ;ML;' Space ,.O
.BYTE $45,$36,$37,$38,$35,$52,$54,$59 ;E6785RTY
.BYTE $00,$46,$47,$48,$56,$43,$42,$4E ;Option FGHVCBN
.BYTE $41,$32,$33,$34,$31,$51,$53,$57 ;A2341QSW
.BYTE $00,$5A,$58,$44,$00,$00,$00,$00 ;Tab ZXD unused Alpha Shift Cmd
.ENDC
.IF USERINT = 1
;----------------------------------------------------------------------
; Icons
;----------------------------------------------------------------------
CrsrData ;arrow for mouse cursor
CrsrMask ;same for mask
.WORD $8000,$C000,$E000,$F000
.WORD $F800,$FC00,$FE00,$FF00
.WORD $F800,$F800,$CC00,$8C00
.WORD $0600,$0600,$0300,$0300
ONE .BYTE $E0,$60,$60,$60,$F0 ;icon id = 1
TWO .BYTE $E0,$30,$60,$C0,$F0 ;icon id = 2
THREE .BYTE $E0,$30,$60,$30,$E0 ;icon id = 3
IObrd .BYTE $FF,$FF,$FF,$3F,$03,$FF,$00,$FF
.BYTE $FF,$FF,$E0,$01,$FF,$FF,$FF,$E4
.BYTE $FF,$C0,$70,$2F,$F9,$50,$66,$9E
.BYTE $C0,$01,$80,$F7,$03,$79,$56,$06
.BYTE $74,$FE,$0F,$FF,$FF,$FF,$FF,$FF
.BYTE $FF,$FF,$3F,$01,$AA,$60,$AA,$AF
.BYTE $FF,$C0,$03,$07,$C4,$FF,$E0,$55
.BYTE $55,$50,$F1,$FF,$FF,$F8,$FF,$FF
CPUbrd .BYTE $FF,$FF,$FF,$3F,$03,$FF,$00,$FF
.BYTE $FF,$FF,$E0,$01,$FF,$FF,$FF,$C4
.BYTE $FF,$C0,$79,$F2,$40,$F9,$38,$E0
.BYTE $BF,$E0,$EF,$F0,$71,$38,$01,$80
.BYTE $79,$FC,$03,$C0,$FF,$FF,$FF,$FF
.BYTE $FF,$FF,$FF,$3F,$01,$FE,$C0,$AA
.BYTE $AA,$BF,$C0,$03,$FC,$84,$1F,$E0
.BYTE $01,$55,$55,$40,$E1,$03,$FF,$FF
.BYTE $E0,$FF,$FF
MEMbrd .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$C3,$1F
.BYTE $FF,$FF,$C0,$80,$0F,$FF,$FF,$80
.BYTE $07,$FF,$E0,$E3,$03,$FF,$F0,$FF
.BYTE $FF,$FF,$71,$04,$5E,$88,$02,$1C
.BYTE $8E,$50,$03,$8C,$70,$C7,$01,$0C
.BYTE $20,$7B,$0E,$04,$0C,$5E,$88,$03
.BYTE $FF,$D5,$57,$00,$FF,$80,$07,$FF
.BYTE $80,$03,$FF,$C0,$F3,$2A,$A8,$FC
.BYTE $7F,$FC,$FF,$FF,$FF,$FF
Xcard .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$E1,$01
.BYTE $FF,$FF,$80,$FC,$FF,$FF,$FF,$FF
.BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.BYTE $FF,$FF,$DF,$03,$63,$EA,$AD,$80
.BYTE $01,$3C,$C0,$06,$15,$50,$CF,$3F
.BYTE $F8
waiticon .BYTE $FF,$FF,$FF,$61,$1F,$FF,$FF,$F8
.BYTE $0F,$18,$FF,$FF,$F0,$0F,$FF,$FF
.BYTE $86,$F0,$11,$FF,$FF,$88,$6D,$05
.BYTE $A0,$02,$18,$80,$01,$40,$01,$4F
.BYTE $F2,$CE,$80,$A8,$15,$F3,$54,$2A
.BYTE $3C,$2A,$54,$14,$28,$CF,$08,$10
.BYTE $FF,$3C,$08,$10,$14,$28,$CF,$28
.BYTE $14,$F3,$50,$0A,$1C,$A0,$05,$01
.BYTE $46,$62,$86,$80,$02,$88,$11,$40
.BYTE $61,$05,$10,$08,$A0,$11,$18,$E0
.BYTE $07,$88,$0F,$FF,$FF,$86,$F0,$0F
.BYTE $FF,$FF,$F0,$E1,$1F,$FF,$FF,$F8
.BYTE $FF,$FF
proicon .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.BYTE $FF,$00,$1F,$FF,$FF,$FF,$FF,$F8
.BYTE $3F,$FF,$F0,$FF,$FF,$FF,$FC,$FF
.BYTE $CC,$03,$7F,$01,$80,$CF,$03,$7F
.BYTE $FC,$01,$80,$00,$3F,$FF,$FF,$FF
.BYTE $FF,$FC,$1C,$FF,$60,$FF,$F3,$FF
.BYTE $38,$03,$0C,$FD,$C0,$FF,$FF,$FF
.BYTE $FF,$FF,$FF
upper .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ;CHG024
.BYTE $FF,$2F,$08,$1F,$FF,$08,$FF,$FC
.BYTE $10,$1F,$FF,$FF,$FC,$02,$20,$1F
.BYTE $FF,$FF,$FC,$47,$F8,$20,$1F,$FF
.BYTE $FF,$FC,$80,$1F,$FF,$08,$FF,$FC
.BYTE $80,$1F,$FF,$FF,$FC,$80,$47,$F8
.BYTE $1F,$FF,$FF,$FC,$20,$E0,$1F,$FF
.BYTE $FF,$FC,$10,$FB,$08,$FF,$FF,$FF
.BYTE $FF,$FF,$FF,$FF
driven .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ;CHG024
.BYTE $FF,$EF,$02,$38,$03,$FF,$04,$07
.BYTE $FF,$22,$88,$3F,$FF,$F8,$11,$FE
.BYTE $E8,$7F,$FF,$FC,$20,$8B,$20,$7F
.BYTE $FF,$FC,$A0,$11,$FE,$3F,$FF,$F8
.BYTE $08,$E3,$07,$FF,$84,$F8,$03,$FF
.BYTE $02,$FF,$FF,$FF,$FF,$FF,$FF,$FF
insertd .BYTE $FF,$79,$07,$FE,$0F,$C6,$FF,$7F
.BYTE $FF,$F0,$71,$FF,$FF,$F8,$0A,$18
.BYTE $AA,$AA,$A8,$FA,$AA,$AA,$F6,$A0
.BYTE $60,$E3,$03,$C0,$07,$38,$04,$20
.BYTE $06,$08,$10,$FF,$F3,$08,$10,$3C
.BYTE $04,$20,$03,$C0,$FF,$FF,$FF,$FF
.BYTE $61,$1F,$FF,$FF,$F8,$0F,$38,$FF
.BYTE $FF,$F0,$01,$80,$CF,$02,$40,$F3
.BYTE $04,$20,$3C,$08,$10,$10,$08,$CF
.BYTE $1C,$38,$FF,$FF,$CF,$03,$C0
keybdout .BYTE $CF,$01,$C0,$FF,$3F,$0E,$38,$CF
.BYTE $08,$08,$F3,$04,$10,$3C,$02,$20
.BYTE $01,$40,$DF,$80,$F3,$01,$C0,$3F
.BYTE $01,$40,$20,$1B,$6D,$B6,$DB,$60
.BYTE $16,$DB,$08,$6D,$B6,$DF,$3B,$6D
.BYTE $B6,$DB,$80,$67,$80,$06,$DB,$6D
.BYTE $B6,$D8,$FF,$0F,$4F,$FF,$FF,$FF
.BYTE $00,$FF,$F0,$FF,$FF,$FF,$FF,$FF
.BYTE $F8,$00,$1B,$6D,$B6,$D8,$36,$C0
.BYTE $1B,$6D,$00,$B6,$D8,$36,$C0,$1B
.BYTE $6D,$B6,$D8,$00,$36,$C0,$1B,$6D
.BYTE $B6,$D8,$36,$C0,$00,$1B,$6D,$B6
.BYTE $D8,$36,$C0,$1B,$6D,$00,$B6,$D8
.BYTE $36,$C0,$1B,$FF,$FF,$D8,$00,$36
.BYTE $C0,$1B,$FF,$FF,$D8,$36,$C0,$00
.BYTE $FF,$FF,$FF,$FF,$FF,$F8,$7F,$FF
.BYTE $F0,$FF,$FF,$FF,$F0,$FF
mouseout .BYTE $FD,$E0,$FF,$F3,$07,$1C,$3C,$04
.BYTE $04,$02,$08,$CF,$01,$10,$F7,$A0
.BYTE $3D,$40,$01,$E0,$FF,$F3,$01,$20
.BYTE $7F,$3F,$9C,$FF,$80,$FF,$FE,$FF
.BYTE $FF,$3C,$7E,$7C,$FF,$FE,$CF,$1F
.BYTE $F0,$F3,$0F,$E0,$3C,$0F,$E0,$1F
.BYTE $F0,$FF,$FF,$FF,$FF,$FF,$FF,$CF
.BYTE $FF,$FE
Question .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.BYTE $CF,$0F,$E0,$F3,$03,$80,$FE,$0C
.BYTE $CF,$03,$80,$F7,$E0,$BF,$03,$EF
.BYTE $03,$FF,$FE,$03,$FF,$FF,$FF,$FF
.BYTE $FF,$FF,$FF
checkmrk .BYTE $CF,$07,$80,$F3,$0E,$80,$BE,$1B
.BYTE $36,$EF,$6C,$7B,$D8,$01,$9E,$B0
.BYTE $03,$60,$E7,$06,$C0,$79,$0D,$80
.BYTE $1B,$DF,$36,$F7,$6C,$3D,$D8,$01
.BYTE $B0,$CF,$03,$60,$F3,$06,$C0,$BC
.BYTE $0D,$80,$1B,$EF,$36,$FB,$6C,$9E
.BYTE $D8,$01,$B0,$E7,$03,$60,$38,$F8
.BYTE $06,$C0,$DC,$0D,$CE,$80,$36,$1B
.BYTE $F3,$1B,$36,$3C,$0D,$EC,$06,$D8
.BYTE $CF,$03,$30,$F3,$01,$E0
badmrk .BYTE $3C,$03,$C0,$02,$E0,$CF,$01,$B0
.BYTE $F7,$D8,$7D,$6C,$36,$DF,$1B,$E7
.BYTE $0D,$80,$79,$06,$C0,$03,$9E,$60
.BYTE $01,$B0,$EF,$D8,$FB,$6C,$BE,$36
.BYTE $1B,$CF,$0D,$80,$F3,$06,$C0,$3C
.BYTE $03,$60,$01,$B0,$DF,$D8,$F7,$6C
.BYTE $7D,$36,$1B,$9F,$0D,$80,$E7,$06
.BYTE $C0,$79,$03,$60,$01,$BE,$B0,$D8
.BYTE $EF,$6C,$FB,$36,$3E,$1B,$0E,$80
diskette .BYTE $FF,$FF,$FF,$FF,$1F,$03,$FF,$FF
.BYTE $86,$F8,$07,$FF,$FF,$F4,$EF,$0A
.BYTE $FB,$05,$BC,$02,$80,$01,$FF,$7D
.BYTE $78,$84,$CF,$01,$02,$FF,$7C,$01
.BYTE $02,$84,$DF,$78,$FF,$FF,$FF,$7F
.BYTE $07,$10,$FF,$FF,$FF,$80,$03,$FF
.BYTE $FF,$FE,$FF,$FF,$FF,$FF
lisa .BYTE $FF,$0F,$03,$FF,$FF,$FF,$00,$FF
.BYTE $C0,$07,$FF,$FF,$FF,$FF,$E0,$10
.BYTE $0C,$FF,$FF,$F0,$30,$01,$FF,$70
.BYTE $FF,$F8,$07,$80,$01,$9E,$FF,$01
.BYTE $FF,$CF,$07,$80,$FF,$3F,$07,$80
.BYTE $E7,$01,$FF,$09,$01,$FF,$01,$FF
.BYTE $FF,$F8,$40,$07,$80,$0C,$FF,$FF
.BYTE $F0,$30,$00,$07,$FF,$FF,$FF,$FF
.BYTE $E0,$03,$FF,$00,$FF,$FF,$FF,$C0
.BYTE $03,$FF,$FF,$FF,$00,$FF,$E0,$07
.BYTE $FF,$FF,$FF,$FF,$F0,$61,$AA,$AA
.BYTE $AA,$95,$FF,$18,$FF,$FF,$9F,$5F
.BYTE $FF,$FD,$86,$1F,$0A,$AA,$A8,$15
.BYTE $3F,$07,$FF,$00,$FF,$FF,$FF,$F0
.BYTE $03,$FF,$FF,$FF,$FC,$FF,$E0,$FF
.BYTE $FF,$FF
.ENDC
.PAGE
.LIST
;----------------------------------------------------------------------
; Message Table
;----------------------------------------------------------------------
.IF USERINT = 0
.IF ROM4K = 0
INITMSG .ASCII 'SELF TEST OK'
.BYTE 0
.IF ROM8K = 1
.IF NEWTWIG = 0
CROMMSG .ASCII 'CPU ROM 1.08'
.BYTE 0
.ENDC
.IF NEWTWIG = 1
CROMMSG .ASCII 'CPU ROM 1.18'
.BYTE 0
.ENDC
.ENDC
IORMMSG .ASCII 'IO ROM '
.BYTE 0
CPUMSG .ASCII 'CPU LOGIC FAILURE'
.BYTE 0
.ENDC ;{ROM4K}
RAMMSG .ASCII 'MEMORY FAILURE'
.BYTE 0
IOMSG .ASCII 'IO LOGIC FAILURE'
.BYTE 0
IOSMSG .ASCII 'IO SLOT FAILURE'
.BYTE 0
DSKMSG .ASCII 'PLEASE INSERT DISK'
.BYTE 0
BOOTERR .ASCII 'STARTUP FAILURE'
.BYTE 0
DVCMSG .ASCII 'DEVICE '
.BYTE 0
ERRMSG .ASCII 'ERROR ' ;FOR ERROR CODE OUTPUT
.BYTE 0
EXCPMSG .ASCII 'EXCEPTION'
.BYTE 0
.IF ROM4K = 0
BOOTMSG .ASCII 'BOOTING...'
.BYTE 0
.ELSE
BOOTMSG .ASCII 'BOOTING'
.BYTE 0
.ENDC
BADBOOT .ASCII 'INVALID SELECTION'
.BYTE 0
.ENDC ;{USERINT}
.IF BURNIN = 1
BRNMSG .ASCII 'POWER CYCLING AT '
.BYTE 0
TIMMSG .ASCII 'TIME IS ' ; RM000
.BYTE 0
TWGMSG .ASCII 'DRIVE TEST' ; RM000
.BYTE 0
LOOPMSG .ASCII 'LOOP COUNT IS '
.BYTE 0
PMMSG .ASCII 'PM BUS ERROR'
.BYTE 0
TWGFAIL .ASCII 'FLOPPY TEST FAILED'
.BYTE 0
TWGRSLT .ASCII 'FLOPPY ERROR COUNT IS '
.BYTE 0
.ENDC
.IF ROM4K = 0
.IF USERINT = 0
CONTMSG .ASCII '2-CONTINUE '
.BYTE 0
LEV1MSG .ASCII '1-RETRY 3-STARTUP FROM... ?'
.BYTE 0
LEV2MSG .ASCII '1-DISPLAY 2-SET 3-CALL '
.IF ROM16K = 1
.ASCII '4-DUMP 5-VERIFY 6-LOOP '
.ENDC
.ASCII '7-ADJUST VIDEO 9-QUIT ?'
.BYTE 0
.ELSE
CHKMSG .ASCII 'TESTING'
.BYTE 0
.ASCII 'TEST' ;French translation
.BYTE 0
.ASCII 'ES WIRD GETESTET' ;German translation
.BYTE 0
RTRYMSG .ASCII 'RESTART'
.BYTE 0
.ASCII 'RECOMMENCER' ;French
.BYTE 0
.ASCII 'NEU STARTEN' ;German
.BYTE 0
CONTMSG .ASCII 'CONTINUE'
.BYTE 0
.ASCII 'CONTINUER' ;French
.BYTE 0
.ASCII 'WEITERMACHEN' ;German
.BYTE 0
STRTMSG .ASCII 'STARTUP FROM'
.BYTE 0
.ASCII 'DEMARRER DE' ;French
.BYTE 0
.ASCII 'STARTEN VON' ;German
.BYTE 0
PERIODS .ASCII '...'
.BYTE 0
MENUHDG .ASCII 'OPTIONS'
.BYTE 0
DISPMSG .ASCII 'DISPLAY MEM 1'
.BYTE 0
SETMSG .ASCII 'SET MEMORY 2'
.BYTE 0
CALLMSG .ASCII 'CALL PROGRAM 3'
.BYTE 0
.IF ROM16K = 1
LPMSG .ASCII 'LOOP ON TEST 4'
.BYTE 0
.ENDC
VIDMSG .ASCII 'ADJUST VIDEO 5'
.BYTE 0
.IF BURNIN = 1
CYCLMSG .ASCII 'POWER CYCLE 6'
.BYTE 0
.ENDC
QUITMSG .ASCII 'QUIT 7'
.BYTE 0
MENUID .BYTE KEY1,KEY2,KEY3 ;menu id table
.IF ROM16K = 1
.BYTE KEY4
.ENDC
.BYTE KEY5
.IF BURNIN = 1
.BYTE KEY6
.ENDC
.BYTE KEY7
.ENDC
.IF ROM16K = 1
.IF FULLSCC = 0
NOTAMSG .ASCII 'NOT YET AVAILABLE'
.BYTE 0
.ENDC
TSTMENU .ASCII '1 - ROM'
.BYTE RET
.ASCII '2 - MMU'
.BYTE RET
.ASCII '3 - VIDEO' ;RM000
.BYTE RET
.ASCII '4 - PARITY' ;RM000
.BYTE RET
.ASCII '5 - PARA VIA' ;RM000
.BYTE RET
.ASCII '6 - KYBD VIA' ;RM000
.BYTE RET
.ASCII '7 - COPS'
.BYTE RET
.ASCII '8 - SCC'
.BYTE RET
.ASCII '9 - DISK'
.BYTE RET
.ASCII 'A - CLOCK'
.BYTE RET
.ASCII 'B - MEMORY'
.BYTE RET
.ASCII 'C - IO SLOTS'
.BYTE 0
.ENDC
.IF USERINT = 0
ADDRMSG .ASCII 'ADDRESS?>'
.BYTE 0
DATAMSG .ASCII 'DATA ? >'
.BYTE 0
CNTMSG .ASCII 'COUNT ? >'
.BYTE 0
DRVMSG .ASCII 'DRIVE ? >'
.BYTE 0
DVCEMSG .ASCII 'DEVICE ?>'
.BYTE 0
TSTMSG .ASCII 'TEST ? >'
.BYTE 0
.ELSE
ADDRMSG .ASCII 'ADDRESS ?'
.BYTE 0
DATAMSG .ASCII 'DATA ?'
.BYTE 0
CNTMSG .ASCII 'COUNT ?'
.BYTE 0
TSTMSG .ASCII 'TEST ?'
.BYTE 0
.ENDC
WHATMSG .ASCII 'WHAT ?'
.BYTE 0
.ENDC ;{ROM4K}
.IF ROM4K = 1
.ORG $0FFC
VRSN .WORD $0027 ;version 0.27
.ENDC
.IF ROM8K = 1
.ORG $1FFC
.IF NEWTWIG = 0
VRSN .WORD $0108 ;version 1.08
.ENDC
.IF NEWTWIG = 1
VRSN .WORD $0118 ;version 1.18
.ENDC
.ENDC
.IF ROM16K = 1
.ORG $3FF4 ; CHG005
;************ COPYRIGHT NOTICE ***************************************
HDGMSG .ASCII 'C84APPLE' ; CHG005
;*********************************************************************
VRSN .BYTE $02 ;version 2 CHG001
REV .ASCII 'H' ; rev H CHG001
.ENDC
LAST .WORD $0000 ;checksum word for ROM test
.END