back to project page

H Disassembly

                   ********************************************************************************
                   * Starship Commander for the Apple II, by Gilman Louie                         *
                   * Copyright 1981 Voyager Software                                              *
                   *                                                                              *
                   * Disassembly of "H" (hi-res character generator).                             *
                   ********************************************************************************
                   * This is a fairly deluxe HRCG.  It has multiple fonts, a blinking underline   *
                   * cursor, inverse/normal text, the ability to overwrite or blend with existing *
                   * contents, page flipping, and full support for the text window.               *
                   *                                                                              *
                   * The code is nearly identical to the HRCG from the DOS Toolkit, Copyright     *
                   * 1980 Apple Computer, Inc.  Presumably this and a couple of the fonts were    *
                   * licensed from Apple.                                                         *
                   ********************************************************************************
                   * Disassembly by Andy McFadden, using 6502bench SourceGen v1.5.                *
                   * Last updated 2020/01/22                                                      *
                   ********************************************************************************
                   MON_WNDLEFT     .eq     $20               ;left column of scroll window
                   MON_WNDWDTH     .eq     $21               ;width of scroll window
                   MON_WNDTOP      .eq     $22               ;top of scroll window
                   MON_WNDBTM      .eq     $23               ;bottom of scroll window
                   MON_CH          .eq     $24               ;cursor horizontal displacement
                   MON_CV          .eq     $25               ;cursor vertical displacement
                   MON_BASL        .eq     $28               ;base address for text output (lo)
                   MON_BASH        .eq     $29               ;base address for text output (hi)
                   hptr            .eq     $2a    {addr/2}
                   SavedY          .eq     $35
                   MON_CSWL        .eq     $36               ;character output hook (lo)
                   MON_CSWH        .eq     $37               ;character output hook (hi)
                   MON_KSWL        .eq     $38               ;character input hook (lo)
                   MON_KSWH        .eq     $39               ;character input hook (hi)
                   MON_RNDL        .eq     $4e               ;low byte of KEYIN "random" value
                   MON_RNDH        .eq     $4f               ;high byte of KEYIN "random" value
                   SavedX          .eq     $eb
                   hptr2           .eq     $ec    {addr/2}
                   temp            .eq     $ee    {addr/2}
                   SavedAcc        .eq     $ff
                   DOS_CHARIO      .eq     $03ea             ;jumps to routine that connects DOS KSW/CSW
                   KBD             .eq     $c000             ;R last key pressed + 128
                   KBDSTRB         .eq     $c010             ;RW keyboard strobe
                   TXTCLR          .eq     $c050             ;RW display graphics
                   MIXCLR          .eq     $c052             ;RW display full screen
                   TXTPAGE1        .eq     $c054             ;RW display page 1
                   TXTPAGE2        .eq     $c055             ;RW display page 2 (or read/write aux mem)
                   HIRES           .eq     $c057             ;RW display hi-res graphics
                   MON_BELL1       .eq     $fbdd             ;sound bell regardless of output device
                   MON_VTAB        .eq     $fc22             ;tab to row specified in Acc
                   MON_VTABZ       .eq     $fc24
                   MON_CLREOP      .eq     $fc42             ;clear screen from cursor to end of page
                   MON_HOME        .eq     $fc58             ;clear screen and reset text output to top-left
                   MON_SCROLL      .eq     $fc70             ;scroll up one line
                   MON_CLREOL      .eq     $fc9c             ;clear to end of line

                                   .org    $88fe
88fe: 4c 0d 89     INIT            jmp     InitWithBanner    ;called by INTRO

8901: 4c 1e 89                     jmp     Init              ;not used?

8904: 0a                           .dd1    $0a
8905: 68 12        ExtFontBase     .dd2    $1268             ;external font base addr; set by START to $1268

8907: 4c 23 8c     DoReturn1?      jmp     Return

890a: 4c 23 8c     DoReturn2?      jmp     Return

890d: 20 1e 89     InitWithBanner  jsr     Init              ;do regular init
8910: a0 00                        ldy     #$00              ;print the program title
8912: b9 41 89     :Loop           lda     ProgName,y
8915: ea                           nop                       ;NOPs set by START
8916: ea                           nop                       ;this calls MON_COUT in DOS Toolkit version
8917: ea                           nop
8918: c8                           iny
8919: c0 1d                        cpy     #$1d
891b: 90 f5                        bcc     :Loop
891d: 60                           rts

891e: a9 73        Init            lda     #<HandleKbdIn     ;set our code as keyboard input handler
8920: 85 38                        sta     MON_KSWL
8922: a9 89                        lda     #>HandleKbdIn
8924: 85 39                        sta     MON_KSWH
8926: a9 17                        lda     #<HandleCharOut   ;set our code as char output handler
8928: 85 36                        sta     MON_CSWL
892a: a9 8a                        lda     #>HandleCharOut
892c: 85 37                        sta     MON_CSWH
892e: 20 ea 03                     jsr     DOS_CHARIO        ;reconnect DOS
8931: 2c 52 c0                     bit     MIXCLR            ;full screen
8934: 2c 57 c0                     bit     HIRES             ;hi-res
8937: 20 53 8c                     jsr     InitState
893a: 20 0c 8b                     jsr     FlipPage
893d: 2c 50 c0                     bit     TXTCLR            ;graphics mode
8940: 60                           rts

8941: 90           ProgName        .dd1    $90               ;Ctrl+P: clear window
8942: c8 c9 ad d2+                 .str    “HI-RES CHAR GEN VERSION 1.0”,$8d
                   ; Command modifier flags.
895e: 00           EscMode         .dd1    $00               ;$00=normal, $80=ESC mode active
895f: 00           CmdFlags        .dd1    $00               ;$80=font change pending, $40=2nd cmd set
                   ; State reset by initialization ($8960-8972).
