******************************************************************************** * Caverns of Freitag, by David Shapiro * * Copyright 1982 * * * * Disassembly of "AMPER". * ******************************************************************************** * This is a thin wrapper around GRAPHIX II, which loads at $0800. * ******************************************************************************** * Disassembly by Andy McFadden, using 6502bench SourceGen v1.5. * * Last updated 2020/01/21 * ******************************************************************************** ARG_DIST .eq $19 ;LINESET distance ARG_RADIUS .eq $1b ;CIRCLE radius ARG_DRAW_MODE .eq $1c ;0=draw, 1=erase, 2=invert ARG_ANGLE .eq $1d ;LINESET angle arg ARG_ITEM_INDEX .eq $1e ;LINESET/CHARSET item index ARG_COLOR .eq $1f ;0=green, 1=orange, 2=purple, 3=blue BAS_FAC .eq $9d {addr/6} ;floating point accumulator (6b) BAS_TXTPTR .eq $b8 {addr/2} ;points at next char or token (2b) ARG_EXT_PTR .eq $e8 {addr/2} ;pointer to external data ARG_X0 .eq $f9 {addr/2} ;X coord #0 (0-255 or 0-139) ARG_Y0 .eq $fb ;Y coord #0 (0-191) ARG_X1 .eq $fc {addr/2} ;X coord #1 (0-255 or 0-139) ARG_Y1 .eq $fe ;Y coord #1 (0-191) ARG_FF .eq $ff ;shape fill flag -or- CLR color BAS_AMPERV .eq $03f5 {addr/3} ;JMP to function that handles Applesoft '&' cmds DOT .eq $0800 ;plot a single pixel CHKDOT .eq $0806 ;see if a pixel is set LINE .eq $0809 ;draw a line LINESET .eq $080c ;draw lines from a set of vectors CLR .eq $080f ;clear the screen SCFLIP .eq $0812 ;XORs colors on hi-res screen HISCROLL .eq $0815 ;scroll entire screen up one line BOX .eq $0818 ;draw a filled or outline rect SWITCHC .eq $081b ;flip hi bits on DOT drawing CHARSET .eq $081e ;draw dots from bitmap BDRW .eq $0821 ;blit hi-res bitmap CIRCLE .eq $0824 ;draw filled or outline circle PENGUIN .eq $0827 ;draw a penguin (uses CHARSET) CDOT .eq $082a ;plot a colored pixel (140 mode) CLINE .eq $0830 ;draw a colored line CBOX .eq $0833 ;draw a colored box CCHARSET .eq $0836 ;draw colored dots from bitmap HIRES_ .eq $0839 ;switch display to hi-res graphics HROFF .eq $0840 ;switch display to text WINDOW .eq $0844 ;switch display to mixed text/graphics WNDOFF .eq $0848 ;switch display to full-screen graphics DRWPG1 .eq $084c ;draw on page 1 DRWPG2 .eq $0852 ;draw on page 2 DISPPG1 .eq $0858 ;display page 1 DISPPG2 .eq $085c ;display page 2 BAS_ERROR .eq $d412 ;print error based on X-reg BAS_FRMEVL .eq $dd7b ;eval expr at TXTPTR (num/str), result into FAC BAS_CHKCOM .eq $debe ;checks TXTPTR for comma BAS_QINT .eq $ebf2 ;converts FP value in FAC to int in FAC+1..FAC+4 .org $1c91 1c91: a0 02 INIT ldy #$02 ;copy jump instruction to ampersand vector 1c93: b9 9d 1c :Loop lda Vec,y 1c96: 99 f5 03 sta BAS_AMPERV,y 1c99: 88 dey 1c9a: 10 f7 bpl :Loop 1c9c: 60 rts 1c9d: 4c a0 1c Vec jmp MAIN ; Ampersand handler entry point. ; ; Start by figuring out which command is being invoked. ]tmp .var $1c {addr/1} ]cmd_index .var $3a {addr/1} ;MON_PCL 1ca0: a2 00 MAIN ldx #$00 ;X is index into our command table 1ca2: a0 00 ldy #$00 ;Y is index into Applesoft code 1ca4: 84 3a sty ]cmd_index ;number of commands we've scanned 1ca6: b1 b8 :ChkLoop lda (BAS_TXTPTR),y ;get byte from Applesoft 1ca8: 85 1c sta ]tmp ;store it 1caa: bd ea 1c lda CommandNames,x ;get byte from our command list 1cad: f0 1c beq :Error ;if at end of list, bail 1caf: c5 1c cmp ]tmp ;match? 1cb1: d0 04 bne :NoMatch ;nope 1cb3: c8 iny 1cb4: e8 :NextName inx 1cb5: d0 ef bne :ChkLoop ;(always) 1cb7: 29 7f :NoMatch and #$7f ;check again with high bit clear 1cb9: c5 1c cmp ]tmp ;if this works, we matched last byte in string 1cbb: f0 13 beq FoundMatch 1cbd: e6 3a inc ]cmd_index ;increment table index 1cbf: a0 00 ldy #$00 ;reset Y to start 1cc1: a9 80 :SkipLoop lda #$80 ;advance X to the start of the next command name 1cc3: 3d ea 1c and CommandNames,x ;is the high bit set? 1cc6: d0 ec bne :NextName ;yes, return to scan loop 1cc8: e8 inx ;no, keep advancing 1cc9: d0 f6 bne :SkipLoop ;(always) 1ccb: a2 10 :Error ldx #$10 1ccd: 4c 12 d4 jmp BAS_ERROR 1cd0: 18 FoundMatch clc 1cd1: c8 iny 1cd2: 98 tya 1cd3: 65 b8 adc BAS_TXTPTR ;update TXTPTR past the command name in the 1cd5: 85 b8 sta BAS_TXTPTR ; BASIC program 1cd7: 90 02 bcc :NoInc 1cd9: e6 b9 inc BAS_TXTPTR+1 1cdb: 06 3a :NoInc asl ]cmd_index ;double the command index 1cdd: a6 3a ldx ]cmd_index 1cdf: e8 inx 1ce0: bd 78 1d lda AddrTable,x ;look it up in the table 1ce3: 48 pha 1ce4: ca dex 1ce5: bd 78 1d lda AddrTable,x 1ce8: 48 pha 1ce9: 60 rts ; Names for 25 commands. ; ; CF uses the following: ; BOX,A,B,C,D,E,F ; CBOX,A,B,C,D,E,F,G ; CHARSET,A,B,C,D,E ; CLR,0 ; HIRES ; HROFF ; LINESET,A,B,C,D,E,F,G,H ; WINDOW ; WINDOFF 1cea: 43 48 4b 44+ CommandNames .dstr ‘CHKDOT’ 1cf0: 44 4f d4 .dstr ‘DOT’ 1cf3: 4c 49 4e 45+ .dstr ‘LINESET’ 1cfa: 4c 49 4e c5 .dstr ‘LINE’ 1cfe: 43 4c d2 .dstr ‘CLR’ 1d01: 53 43 46 4c+ .dstr ‘SCFLIP’ 1d07: 48 49 53 43+ .dstr ‘HISCROLL’ 1d0f: 42 4f d8 .dstr ‘BOX’ 1d12: 53 57 49 54+ .dstr ‘SWITCHC’ 1d19: 43 48 41 52+ .dstr ‘CHARSET’ 1d20: 42 44 52 d7 .dstr ‘BDRW’ 1d24: 43 49 52 43+ .dstr ‘CIRCLE’ 1d2a: 50 45 4e 47+ .dstr ‘PENGUIN’ 1d31: 43 44 4f d4 .dstr ‘CDOT’ 1d35: 43 4c 49 4e+ .dstr ‘CLINE’ 1d3a: 43 42 4f d8 .dstr ‘CBOX’ 1d3e: 43 43 48 41+ .dstr ‘CCHARSET’ 1d46: 48 49 52 45+ .dstr ‘HIRES’ 1d4b: 48 52 4f 46+ .dstr ‘HROFF’ 1d50: 57 49 4e 44+ .dstr ‘WINDOW’ 1d56: 57 49 4e 44+ .dstr ‘WINDOFF’ 1d5d: 44 52 57 50+ .dstr ‘DRWPG1’ 1d63: 44 52 57 50+ .dstr ‘DRWPG2’ 1d69: 44 49 53 50+ .dstr ‘DISPPG1’ 1d70: 44 49 53 50+ .dstr ‘DISPPG2’ 1d77: 00 .dd1 $00 ; Table of addresses for RTS. This parallels CommandNames. 1d78: d1 1d AddrTable .dd2 Cmd_CHKDOT-1 1d7a: d7 1d .dd2 Cmd_DOT-1 1d7c: f0 1d .dd2 Cmd_LINESET-1 1d7e: e2 1d .dd2 Cmd_LINE-1 1d80: 14 1e .dd2 Cmd_CLR-1 1d82: 1c 1e .dd2 Cmd_SCFLIP-1 1d84: 24 1e .dd2 Cmd_HISCROLL-1 1d86: 27 1e .dd2 Cmd_BOX-1 1d88: 51 1e .dd2 Cmd_SWITCHC-1 1d8a: 3a 1e .dd2 Cmd_CHARSET-1 1d8c: 54 1e .dd2 Cmd_BDRW-1 1d8e: 66 1e .dd2 Cmd_CIRCLE-1 1d90: 7e 1e .dd2 Cmd_PENGUIN-1 1d92: 8f 1e .dd2 Cmd_CDOT-1 1d94: 9d 1e .dd2 Cmd_CLINE-1 1d96: ae 1e .dd2 Cmd_CBOX-1 1d98: c4 1e .dd2 Cmd_CCHARSET-1 1d9a: de 1e .dd2 Cmd_HIRES-1 1d9c: e1 1e .dd2 Cmd_HROFF-1 1d9e: e4 1e .dd2 Cmd_WINDOW-1 1da0: e7 1e .dd2 Cmd_WNDOFF-1 1da2: ea 1e .dd2 Cmd_DRWPG1-1 1da4: ed 1e .dd2 Cmd_DRWPG2-1 1da6: f0 1e .dd2 Cmd_DISPPG1-1 1da8: f3 1e .dd2 Cmd_DISPPG2-1 ; Gets a numeric value from the BASIC program, which must follow a comma. ; ; On exit: ; X-reg: low byte ; Y-reg: high byte • Clear variables 1daa: 20 be de GetCommaInt jsr BAS_CHKCOM 1dad: 20 7b dd jsr BAS_FRMEVL 1db0: 20 f2 eb jsr BAS_QINT 1db3: a6 a1 ldx BAS_FAC+4 1db5: a4 a0 ldy BAS_FAC+3 1db7: 60 rts ; Get a two-byte integer and a one-byte integer. Useful for X,Y coordinates (0- ; 279, 0-191). 1db8: 20 aa 1d GetCoords_X0Y0 jsr GetCommaInt 1dbb: 86 f9 stx ARG_X0 1dbd: 84 fa sty ARG_X0+1 1dbf: 20 aa 1d jsr GetCommaInt 1dc2: 86 fb stx ARG_Y0 1dc4: 60 rts 1dc5: 20 aa 1d GetCoords_X1Y1 jsr GetCommaInt 1dc8: 86 fc stx ARG_X1 1dca: 84 fd sty ARG_X1+1 1dcc: 20 aa 1d jsr GetCommaInt 1dcf: 86 fe stx ARG_Y1 1dd1: 60 rts 1dd2: 20 b8 1d Cmd_CHKDOT jsr GetCoords_X0Y0 1dd5: 4c 06 08 jmp CHKDOT 1dd8: 20 b8 1d Cmd_DOT jsr GetCoords_X0Y0 1ddb: 20 aa 1d jsr GetCommaInt 1dde: 86 1c stx ARG_DRAW_MODE 1de0: 4c 00 08 jmp DOT 1de3: 20 b8 1d Cmd_LINE jsr GetCoords_X0Y0 1de6: 20 c5 1d jsr GetCoords_X1Y1 1de9: 20 aa 1d jsr GetCommaInt 1dec: 86 1c stx ARG_DRAW_MODE 1dee: 4c 09 08 jmp LINE 1df1: 20 8a 1e Cmd_LINESET jsr GetOneInt_1f 1df4: 20 b8 1d jsr GetCoords_X0Y0 1df7: 20 aa 1d jsr GetCommaInt 1dfa: 86 e8 stx ARG_EXT_PTR 1dfc: 84 e9 sty ARG_EXT_PTR+1 1dfe: 20 aa 1d jsr GetCommaInt 1e01: 86 1e stx ARG_ITEM_INDEX 1e03: 20 aa 1d jsr GetCommaInt 1e06: 86 19 stx ARG_DIST 1e08: 20 aa 1d jsr GetCommaInt 1e0b: 86 1d stx ARG_ANGLE 1e0d: 20 aa 1d jsr GetCommaInt 1e10: 86 1c stx ARG_DRAW_MODE 1e12: 4c 0c 08 jmp LINESET 1e15: 20 aa 1d Cmd_CLR jsr GetCommaInt 1e18: 86 ff stx ARG_FF 1e1a: 4c 0f 08 jmp CLR 1e1d: 20 aa 1d Cmd_SCFLIP jsr GetCommaInt 1e20: 86 ff stx ARG_FF 1e22: 4c 12 08 jmp SCFLIP 1e25: 4c 15 08 Cmd_HISCROLL jmp HISCROLL 1e28: 20 b8 1d Cmd_BOX jsr GetCoords_X0Y0 1e2b: 20 c5 1d jsr GetCoords_X1Y1 1e2e: 20 aa 1d jsr GetCommaInt 1e31: 86 1c stx ARG_DRAW_MODE 1e33: 20 aa 1d jsr GetCommaInt 1e36: 86 ff stx ARG_FF 1e38: 4c 18 08 jmp BOX 1e3b: 20 b8 1d Cmd_CHARSET jsr GetCoords_X0Y0 1e3e: 20 aa 1d jsr GetCommaInt 1e41: 86 1e stx ARG_ITEM_INDEX 1e43: 20 aa 1d jsr GetCommaInt 1e46: 86 e8 stx ARG_EXT_PTR 1e48: 84 e9 sty ARG_EXT_PTR+1 1e4a: 20 aa 1d jsr GetCommaInt 1e4d: 86 1c stx ARG_DRAW_MODE 1e4f: 4c 1e 08 jmp CHARSET 1e52: 4c 1b 08 Cmd_SWITCHC jmp SWITCHC 1e55: 20 b8 1d Cmd_BDRW jsr GetCoords_X0Y0 1e58: 20 aa 1d jsr GetCommaInt 1e5b: 86 1e stx ARG_ITEM_INDEX 1e5d: 20 aa 1d jsr GetCommaInt 1e60: 86 e8 stx ARG_EXT_PTR 1e62: 84 e9 sty ARG_EXT_PTR+1 1e64: 4c 21 08 jmp BDRW 1e67: 20 8a 1e Cmd_CIRCLE jsr GetOneInt_1f 1e6a: 20 b8 1d jsr GetCoords_X0Y0 1e6d: 20 aa 1d jsr GetCommaInt 1e70: 86 1b stx ARG_RADIUS 1e72: 20 aa 1d jsr GetCommaInt 1e75: 86 1c stx ARG_DRAW_MODE 1e77: 20 aa 1d jsr GetCommaInt 1e7a: 86 ff stx ARG_FF 1e7c: 4c 24 08 jmp CIRCLE 1e7f: 20 b8 1d Cmd_PENGUIN jsr GetCoords_X0Y0 1e82: 20 aa 1d jsr GetCommaInt 1e85: 86 1c stx ARG_DRAW_MODE 1e87: 4c 27 08 jmp PENGUIN 1e8a: 20 aa 1d GetOneInt_1f jsr GetCommaInt 1e8d: 86 1f stx ARG_COLOR 1e8f: 60 rts 1e90: 20 8a 1e Cmd_CDOT jsr GetOneInt_1f 1e93: 20 b8 1d jsr GetCoords_X0Y0 1e96: 20 aa 1d jsr GetCommaInt 1e99: 86 1c stx ARG_DRAW_MODE 1e9b: 4c 2a 08 jmp CDOT 1e9e: 20 8a 1e Cmd_CLINE jsr GetOneInt_1f 1ea1: 20 b8 1d jsr GetCoords_X0Y0 1ea4: 20 c5 1d jsr GetCoords_X1Y1 1ea7: 20 aa 1d jsr GetCommaInt 1eaa: 86 1c stx ARG_DRAW_MODE 1eac: 4c 30 08 jmp CLINE 1eaf: 20 8a 1e Cmd_CBOX jsr GetOneInt_1f 1eb2: 20 b8 1d jsr GetCoords_X0Y0 1eb5: 20 c5 1d jsr GetCoords_X1Y1 1eb8: 20 aa 1d jsr GetCommaInt 1ebb: 86 1c stx ARG_DRAW_MODE 1ebd: 20 aa 1d jsr GetCommaInt 1ec0: 86 ff stx ARG_FF 1ec2: 4c 33 08 jmp CBOX 1ec5: 20 8a 1e Cmd_CCHARSET jsr GetOneInt_1f 1ec8: 20 b8 1d jsr GetCoords_X0Y0 1ecb: 20 aa 1d jsr GetCommaInt 1ece: 86 1e stx ARG_ITEM_INDEX 1ed0: 20 aa 1d jsr GetCommaInt 1ed3: 86 e8 stx ARG_EXT_PTR 1ed5: 84 e9 sty ARG_EXT_PTR+1 1ed7: 20 aa 1d jsr GetCommaInt 1eda: 86 1c stx ARG_DRAW_MODE 1edc: 4c 36 08 jmp CCHARSET 1edf: 4c 39 08 Cmd_HIRES jmp HIRES_ 1ee2: 4c 40 08 Cmd_HROFF jmp HROFF 1ee5: 4c 44 08 Cmd_WINDOW jmp WINDOW 1ee8: 4c 48 08 Cmd_WNDOFF jmp WNDOFF 1eeb: 4c 4c 08 Cmd_DRWPG1 jmp DRWPG1 1eee: 4c 52 08 Cmd_DRWPG2 jmp DRWPG2 1ef1: 4c 58 08 Cmd_DISPPG1 jmp DISPPG1 1ef4: 4c 5c 08 Cmd_DISPPG2 jmp DISPPG2