8960: 20           HiResPage       .dd1    $20               ;$20 or $40
8961: 00           InvFlag         .dd1    $00               ;$00=normal, $7f=inverse
8962: 00           MixFlag         .dd1    $00               ;$00=overwrite, $80=blend (ORA/AND), $c0=xdraw (EOR)
8963: 00           PageFlipMask    .dd1    $00               ;$00=draw on current page, $60=draw on hidden page
8964: 00           VertWrapFlag    .dd1    $00               ;$00=normal, $ff=wrap to top instead of scroll
8965: 80           LowerCaseFlag   .dd1    $80               ;$00=normal, $80=conv upper to lower, $c0=noconv first
8966: 68 12        FontAddr        .dd2    $1268             ;font address
8968: 00           SavedState      .dd1    $00               ;$8960-8967 copied here
8969: 00                           .dd1    $00
896a: 00                           .dd1    $00
896b: 00                           .dd1    $00
896c: 00                           .dd1    $00
896d: 00                           .dd1    $00
896e: 00                           .dd1    $00
896f: 00                           .dd1    $00
8970: 00           StateSavedFlag  .dd1    $00               ;$00=state not saved, $ff=saved
8971: 00           SavedHtab       .dd1    $00
8972: 00           SavedVtab       .dd1    $00

                   ; Handle request for keyboard input.  Called from monitor RDKEY.
                   ; 
                   ; On entry:
                   ;  A-reg: character under cursor
                   ;  Y-reg: horizontal offset
8973: 91 28        HandleKbdIn     sta     (MON_BASL),y      ;replace flashing text with normal
8975: 86 eb                        stx     SavedX            ;preserve X
8977: a5 28                        lda     MON_BASL
8979: 85 2a                        sta     hptr              ;set up pointer to point at hi-res page
897b: a5 29                        lda     MON_BASH          ; using the text page addr as the base
897d: 09 1c                        ora     #$1c
897f: 0d 60 89                     ora     HiResPage
8982: 85 2b                        sta     hptr+1
8984: a2 01                        ldx     #$01
8986: b1 2a                        lda     (hptr),y          ;save original value
8988: 48                           pha
8989: e6 4e        :InputLoop      inc     MON_RNDL          ;update RNG
898b: d0 0b                        bne     :CheckKbd         ;didn't roll, branch
898d: e6 4f                        inc     MON_RNDH          ;update high byte
898f: ca                           dex                       ;time to invert value?
8990: d0 06                        bne     :CheckKbd         ;nope, not yet
8992: 49 7f                        eor     #$7f              ;yes, invert hi-res byte
8994: 91 2a                        sta     (hptr),y          ;this gives us a blinking underline cursor
8996: a2 50                        ldx     #$50              ;reset timer
8998: 2c 00 c0     :CheckKbd       bit     KBD               ;got input?
899b: 10 ec                        bpl     :InputLoop        ;branch if not yet
899d: 68                           pla
899e: 91 2a                        sta     (hptr),y          ;restore hi-res byte
89a0: ba                           tsx
89a1: bd 04 01                     lda     $0104,x           ;check caller's caller's caller
89a4: c9 f8                        cmp     #$f8              ;in ROM?
89a6: ad 00 c0                     lda     KBD               ;get pending key
89a9: 2c 10 c0                     bit     KBDSTRB           ;clear pending key
89ac: 90 1b                        bcc     :Done             ;not called from ROM, don't do extras
89ae: 48                           pha
89af: 2c 5e 89                     bit     EscMode           ;in ESC mode?
89b2: 30 18                        bmi     HandleEscActions  ;yes, handle ESC Char
89b4: c9 9b                        cmp     #$9b              ;is this ESC?
89b6: d0 07                        bne     :NotEsc           ;nope
89b8: a9 80                        lda     #$80              ;yes, set ESC mode
89ba: 8d 5e 89                     sta     EscMode
89bd: d0 09                        bne     :PlaDone          ;(always)

89bf: c9 8d        :NotEsc         cmp     #$8d              ;is this carriage return?
89c1: d0 05                        bne     :PlaDone          ;no, done
89c3: 20 8c 8d                     jsr     ClearToEol
89c6: a4 24        :LdyPlaDone     ldy     MON_CH            ;restore Y
89c8: 68           :PlaDone        pla                       ;char in A
89c9: a6 eb        :Done           ldx     SavedX            ;restore X
89cb: 60                           rts

                   ; Handle ESC mode actions.  The movement keys are handled by the monitor, but we
                   ; need to drop out of ESC mode after one key if it isn't IJKM, and we need to
                   ; handle things like screen clears and scrolling when we reach the bottom.
                   HandleEscActions
89cc: c9 c9                        cmp     #“I”              ;is char < 'I'?
89ce: 90 0c                        bcc     :NotIJKM          ;yes, so not IJKM
89d0: c9 cd                        cmp     #“M”
89d2: f0 36                        beq     :CursorDown       ;'M' moves cursor down
89d4: b0 06                        bcs     :NotIJKM          ;if > 'M', it's not IJKM
89d6: c9 cb                        cmp     #“K”
89d8: f0 2b                        beq     :CursorRight      ;'K' moves cursor right
89da: 90 ec                        bcc     :PlaDone          ;it's 'I' (up) or 'J' (left), nothing to do
89dc: 0e 5e 89     :NotIJKM        asl     EscMode           ;clear ESC mode
89df: c9 c0                        cmp     #“@”              ;'@' clears the screen
89e1: d0 06                        bne     :NotAt
89e3: 20 6f 8d                     jsr     ClearWindow
89e6: 4c c6 89                     jmp     :LdyPlaDone

89e9: c9 c5        :NotAt          cmp     #“E”              ;'E' clears to end of line
89eb: d0 06                        bne     :NotE
89ed: 20 8c 8d                     jsr     ClearToEol
89f0: 4c c6 89                     jmp     :LdyPlaDone

89f3: c9 c6        :NotE           cmp     #“F”              ;'F' clears to end of screen
89f5: d0 06                        bne     :NotF
89f7: 20 79 8d                     jsr     ClearToEos
89fa: 4c c6 89                     jmp     :LdyPlaDone

89fd: c9 c3        :NotF           cmp     #“C”              ;'C' moves down a line
89ff: f0 09                        beq     :CursorDown
8a01: c9 c1                        cmp     #“A”              ;A=right
8a03: d0 c3                        bne     :PlaDone          ;B=left, D=up
8a05: c8           :CursorRight    iny                       ;check move right
8a06: c4 21                        cpy     MON_WNDWDTH       ;did we reach the right edge of window?
8a08: 90 bc                        bcc     :LdyPlaDone       ;nope, nothing to do
8a0a: a4 25        :CursorDown     ldy     MON_CV            ;check move down
8a0c: c8                           iny
8a0d: c4 23                        cpy     MON_WNDBTM        ;did we reach bottom of window?
8a0f: 90 b5                        bcc     :LdyPlaDone       ;nope, nothing to do
8a11: 20 20 8d                     jsr     ScrollUp          ;scroll entire screen up one line
8a14: 4c c6 89                     jmp     :LdyPlaDone

8a17: 85 ff        HandleCharOut   sta     SavedAcc          ;save A/X/Y
8a19: 86 eb                        stx     SavedX
8a1b: 84 35                        sty     SavedY
8a1d: 20 27 8a                     jsr     OutputChar        ;output character
8a20: a4 35                        ldy     SavedY            ;restore A/X/Y
8a22: a6 eb                        ldx     SavedX
8a24: a5 ff                        lda     SavedAcc
8a26: 60                           rts

8a27: 29 7f        OutputChar      and     #$7f              ;clear high bit
8a29: 0e 5f 89                     asl     CmdFlags          ;are we changing fonts?
8a2c: b0 57                        bcs     SelectFont        ;yes, get the font index
8a2e: c9 20                        cmp     #‘ ’              ;is it a control char?
8a30: 90 03                        bcc     OutputCtrlChar    ;yes
8a32: 4c 7a 8c                     jmp     DoOutput          ;no, just draw it

8a35: c9 1b        OutputCtrlChar  cmp     #$1b              ;is is Ctrl-@ through Ctrl-Z?
8a37: b0 0a                        bcs     :NotSpecial       ;nope
8a39: 0a                           asl     A                 ;get handler address
8a3a: aa                           tax
8a3b: bd 48 8a                     lda     JumpTable+1,x
8a3e: 48                           pha
8a3f: bd 47 8a                     lda     JumpTable,x
8a42: 48                           pha
8a43: 0e 5f 89     :NotSpecial     asl     CmdFlags
8a46: 60                           rts

                   ; Jump table for control commands.
                   ; 
                   ; Printing a control character from Ctrl+A to Ctrl+Z invokes a command.  The
                   ; table below maps characters to code.
                   ; 
                   ; Each letter potentially represents two commands; the second set is used if the
                   ; previous character output was Ctrl+O.  The carry flag will be clear for
                   ; primary set, set for secondary set.
8a47: 45 8b        JumpTable       .dd2    :Return-1         ;80 @: (no-op)
8a49: 7c 8a                        .dd2    SetSelectFontFlag-1 ;81 A: select font (next char is index) | set hpage=1
8a4b: a8 8a                        .dd2    SaveState-1       ;82 B: save state | set hpage=2
8a4d: d0 8a                        .dd2    RestoreHtab-1     ;83 C: restore HTAB | set xdraw/no-flip
8a4f: eb 8a                        .dd2    RestoreState-1    ;84 D: restore state | flip page
8a51: 19 8b                        .dd2    CmdClearToEol-1   ;85 E: clear to end of line | (no-op)
8a53: 21 8b                        .dd2    CmdClearToEos-1   ;86 F: clear to end of screen | (no-op)
8a55: dc fb                        .dd2    MON_BELL1-1       ;87 G: beep
8a57: 29 8b                        .dd2    Backspace-1       ;88 H: backspace | (no-op)
8a59: 3e 8b                        .dd2    SetInvFlag-1      ;89 I: sets inverse flag | (no-op)
8a5b: 02 8d                        .dd2    MoveDown-1        ;8A J: move down a line
8a5d: 46 8b                        .dd2    ClearLowerCaseFlag-1 ;8B K: clear lower-case flag | (no-op)
8a5f: 4e 8b                        .dd2    SetLowerCaseFlag-1 ;8C L: set lower-case flag | (no-op)
8a61: 56 8b                        .dd2    HandleCr-1        ;8D M: carriage return (checks Ctrl+S for pause)
8a63: 71 8b                        .dd2    ClearInvFlag-1    ;8E N: clear inverse flag | (no-op)
8a65: 79 8b                        .dd2    SetSecondCmdFlag-1 ;8F O: next cmd is from 2nd set | set blend/no-flip
8a67: 8c 8b                        .dd2    CmdClearWindow-1  ;90 P: clear window contents | set no-blend/no-flip
8a69: 9d 8b                        .dd2    RestoreVtabHtab-1 ;91 Q: restore saved VTAB/HTAB | (no-op)
8a6b: ac 8b                        .dd2    SetXdrawFlip-1    ;92 R: set xdraw/flip | (no-op)
8a6d: b9 8b                        .dd2    SetLowerCaseSkip-1 ;93 S: lower case conv one char only | clear vert wrap flag
8a6f: c7 8b                        .dd2    SetBlendFlip-1    ;94 T: set blend/flip | (no-op)
8a71: 45 8b                        .dd2    :Return-1         ;95 U: (no-op)
8a73: d4 8b                        .dd2    SetWinTopLeft-1   ;96 V: sets window top/left | (no-op)
8a75: 02 8c                        .dd2    SetWinBotRight-1  ;97 W: sets window bottom/right | set vert wrap flag
8a77: 45 8b                        .dd2    :Return-1         ;98 X: (no-op)
8a79: 29 8c                        .dd2    ResetWindow-1     ;99 Y: reset window to full screen | (special no-op)
8a7b: 50 8c                        .dd2    ReinitState-1     ;9A Z: reinit state | (special no-op)

                   ; Sets the "select font" flag, so we interpret the next character received as
                   ; the font index.
                   SetSelectFontFlag
8a7d: b0 24                        bcs     SetHiResPage1
8a7f: a9 80                        lda     #$80
8a81: 8d 5f 89                     sta     CmdFlags
8a84: 60                           rts

                   ; The previous character was Ctrl+A, so this char is the font index.
8a85: e9 31        SelectFont      sbc     #‘1’              ;change ['1','9'] to [0,8]
8a87: c9 09                        cmp     #$09              ;in range?
8a89: b0 0d                        bcs     SetDefaultFont    ;nope
8a8b: ae 05 89                     ldx     ExtFontBase       ;get low byte (always the same)
8a8e: 85 ee                        sta     temp              ;multiply value by 3
8a90: 0a                           asl     A
8a91: 65 ee                        adc     temp
8a93: 6d 06 89                     adc     ExtFontBase+1     ;add it to base ($300 per font)
8a96: d0 04                        bne     :SetFont
8a98: a2 fe        SetDefaultFont  ldx     #<DefaultFont
8a9a: a9 8d                        lda     #>DefaultFont
8a9c: 8e 66 89     :SetFont        stx     FontAddr          ;set new font address
8a9f: 8d 67 89                     sta     FontAddr+1
8aa2: 60                           rts

8aa3: a9 20        SetHiResPage1   lda     #$20
8aa5: 8d 60 89                     sta     HiResPage
8aa8: 60                           rts

8aa9: b0 20        SaveState       bcs     SetHiResPage2
8aab: 2c 70 89                     bit     StateSavedFlag    ;do we have saved state?
8aae: 30 10                        bmi     :HaveState        ;yes, just update VTAB/HTAB
8ab0: a9 ff                        lda     #$ff              ;no, set flag and copy state
8ab2: 8d 70 89                     sta     StateSavedFlag
8ab5: a0 07                        ldy     #$07
8ab7: b9 60 89     :Loop           lda     HiResPage,y
8aba: 99 68 89                     sta     SavedState,y
8abd: 88                           dey
8abe: 10 f7                        bpl     :Loop
8ac0: a5 24        :HaveState      lda     MON_CH            ;copy HTAB/VTAB to save area
8ac2: 8d 71 89                     sta     SavedHtab
8ac5: a5 25                        lda     MON_CV
8ac7: 8d 72 89                     sta     SavedVtab
8aca: 60                           rts

8acb: a9 40        SetHiResPage2   lda     #$40
8acd: 8d 60 89                     sta     HiResPage
8ad0: 60                           rts

8ad1: b0 0e        RestoreHtab     bcs     SetXdrawNoFlip
8ad3: ad 71 89                     lda     SavedHtab         ;? not entirely sure what this does
8ad6: c5 24                        cmp     MON_CH
8ad8: 85 24                        sta     MON_CH
8ada: f0 02                        beq     :LE               ;if saved is <= HTAB, move down
8adc: b0 68                        bcs     :Return
8ade: 4c 03 8d     :LE             jmp     MoveDown

8ae1: a9 c0        SetXdrawNoFlip  lda     #$c0
8ae3: 8d 62 89                     sta     MixFlag
8ae6: a9 00                        lda     #$00
8ae8: 8d 63 89                     sta     PageFlipMask
8aeb: 60                           rts

8aec: b0 1e        RestoreState    bcs     FlipPage
8aee: 2c 70 89                     bit     StateSavedFlag    ;is there state to restore?
8af1: 10 53                        bpl     :Return           ;no, bail
8af3: a0 07                        ldy     #$07
8af5: b9 68 89     :Loop           lda     SavedState,y
8af8: 99 60 89                     sta     HiResPage,y
8afb: 88                           dey
8afc: 10 f7                        bpl     :Loop
8afe: a9 00                        lda     #$00
8b00: 8d 70 89                     sta     StateSavedFlag    ;clear flag
8b03: 8d 71 89                     sta     SavedHtab         ;reset saved HTAB/VTAB
8b06: a5 22                        lda     MON_WNDTOP
8b08: 8d 72 89                     sta     SavedVtab
8b0b: 60                           rts

                   ; Displays hi-res page 1 or 2 based on current page setting.
8b0c: 2c 54 c0     FlipPage        bit     TXTPAGE1
8b0f: ad 60 89                     lda     HiResPage
8b12: c9 40                        cmp     #$40
8b14: d0 30                        bne     :Return
8b16: 2c 55 c0                     bit     TXTPAGE2
8b19: 60                           rts

8b1a: b0 2a        CmdClearToEol   bcs     :Return
8b1c: 20 8c 8d                     jsr     ClearToEol
8b1f: 4c 9c fc                     jmp     MON_CLREOL

8b22: b0 22        CmdClearToEos   bcs     :Return
8b24: 20 79 8d                     jsr     ClearToEos
8b27: 4c 42 fc                     jmp     MON_CLREOP

8b2a: c6 24        Backspace       dec     MON_CH            ;reduce HTAB
8b2c: 10 18                        bpl     :Return           ;if >= 0, done
8b2e: a5 21                        lda     MON_WNDWDTH       ;set HTAB to window width
8b30: 85 24                        sta     MON_CH
8b32: c6 24                        dec     MON_CH
8b34: a5 22                        lda     MON_WNDTOP        ;back up one line if not yet at top
8b36: c5 25                        cmp     MON_CV
8b38: b0 0c                        bcs     :Return
8b3a: c6 25                        dec     MON_CV
8b3c: 4c 22 fc                     jmp     MON_VTAB          ;update monitor VTAB

8b3f: b0 05        SetInvFlag      bcs     :Return
8b41: a9 7f                        lda     #$7f
8b43: 8d 61 89                     sta     InvFlag
8b46: 60           :Return         rts

                   ClearLowerCaseFlag
8b47: b0 fd                        bcs     :Return
8b49: a9 00                        lda     #$00
8b4b: 8d 65 89                     sta     LowerCaseFlag
8b4e: 60                           rts

                   SetLowerCaseFlag
8b4f: b0 f5                        bcs     :Return
8b51: a9 80                        lda     #$80
8b53: 8d 65 89                     sta     LowerCaseFlag
8b56: 60                           rts

8b57: ac 00 c0     HandleCr        ldy     KBD               ;key pending?
8b5a: 10 13                        bpl     :NoKey            ;nope
8b5c: c0 93                        cpy     #$93              ;Ctrl+S?
8b5e: d0 0f                        bne     :NoKey            ;nope
8b60: 2c 10 c0                     bit     KBDSTRB           ;clear key
8b63: ac 00 c0     :Loop           ldy     KBD               ;wait for another key press
8b66: 10 fb                        bpl     :Loop
8b68: c0 83                        cpy     #$83              ;was it Ctrl+C?
8b6a: f0 03                        beq     :NoKey            ;yes, don't clear it
8b6c: 2c 10 c0                     bit     KBDSTRB           ;no, eat it
8b6f: 4c ff 8c     :NoKey          jmp     MoveToLeftAndDown ;handle CR output

8b72: b0 d2        ClearInvFlag    bcs     :Return
8b74: a9 00                        lda     #$00
8b76: 8d 61 89                     sta     InvFlag
8b79: 60                           rts

                   SetSecondCmdFlag
8b7a: b0 06                        bcs     SetBlendNoFlip
8b7c: a9 40                        lda     #$40
8b7e: 8d 5f 89                     sta     CmdFlags
8b81: 60                           rts

8b82: a9 80        SetBlendNoFlip  lda     #$80
8b84: 8d 62 89                     sta     MixFlag
8b87: a9 00                        lda     #$00
8b89: 8d 63 89                     sta     PageFlipMask
8b8c: 60                           rts

8b8d: b0 06        CmdClearWindow  bcs     SetNoBlendNoFlip
8b8f: 20 6f 8d                     jsr     ClearWindow
8b92: 4c 58 fc                     jmp     MON_HOME

                   SetNoBlendNoFlip
8b95: a9 00                        lda     #$00
8b97: 8d 62 89                     sta     MixFlag
8b9a: 8d 63 89                     sta     PageFlipMask
8b9d: 60                           rts

8b9e: b0 a6        RestoreVtabHtab bcs     :Return
8ba0: ad 71 89                     lda     SavedHtab
8ba3: 85 24                        sta     MON_CH
8ba5: ad 72 89                     lda     SavedVtab
8ba8: 85 25                        sta     MON_CV
8baa: 4c 24 fc                     jmp     MON_VTABZ

8bad: 90 74        SetXdrawFlip    bcc     Return
8baf: a9 c0                        lda     #$c0
8bb1: 8d 62 89                     sta     MixFlag
8bb4: a9 60                        lda     #$60
8bb6: 8d 63 89                     sta     PageFlipMask
8bb9: 60                           rts

                   SetLowerCaseSkip
8bba: b0 06                        bcs     ClearVertWrapFlag
8bbc: a9 c0                        lda     #$c0
8bbe: 8d 65 89                     sta     LowerCaseFlag
8bc1: 60                           rts

                   ClearVertWrapFlag
8bc2: a9 00                        lda     #$00
8bc4: 8d 64 89                     sta     VertWrapFlag
8bc7: 60                           rts

8bc8: 90 59        SetBlendFlip    bcc     Return
8bca: a9 80                        lda     #$80
8bcc: 8d 62 89                     sta     MixFlag
8bcf: a9 60                        lda     #$60
8bd1: 8d 63 89                     sta     PageFlipMask
8bd4: 60                           rts

                   ; Set the window top/left to match current HTAB/VTAB, and reduces width to
                   ; maintain the current right edge.
8bd5: b0 4c        SetWinTopLeft   bcs     Return
8bd7: a5 24                        lda     MON_CH            ;get htab
8bd9: 65 20                        adc     MON_WNDLEFT       ;add current left window posn
8bdb: c9 28                        cmp     #40               ;on screen?
8bdd: 90 02                        bcc     :NotOffRight      ;yes
8bdf: a9 27                        lda     #39               ;no, clamp
8be1: 85 20        :NotOffRight    sta     MON_WNDLEFT       ;set left edge
8be3: 38                           sec
8be4: a5 21                        lda     MON_WNDWDTH       ;update width
8be6: e5 24                        sbc     MON_CH
8be8: 85 21                        sta     MON_WNDWDTH
8bea: a9 00                        lda     #$00              ;set HTAB to 0
8bec: 85 24                        sta     MON_CH
8bee: a5 25                        lda     MON_CV            ;now update window bottom
8bf0: c9 18                        cmp     #24               ;on screen?
8bf2: 90 02                        bcc     :NotOffBottom     ;yes
8bf4: a9 17                        lda     #23               ;no, clamp
8bf6: 85 22        :NotOffBottom   sta     MON_WNDTOP
8bf8: 2c 70 89                     bit     StateSavedFlag    ;do we have saved state?
8bfb: 30 03                        bmi     :Done             ;no, bail
8bfd: 8d 72 89                     sta     SavedVtab         ;yes, update VTAB
8c00: 4c 22 fc     :Done           jmp     MON_VTAB          ;update text routines

8c03: b0 1f        SetWinBotRight  bcs     SetVertWrapFlag
8c05: a5 24                        lda     MON_CH            ;get htab
8c07: 85 21                        sta     MON_WNDWDTH       ;set width
8c09: 65 20                        adc     MON_WNDLEFT
8c0b: c9 28                        cmp     #40               ;on screen?
8c0d: 90 06                        bcc     :OnScreen         ;yes
8c0f: a9 27                        lda     #39               ;no, clamp
8c11: e5 20                        sbc     MON_WNDLEFT
8c13: 85 21                        sta     MON_WNDWDTH       ;update width
8c15: e6 21        :OnScreen       inc     MON_WNDWDTH       ;HTAB starts at 0, width starts at 1
8c17: a5 25                        lda     MON_CV            ;get vtab
8c19: c9 18                        cmp     #24               ;on screen?
8c1b: 90 02                        bcc     :OnScreen         ;yes, good
8c1d: a9 17                        lda     #23               ;no, clamp
8c1f: 85 23        :OnScreen       sta     MON_WNDBTM        ;set window bottom
8c21: e6 23                        inc     MON_WNDBTM        ; to vtab+1
8c23: 60           Return          rts

8c24: a9 ff        SetVertWrapFlag lda     #$ff
8c26: 8d 64 89                     sta     VertWrapFlag
8c29: 60                           rts

8c2a: b0 22        ResetWindow     bcs     CallDoReturn1
8c2c: a5 20        DoResetWindow   lda     MON_WNDLEFT       ;preserve HTAB, which is relative to WNDLEFT
8c2e: 65 24                        adc     MON_CH
8c30: 85 24                        sta     MON_CH
8c32: a9 00                        lda     #$00              ;set left/top to edge of screen
8c34: 85 20                        sta     MON_WNDLEFT
8c36: 85 22                        sta     MON_WNDTOP
8c38: 2c 70 89                     bit     StateSavedFlag    ;do we have saved state?
8c3b: 30 06                        bmi     :HaveState        ;yes, do not disturb
8c3d: 8d 71 89                     sta     SavedHtab
8c40: 8d 72 89                     sta     SavedVtab
8c43: a9 28        :HaveState      lda     #40
8c45: 85 21                        sta     MON_WNDWDTH       ;set with to 40
8c47: a9 18                        lda     #24
8c49: 85 23                        sta     MON_WNDBTM        ;set height to 24
8c4b: 4c 22 fc                     jmp     MON_VTAB          ;update the monitor text routines

8c4e: 4c 07 89     CallDoReturn1   jmp     DoReturn1?

8c51: b0 24        ReinitState     bcs     CallDoReturn2
8c53: a9 00        InitState       lda     #$00              ;zero out $8960-8972
8c55: a0 12                        ldy     #$12
8c57: 99 60 89     :Loop           sta     HiResPage,y
8c5a: 88                           dey
8c5b: 10 fa                        bpl     :Loop
8c5d: 20 2c 8c                     jsr     DoResetWindow
8c60: 20 98 8a                     jsr     SetDefaultFont
8c63: 20 a3 8a                     jsr     SetHiResPage1
8c66: a9 23                        lda     #<Return
8c68: 8d 08 89                     sta     DoReturn1?+1
8c6b: 8d 0b 89                     sta     DoReturn2?+1
8c6e: a9 8c                        lda     #>Return
8c70: 8d 09 89                     sta     DoReturn1?+2
8c73: 8d 0c 89                     sta     DoReturn2?+2
8c76: 60                           rts

8c77: 4c 0a 89     CallDoReturn2   jmp     DoReturn2?

                   ; Copies font data to the screen.
8c7a: 0e 5f 89     DoOutput        asl     CmdFlags          ;check flag for second command set
8c7d: b0 a4                        bcs     Return            ;it's raised; do nothing
8c7f: 2c 65 89                     bit     LowerCaseFlag     ;check lower case flag
8c82: 10 0f                        bpl     :NoConv           ;not set, do nothing
8c84: 50 05                        bvc     :CheckRange       ;set to $80, do conversion
8c86: 0e 65 89                     asl     LowerCaseFlag     ;set to $c0; shift left to make it $80
8c89: b0 08                        bcs     :NoConv           ;(always)
8c8b: c9 41        :CheckRange     cmp     #‘A’              ;< 'A'?
8c8d: 90 04                        bcc     :NoConv           ;yes, don't convert
8c8f: c9 5b                        cmp     #‘[’              ;< 'Z'+1?
8c91: 90 03                        bcc     :NoSub            ;yes, convert to lower by skipping the -$20
8c93: 38           :NoConv         sec                       ;fonts don't store control character, so
8c94: e9 20                        sbc     #$20              ; subtract $20 to find start
8c96: 0a           :NoSub          asl     A                 ;multiply by 8
8c97: 26 ef                        rol     temp+1            ;($ef not initialized, but that's okay)
8c99: 0a                           asl     A
8c9a: 26 ef                        rol     temp+1
8c9c: 0a                           asl     A
8c9d: 26 ef                        rol     temp+1
8c9f: 18                           clc
8ca0: 6d 66 89                     adc     FontAddr          ;add to font address
8ca3: 85 ee                        sta     temp              ;save
8ca5: a5 ef                        lda     temp+1            ;now the high byte of address
8ca7: 29 07                        and     #$07              ;mask off the uninitialized bits
8ca9: 6d 67 89                     adc     FontAddr+1
8cac: 85 ef                        sta     temp+1
8cae: 20 ca 8d                     jsr     GetHiResAddr      ;get address in $2a-2b
8cb1: 65 24                        adc     MON_CH
8cb3: 85 2a                        sta     hptr
8cb5: 85 ec                        sta     hptr2
8cb7: a5 2b                        lda     hptr+1            ;set hptr2 to be the source addr for blending
8cb9: 4d 63 89                     eor     PageFlipMask
8cbc: 85 ed                        sta     hptr2+1
8cbe: a4 24                        ldy     MON_CH            ;update text screen
8cc0: a5 ff                        lda     SavedAcc
8cc2: 91 28                        sta     (MON_BASL),y
                   ; Copy 8 bytes from the font to the screen.  If we're merging with the existing
                   ; contents, we pull them from hptr2, which may be the other page.
8cc4: a2 00                        ldx     #$00              ;always 0; "OP (dp)" introduced in 65c02
8cc6: a0 00                        ldy     #$00
8cc8: b1 ee        :Loop           lda     (temp),y
8cca: 4d 61 89                     eor     InvFlag
8ccd: 2c 62 89                     bit     MixFlag           ;how should we mix with existing pixels?
8cd0: 10 11                        bpl     :DoStore          ;overwrite
8cd2: 70 0d                        bvs     :DoXdraw          ;xdraw
8cd4: 2c 61 89                     bit     InvFlag           ;is inverse flag set?
8cd7: 70 04                        bvs     :DoInvMerge       ;yes, AND our bits with the screen
8cd9: 01 ec                        ora     (hptr2,x)         ;no, OR our bits with the screen
8cdb: 50 06                        bvc     :DoStore

8cdd: 21 ec        :DoInvMerge     and     (hptr2,x)
8cdf: 70 02                        bvs     :DoStore          ;(always)

8ce1: 41 ec        :DoXdraw        eor     (hptr2,x)
8ce3: 81 2a        :DoStore        sta     (hptr,x)          ;store merged value
8ce5: c8                           iny
8ce6: c0 08                        cpy     #$08              ;did 8 lines?
8ce8: b0 0d                        bcs     :CopyDone         ;yes
8cea: a5 2b                        lda     hptr+1            ;no, update hi-res addresses
8cec: 69 04                        adc     #$04              ;(within an aligned 8-line range, just add 4 to hi)
8cee: 85 2b                        sta     hptr+1
8cf0: 4d 63 89                     eor     PageFlipMask
8cf3: 85 ed                        sta     hptr2+1
8cf5: 90 d1                        bcc     :Loop             ;(always)
8cf7: e6 24        :CopyDone       inc     MON_CH            ;advance HTAB
8cf9: a5 24                        lda     MON_CH
8cfb: c5 21                        cmp     MON_WNDWDTH       ;reached right edge?
8cfd: 90 20                        bcc     :Return           ;no, good
                   MoveToLeftAndDown
8cff: a9 00                        lda     #$00              ;set HTAB to left edge
8d01: 85 24                        sta     MON_CH
8d03: e6 25        MoveDown        inc     MON_CV            ;advance to next line
8d05: a5 25                        lda     MON_CV
8d07: c5 23                        cmp     MON_WNDBTM        ;hit bottom?
8d09: 90 11                        bcc     :NotBottom        ;no
8d0b: 2c 64 89                     bit     VertWrapFlag      ;yes, should we scroll?
8d0e: 70 08                        bvs     :NoScroll         ;no
8d10: c6 25                        dec     MON_CV            ;yes, dec VTAB so we're back on screen
8d12: 20 20 8d                     jsr     ScrollUp          ;redraw screen contents
8d15: 4c 70 fc                     jmp     MON_SCROLL        ;scroll text screen

8d18: a5 22        :NoScroll       lda     MON_WNDTOP        ;get window top
8d1a: 85 25                        sta     MON_CV            ;store in VTAB
8d1c: 20 24 fc     :NotBottom      jsr     MON_VTABZ         ;update monitor text routines
8d1f: 60           :Return         rts

                   ; Scrolls the current text window up one line.
8d20: a5 22        ScrollUp        lda     MON_WNDTOP        ;get top row
8d22: 48                           pha
8d23: 20 cc 8d                     jsr     GetHiResAddrA     ;get hi-res base address for row + window left
8d26: a5 2a        :TextLineLoop   lda     hptr              ;this will be the destination row
8d28: 85 ec                        sta     hptr2             ;copy to hptr2
8d2a: a5 2b                        lda     hptr+1
8d2c: 29 e3                        and     #$e3              ;for 2nd and later iterations, reset to top of 8-row
8d2e: 85 ed                        sta     hptr2+1           ; section
8d30: 68                           pla
8d31: 18                           clc
8d32: 69 01                        adc     #$01
8d34: c5 23                        cmp     MON_WNDBTM        ;have we reached the bottom row?
8d36: b0 22                        bcs     :CopyDone         ;yes, done
8d38: 48                           pha
8d39: 20 cc 8d                     jsr     GetHiResAddrA     ;get hi-res base address for source row
8d3c: a2 07                        ldx     #$07              ;copy 8 rows
8d3e: a4 21        :RowLoop        ldy     MON_WNDWDTH       ;from right to left
8d40: 88                           dey
8d41: b1 2a        :ColLoop        lda     (hptr),y
8d43: 91 ec                        sta     (hptr2),y
8d45: 88                           dey
8d46: 10 f9                        bpl     :ColLoop
8d48: ca                           dex
8d49: 30 db                        bmi     :TextLineLoop     ;if all rows done, move on to next line of text
8d4b: 18                           clc                       ;advance pointers to next row
8d4c: a5 2b                        lda     hptr+1
8d4e: 69 04                        adc     #$04
8d50: 85 2b                        sta     hptr+1
8d52: a5 ed                        lda     hptr2+1
8d54: 69 04                        adc     #$04
8d56: 85 ed                        sta     hptr2+1
8d58: d0 e4                        bne     :RowLoop
8d5a: ad 62 89     :CopyDone       lda     MixFlag           ;save MixFlag
8d5d: 48                           pha
8d5e: a5 23                        lda     MON_WNDBTM        ;clear last line
8d60: e9 01                        sbc     #$01
8d62: a0 00                        ldy     #$00              ;always clear
8d64: 8c 62 89                     sty     MixFlag
8d67: 20 90 8d                     jsr     ClearToEol2       ;A=row, Y=col
8d6a: 68                           pla
8d6b: 8d 62 89                     sta     MixFlag           ;restore MixFlag
8d6e: 60                           rts

8d6f: a5 22        ClearWindow     lda     MON_WNDTOP        ;start from the top of the window
8d71: 85 25                        sta     MON_CV
8d73: a0 00                        ldy     #$00
8d75: 84 24                        sty     MON_CH
8d77: f0 04                        beq     :LineLoop

8d79: a4 24        ClearToEos      ldy     MON_CH            ;start from current VTAB/HTAB
8d7b: a5 25                        lda     MON_CV
8d7d: 48           :LineLoop       pha
8d7e: 20 90 8d                     jsr     ClearToEol2
8d81: 68                           pla
8d82: 18                           clc
8d83: 69 01                        adc     #$01
8d85: c5 23                        cmp     MON_WNDBTM
8d87: a0 00                        ldy     #$00
8d89: 90 f2                        bcc     :LineLoop
8d8b: 60                           rts

8d8c: a4 24        ClearToEol      ldy     MON_CH
8d8e: a5 25                        lda     MON_CV
                   ; Clear from the current position (VTAB in A-reg, HTAB in Y-reg) to the end of
                   ; the line by drawing individual bytes, obeying the inverse and mix flags as
                   ; well as the page flip mode.
                   ; 
                   ; On exit, Y will have its initial value.
8d90: 84 ee        ClearToEol2     sty     temp              ;save Y-reg
8d92: 20 cc 8d                     jsr     GetHiResAddrA     ;get address in $2a-2b for line in A-reg
8d95: a2 07                        ldx     #$07              ;write 8 bytes
8d97: ad 61 89     :Loop           lda     InvFlag           ;clear to $00 or $7f
8d9a: 2c 62 89                     bit     MixFlag           ;check mix mode
8d9d: 10 15                        bpl     :DoDraw           ;branch if overwrite
8d9f: a5 2a                        lda     hptr              ;set up alternate page source for blend modes
8da1: 85 ec                        sta     hptr2
8da3: a5 2b                        lda     hptr+1
8da5: 4d 63 89                     eor     PageFlipMask
8da8: 85 ed                        sta     hptr2+1
8daa: b1 ec                        lda     (hptr2),y         ;get current data
8dac: 2c 62 89                     bit     MixFlag
8daf: 50 03                        bvc     :DoDraw           ;blend mode, keep existing
8db1: 4d 61 89                     eor     InvFlag           ;invert if invert flag set
8db4: 91 2a        :DoDraw         sta     (hptr),y
8db6: c8                           iny
8db7: c4 21                        cpy     MON_WNDWDTH       ;reached right edge of window?
8db9: 90 dc                        bcc     :Loop             ;not yet
8dbb: ca                           dex                       ;done 8 bytes?
8dbc: 30 0b                        bmi     :Done             ;yes, bail
8dbe: a4 ee                        ldy     temp              ;advance hptr
8dc0: a5 2b                        lda     hptr+1
8dc2: 18                           clc
8dc3: 69 04                        adc     #$04
8dc5: 85 2b                        sta     hptr+1
8dc7: d0 ce                        bne     :Loop             ;(always)
8dc9: 60           :Done           rts

                   ; Gets the hi-res base address, and stores it in $2a-2b.
8dca: a5 25        GetHiResAddr    lda     MON_CV            ;get VTAB (0-23)
8dcc: 4a           GetHiResAddrA   lsr     A                 ;do some math to get hi-res base address
8dcd: aa                           tax
8dce: 29 03                        and     #$03
8dd0: 0d 60 89                     ora     HiResPage
8dd3: 85 2b                        sta     hptr+1
8dd5: bd de 8d                     lda     HiResAddrLo,x     ;table lookups make the math easier
8dd8: 6a                           ror     A
8dd9: 65 20                        adc     MON_WNDLEFT       ;add window left
8ddb: 85 2a                        sta     hptr
8ddd: 60                           rts

8dde: 00 00 00 00+ HiResAddrLo     .bulk   0000000050505050a0a0a0a0
8dea: b9 a2 a0 d2+                 .bulk   b9a2a0d2e9a0f2a0a5b9c180c4cda08ca0aca0a0 ;unused?

                   vis
8dfe: 00 00 00 00+ DefaultFont     .bulk   00000000000000000808080808000800141414000000000014143e143e141400
                                    +      083c0a1c281e08000626100804323000040a0a042a122c000808080000000000
                                    +      08040202020408000810202020100800082a1c081c2a08000008083e08080000
                                    +      00000000080804000000003e0000000000000000000008000020100804020000
                                    +      1c22322a26221c00080c080808081c001c22201804023e003e20101820221c00
                                    +      101814123e1010003e021e2020221c003804021e22221c003e20100804040400
                                    +      1c22221c22221c001c22223c20100e0000000800080000000000080008080400
                                    +      100804020408100000003e003e00000004081020100804001c22100808000800
                                    +      1c222a3a1a023c00081422223e2222001e22221e22221e001c22020202221c00
                                    +      1e22222222221e003e02021e02023e003e02021e020202003c02020232223c00
                                    +      2222223e222222001c08080808081c002020202020221c0022120a060a122200
                                    +      0202020202023e0022362a2a222222002222262a322222001c22222222221c00
                                    +      1e22221e020202001c2222222a122c001e22221e0a1222001c22021c20221c00
                                    +      3e080808080808002222222222221c0022222222221408002222222a2a362200
                                    +      222214081422220022221408080808003e20100804023e003e06060606063e00
                                    +      00020408102000003e30303030303e000000081422000000000000000000007f
                                    +      040810000000000000001c203c223c0002021e2222221e0000003c0202023c00
                                    +      20203c2222223c0000001c223e023c001824041e0404040000001c22223c201c
                                    +      02021e222222220008000c0808081c00100018101010120c020222120e122200
                                    +      0c08080808081c000000362a2a2a220000001e222222220000001c2222221c00
                                    +      00001e22221e020200003c22223c202000003a060202020000003c021c201e00
                                    +      04041e04042418000000222222322c000000222222140800000022222a2a3600
                                    +      000022140814220000002222223c201c00003e1008043e00380c0c060c0c3800
                                    +      08080808080808080e18183018180e002c1a0000000000007f7f7f7f7f7f7f7f

Symbol Table

INIT$88fe