STARGO ====== Assembly listing generated by TurboMASM from the modified Acorn source. Source: https://www.4corn.co.uk/articles/65hostandmos/ Source: http://regregex.bbcmicro.net/#prog.os126 Source: https://github.com/regregex/OS126 Branch slack calculated by Greg Cook with slack.pl (attached), 25 January 2025 Columns, left to right: (1) Filename, (2) line number and (3) hex address of limiting branch instruction (4) Direction of limiting branch: ^=backwards, v=forwards, Space=N/A (5) Hex number of bytes that may be inserted at this address, or between the branch instruction and the target SYMBOL at this address (NB: a more generous limit than shown may apply on the far side of the symbol.) --=no limit. (6) Current source filename, (7) line of assembly listing which typically starts with source line number, hex address and optional hex equate. *emulateturbo Acorn 6502 Tube 6502 Emulator OS 0.64 (19 Oct 1988) HIBASIC >*turmasm TURBOMASM Acorn Macro assembler 1.15 Action : width 127 Action : length 127 Action : stop on Action : print on Action : asm SgoHdr Macro library : Acorn macro assembler Page 1 Pass 1 Pass 2 0001 0000 ; > SgoHdr 0002 0000 0003 0000 GBLL $Tutu 0004 0000 $Tutu SETL 1=0 0005 0000 0006 0000 ; conditional assembly flags 0007 0000 007F MOS125 * &7F 0008 0000 0000 STARGO * &00 0009 0000 00FF NOSP * &FF 0010 0000 ; ($00 => TRUE, $FF => FALSE) 0011 0000 0012 0000 ; special labels for STARGO 0013 0000 00DC SEAL * &DC 0014 0000 ;The value to be returned in A by OSARGS A=1, Y=0 0015 0000 ;when trapped by MOS/CFS/RFS. 0016 0000 ;MSRM says to preserve A (p. H.3-5), i.e. A=1 0017 0000 ;however MOS 3.20 breaks the spec and returns A=&DC, mainly. 0018 0000 ;This is just a copy of the 3MSB of the pointer at X+1. 0019 0000 ;NAUG says A is undefined (p.253); other unofficial sources 0020 0000 ;suggest that implemented OSARGS calls *should not* 0021 0000 ;preserve A. 0022 0000 0023 0000 02D0 TAILLO * &02D0 0024 0000 02D1 TAILHI * &02D1 0025 0000 ;Locations to store the command line tail pointer from *GO 0026 0000 ;and *RUN. Need not be adjacent. Formerly buffer activity 0027 0000 ;flags that are free in OS 1.26. 0028 0000 0029 0000 LNK MOS00 0001 0000 0002 0000 TTL VDU File -> MOS00 0003 0000 OPT &01 0004 0000 0005 0000 ; 0006 0000 ; MASM options 0007 0000 ; 0008 0000 0004 OPNEWP * &04 ;new page 0009 0000 0001 OPPON * &01 ;print on 0010 0000 0002 OPPOFF * &02 ;print off 0011 0000 ; 0012 0000 ; module print selections 0013 0000 ; 0014 0000 0005 DEFOPT * OPPON:OR:OPNEWP ;default option for MOS code 0015 0000 0005 MOS00 * DEFOPT 0016 0000 0005 MOS01 * DEFOPT 0017 0000 0005 MOS02 * DEFOPT 0018 0000 0005 MOS03 * DEFOPT 0019 0000 0005 MOS04 * DEFOPT 0020 0000 0005 MOS05 * DEFOPT 0021 0000 0005 MOS06 * DEFOPT 0022 0000 0005 MOS07 * DEFOPT 0023 0000 0005 MOS08 * DEFOPT 0024 0000 0025 0000 0005 MOS10 * DEFOPT 0026 0000 0005 MOS11 * DEFOPT 0027 0000 0028 0000 OPT MOS00 Acorn macro assembler Page 2 VDU File -> MOS00 0029 0000 0030 0000 00F0 WARGS * &00F0 0031 0000 00FA SEIWKA * &00FA 0032 0000 00FB SEIWKB * &00FB 0033 0000 0034 0000 ;Last updated 01/08/82 0035 0000 0036 0000 ;01/08/82 Intro of SEIWKA and SEIWKB to fix palette IRQ problem 0037 0000 ;01/05/82 Order of variables changed. Pseudo op # used. 0038 0000 ;21/04/82 QPOSN removed completely 0039 0000 ;25/03/82 Low byte of BEGSCN replaced with BYTCH (it was always zero) 0040 0000 ;04/02/82 QPOSN moved to MOS 0041 0000 ;07/01/82 VDUVEC removed (to $222 in MOS) 0042 0000 ;14/11/81 DOTS removed 0043 0000 0044 0000 ;VARIABLES, NOT ZERO PAGE 0045 0000 0046 0000 ;CHARACTER FONTS 0047 0000 0048 0000 BF00 HFONT * &BF00 0049 0000 00BF HFMSB * /(HFONT ) ;MSB of HFONT 0050 0000 0051 0000 ;VARIABLES PROPER 0052 0000 0053 0000 0054 0000 0300 VARBLE * &0300 0055 0000 0300 V * VARBLE ;An abbreviation 0056 0000 0057 0000 0058 0000 ^ VARBLE 0059 0000 0060 0000 0300 GWLCOL # &02 ;Row no. of LH margin of graphics window (internal repn.) 0061 0000 0302 GWBROW # &02 ;Row no. of bottom margin of graphics window (internal repn.) 0062 0000 0304 GWRCOL # &02 ;Col no. of RH margin of graphics window (internal repn.) 0063 0000 0306 GWTROW # &02 ;Row no. of top margin of graphics window (internal repn.) 0064 0000 0308 TWLCOL # &01 ;Column number of left margin of text window 0065 0000 0309 TWBROW # &01 ;Row number of bottom margin of text window 0066 0000 030A TWRCOL # &01 ;Column number of right margin of text window 0067 0000 030B TWTROW # &01 ;Row number of top margin of text window 0068 0000 030C ORGX # &02 ;Screen origin (external represntation) 0069 0000 030E ORGY # &02 0070 0000 0310 GCSX # &02 ;Graphics cursor (external representation) 0071 0000 0312 GCSY # &02 0072 0000 0314 OLDCS # &04 ;Old graphics cursor 0073 0000 0318 CSX # &01 ;Text cursor posn (screen relative) 0074 0000 0319 CSY # &01 0075 0000 031A YLINE # &01 ;Offset from ZMEMG for current graphics point 0076 0000 031B QQ # &08 ;Queue 0077 0000 0323 QEND # &01 ;Last byte in queue 0078 0000 0324 GCSIX # &02 ;Graphics cursor (internal representation) 0079 0000 0326 GCSIY # &02 0080 0000 0328 VDUWS # &22 ;Workspace for VDU 0081 0000 034A CSPOSN # &02 ;Memory of top byte of character at cursor 0082 0000 034C PWWDTH # &02 ;Text window width in bytes 0083 0000 034E BEGSCN # &01 ;MSByte of Lowest byte address displayed 0084 0000 034F BYTCH # &01 ;No bytes per character displayed 0085 0000 0350 TOPSCN # &02 ;Address of top left byte on screen 0086 0000 0352 BYTROW # &02 ;Bytes per row 0087 0000 0354 BYTSCN # &01 ;Bytes used for screen display 0088 0000 0355 MODE # &01 ;Current VDU mode (0..7) 0089 0000 0356 MEMODE # &01 ;Memory map type (0..4) 0090 0000 ;STATS # $01 ;Individual bits used for various things - see docn. for details 0091 0000 0357 FTCOLF # &01 ;Next four must be in this order Foreground text colour 0092 0000 0358 BTCOLF # &01 ;Background text colour 0093 0000 0359 FGCOLF # &01 ;Foreground graphics colour 0094 0000 035A BGCOLF # &01 ;Background graphics colour 0095 0000 035B GPLFMD # &01 ;Current graphics foreground plot colour 0096 0000 035C GPLBMD # &01 ;Current graphics background plot colour 0097 0000 035D JVEC # &02 ;Jump vector for JMIs 0098 0000 035F CSTEMP # &01 ;Cursor start register of 6845 0099 0000 0360 NCOLOR # &01 ;No. colours available (=0 for TTX) 0100 0000 0361 NPIX # &01 ;No. pixels per byte (=0 for non-graphics mode) 0101 0000 0362 MASKL # &01 ;Mask for left most pixel in byte 0102 0000 0363 MASKR # &01 ;Mask for right most pixel in byte 0103 0000 0364 PCSX # &01 ;Print cursor x position 0104 0000 0365 PCSY # &01 ;Print cursor y position 0105 0000 0366 CHCSR # &01 ;Character which is the displayed cursor on print line 0106 0000 0367 FNTFLG # &01 ;Default font flags, 0 for hard font, p.1=b6 .. p.7=b0 0107 0000 0368 PGSFNT # &07 ;Page addresses for the soft font $20 - $3F & etc. 0108 0000 036F PARROT # &10 ;Storage of 16 physical colours 0109 0000 037F VEND # &00 ;End of the variables 0110 0000 0111 0000 ; ************************** MANIFESTS **************************** 0112 0000 0113 0000 0114 0000 ^ VDUWS 0115 0000 0328 DLEWS # &08 ;Workspace for DLE 0116 0000 0330 DLENLN # &01 0117 0000 0118 0000 ^ VDUWS 0119 0000 0328 CANWS # &04 ;Workspace for CAN 0120 0000 032C CDELTA # &04 0121 0000 0122 0000 ^ VDUWS 0123 0000 0328 USWS # &02 ;Workspace for US 0124 0000 0125 0000 ^ VDUWS 0126 0000 0328 SSWS # &02 ;Workspace for soft scrolling 0127 0000 0128 0000 ^ VDUWS 0129 0000 0328 APCS1 # &04 ;Workspace for anomalous printing 0130 0000 0131 0000 ^ VDUWS 0132 0000 0328 READWS # &08 ;Intermediate bit pattern formed during READCH 0133 0000 0134 0000 ^ VDUWS 0135 0000 0328 RPXLWS # &04 ;Workspace for read pixel 0136 0000 0137 0000 ;For graphics in general 0138 0000 0139 0000 030C ORG * ORGX ;Graphics origin 0140 0000 0310 GCSR * GCSX ;Graphics external cursor 0141 0000 0324 GCSIR * GCSIX ;Graphics internal cursor 0142 0000 0320 NEWPT * QEND-&03 ;New point introduced by call to routine. Multiple of 8 ! 0143 0000 031F PLMODE * QEND-&04 ;Plot mode 0144 0000 0145 0000 ;Plotting lines 0146 0000 0147 0000 ^ VDUWS 0148 0000 0328 LDELTA # &04 ;DeltaX & DeltaY 0149 0000 032C LSTART # &04 ;Start point for line Acorn macro assembler Page 3 VDU File -> MOS00 0150 0000 0330 HEND # &02 ;Horizontal end point 0151 0000 0332 D2JVEC # &02 ;Jump vector for D2 0152 0000 0334 DOTFLG # &01 ;Dotted line flag 0153 0000 0335 LPARMS # &06 ;Parameters for line drawing 0154 0000 0155 0000 ;Plotting triangles 0156 0000 0157 0000 ^ VDUWS 0158 0000 0328 HPARMS # &06 0159 0000 032E HSTART # &04 0160 0000 0332 HDIREC # &01 0161 0000 0333 SPARMS # &06 0162 0000 0339 SSTART # &04 0163 0000 033D SDIREC # &01 0164 0000 033E GCSTMP # &08 0165 0000 0166 0000 032A HDELTA * HPARMS+&02 0167 0000 0335 SDELTA * SPARMS+&02 0168 0000 031B TRINLN * QQ 0169 0000 0170 0000 ;Teletext temp variable for byte hidden by input cursor 0171 0000 0172 0000 0338 TTXTMP * VDUWS+&10 ;as nothing available in TTX uses this much storage 0173 0000 0174 0000 LNK MOS01 0001 0000 0002 0000 TTL VDU File - MOS01 0003 0000 OPT MOS01 Acorn macro assembler Page 4 VDU File - MOS01 0004 0000 0005 0000 < &0001 0006 0000 > &0002 0007 0000 0008 0000 ;Last revision 02/06/82 0009 0000 0010 0000 ;02/06/82 Remove HWMOFS 0011 0000 ;26/05/82 Concatenate TBZGOE & FCOLTB 0012 0000 ;05/05/82 Reverse bytes of multiplication tables TXTTB & HRGTB 0013 0000 ; Delete LRGTB 0014 0000 ;02/05/82 Concatenate TBZGxx tables 0015 0000 ; Change order of D1 & D2 jump tables & EWTBA 0016 0000 ;21/04/82 Colour mode #5 (which gives no change) included in TBZGxx. 0017 0000 ; External entry points provided 0018 0000 ;15/04/82 NPCOL declared 0019 0000 ;24/03/82 Delete DFSFPG as these are calculated at run time 0020 0000 ;22/01/82 Delete PDIVTB, it wasn't referenced 0021 0000 ; Delete READVP entry point & asssociated jump table 0022 0000 ; Change VDUVEC to VDUVEC, prefix all MOS names with m 0023 0000 ; TRMCH fixed as $0D 0024 0000 ; Soft font default now the exploded default 0025 0000 ;07/01/82 Change MODEL & VDUVEC 0026 0000 ;09/11/81 Change to one entry point for read VDU parameters 0027 0000 ;28/10/81 ETB msb changed from $49 to $59 0028 0000 ; Chars $C0-$DF taken from $10 (was $0C) 0029 0000 ; Chars $E0-$FF taken from $0C (was $10) 0030 0000 0031 0000 ; conditional assembly flags 0032 0000 00FF STARTP * &FF ;assume end points plotted twice 0033 0000 0000 PAGEFX * &00 ;Fix bug in page mode (I hope) 0034 0000 ; ($00 => TRUE, $FF => FALSE) 0035 0000 0036 0000 ;ZERO PAGE VARIABLES 0037 0000 0038 0000 ^ &00D0 0039 0000 00D0 STATS # &01 0040 0000 0041 0000 ; 0042 0000 00D1 ZMASK # &01 0043 0000 00D2 ZORA # &01 ;Next four must be in this order 0044 0000 00D3 ZEOR # &01 0045 0000 00D4 ZGORA # &01 0046 0000 00D5 ZGEOR # &01 0047 0000 ; 0048 0000 00D6 ZMEMG # &02 0049 0000 00D8 ZMEMT # &02 ;Immediately before ZTEMP (SSCRS) 0050 0000 00DA ZTEMP # &02 0051 0000 00DC ZTEMPB # &02 0052 0000 00DE ZTEMPC # &02 0053 0000 00E0 ZTBL # &02 0054 0000 0055 0000 ;EQUATE TABLE 0056 0000 0057 0000 0006 ACKASC * &06 ;Ascii value of acknowledge 0058 0000 00FE INBYTE * &FE ;Dummy colour to indicate invert (illegal colour) 0059 0000 0060 0000 0020 TTXBCL * &20 ;Byte to clear screen with in TTX 0061 0000 000D TRMCH * &0D ;Byte to terminate edit mode 0062 0000 000C SFPAGE * &0C ;Page of first definable set of characters 0063 0000 003F INVSXT * &3F ;Used to invert logical colour of mode 2 without touching flash 0064 0000 000F NPCOL * &0F ;number of physical colours - 1 0065 0000 0066 0000 ;MACHINE CONSTANTS 0067 0000 0068 0000 FE00 CRTCA * &FE00 ;6845 address reg. 0069 0000 FE01 CRTCD * &FE01 ;6845 data register 0070 0000 0071 0000 ;ENTRY POINTS 0072 0000 0073 0000 C300 CODE * &C300 0074 0000 00C3 CODORG * /CODE 0075 0000 0076 0000 ORG CODE 0077 C300 0078 C300 4C FA CA JMP RESET ;Reset VDU to mode (A) 0079 C303 ; JMP GADDR 0080 C303 ; JMP WIND 0081 C303 ; JMP EIGABS 0082 C303 ; JMP IEG 0083 C303 ; JMP PLOT 0084 C303 ; JMP HPLOT 0085 C303 ; JMP SETZG 0086 C303 ; JMP RPXLD 0087 C303 0088 C303 ; MOS messages to be written by WRSTR 0089 C303 MSG 0090 C303 MSGBBC ;BBC Computer 0091 C303 0D 42 42 = MCR,"BBC Computer ",0 0092 C312 0093 C312 MSG16K ;16K 0094 C312 31 36 4B = "16K",BEL,0 0095 C317 0096 C317 MSG32K ;32K 0097 C317 33 32 4B = "32K",BEL,0 0098 C31C 0099 C31C MSG2CR 0100 C31C 08 = &08 0101 C31D 0D = &0D 0102 C31E 0D = &0D ;uses the next $00 0103 C31F 0104 C31F ;EXPANDED BIT PATTERN TABLES - must be contiguous 0105 C31F 0106 C31F ;FOUR COLOUR MODE 0107 C31F 0108 C31F 00 BPFTB = &00 0109 C320 11 = &11 0110 C321 22 = &22 0111 C322 33 = &33 0112 C323 44 = &44 0113 C324 55 = &55 0114 C325 66 = &66 0115 C326 77 = &77 0116 C327 88 = &88 0117 C328 99 = &99 0118 C329 AA = &AA 0119 C32A BB = &BB 0120 C32B CC = &CC 0121 C32C DD = &DD 0122 C32D EE = &EE 0123 C32E FF = &FF 0124 C32F Acorn macro assembler Page 5 VDU File - MOS01 0125 C32F ;SIXTEEN COLOUR MODE 0126 C32F 0127 C32F 00 BPSTB = &00 0128 C330 55 = &55 0129 C331 AA = &AA 0130 C332 FF = &FF 0131 C333 0132 C333 0133 C333 ;JUMP TABLES Lower byte 0134 C333 0135 C333 12 JTBLO = ACK ;Points to an RTS 0136 C334 3C = SOH 0137 C335 95 = STX 0138 C336 A0 = ETX 0139 C337 AC = EOT 0140 C338 B8 = ENQ 0141 C339 12 = ACK 0142 C33A 99 = BELL 0143 C33B C4 = BS 0144 C33C 63 = HT 0145 C33D EF = LF 0146 C33E 5A = VT 0147 C33F 47 = FF 0148 C340 B9 = CR 0149 C341 8C = SO 0150 C342 A5 = SI 0151 C343 C7 = DLE 0152 C344 00 = DCA 0153 C345 04 = DCB 0154 C346 82 = DCC 0155 C347 3F = DCD 0156 C348 9A = NAK 0157 C349 D0 = SYN 0158 C34A D6 = ETB 0159 C34B 0D = CAN 0160 C34C 62 = EM 0161 C34D 93 = SUB 0162 C34E 12 = ACK ;Points to an RTS 0163 C34F F9 = FS 0164 C350 76 = GS 0165 C351 64 = RS 0166 C352 91 = US 0167 C353 D8 = DEL 0168 C354 0169 C354 ;Higher byte unless bytes to be queued, in which case, lower nibble 0170 C354 ;gives number of bytes to be queued, upper offset of higher byte 0171 C354 ;of routine address from code origin as specified by CODORG. Note 0172 C354 ;that this must be <8, i.e. biy 7 of whole byte is clear. 0173 C354 0174 C354 C5 JTBHI = /(ACK ) ;Points to an RTS 0175 C355 2F = SOH:SHR:&8-CODORG:SHL:&4+&10-&1 ;Queue 1 byte (SOH) 0176 C356 C5 = /(STX ) 0177 C357 C5 = /(ETX ) 0178 C358 C5 = /(EOT ) 0179 C359 C5 = /(ENQ ) 0180 C35A C5 = /(ACK ) 0181 C35B E8 = /(BELL ) 0182 C35C C5 = /(BS ) 0183 C35D C6 = /(HT ) 0184 C35E C6 = /(LF ) 0185 C35F C6 = /(VT ) 0186 C360 C7 = /(FF ) 0187 C361 C7 = /(CR ) 0188 C362 C5 = /(SO ) 0189 C363 C5 = /(SI ) 0190 C364 C7 = /(DLE ) 0191 C365 5F = DCA:SHR:&8-CODORG:SHL:&4+&10-&1 ;Queue 1 byte (DCA) 0192 C366 5E = DCB:SHR:&8-CODORG:SHL:&4+&10-&2 ;Queue 2 bytes (DCB) 0193 C367 5B = DCC:SHR:&8-CODORG:SHL:&4+&10-&5 ;Queue 5 bytes (DCC) 0194 C368 C8 = /(DCD ) 0195 C369 C5 = /(NAK ) 0196 C36A 5F = SYN:SHR:&8-CODORG:SHL:&4+&10-&1 ;Queue 1 byte (SYN) 0197 C36B 57 = ETB:SHR:&8-CODORG:SHL:&4+&10-&9 ;Queue 9 bytes (ETB) 0198 C36C 78 = CAN:SHR:&8-CODORG:SHL:&4+&10-&8 ;Queue 8 bytes (CAN) 0199 C36D 6B = EM:SHR:&8-CODORG:SHL:&4+&10-&5 ;Queue 5 bytes (EM) 0200 C36E C9 = /(SUB ) 0201 C36F C5 = /(ACK ) ;Points to an RTS 0202 C370 3C = FS:SHR:&8-CODORG:SHL:&4+&10-&4 ;Queue 4 bytes (FS) 0203 C371 7C = GS:SHR:&8-CODORG:SHL:&4+&10-&4 ;Queue 4 bytes (GS) 0204 C372 C7 = /(RS ) 0205 C373 4E = US:SHR:&8-CODORG:SHL:&4+&10-&2 ;Queue 2 bytes (US) 0206 C374 CF = /(DEL ) 0207 C375 0208 C375 ;ROW OFFSETS FOR H.R.G. 0209 C375 0210 C375 00 HRGTB = &00 0211 C376 00 = &00 0212 C377 02 = &02 0213 C378 80 = &80 0214 C379 05 = &05 0215 C37A 00 = &00 0216 C37B 07 = &07 0217 C37C 80 = &80 0218 C37D 0A = &0A 0219 C37E 00 = &00 0220 C37F 0C = &0C 0221 C380 80 = &80 0222 C381 0F = &0F 0223 C382 00 = &00 0224 C383 11 = &11 0225 C384 80 = &80 0226 C385 14 = &14 0227 C386 00 = &00 0228 C387 16 = &16 0229 C388 80 = &80 0230 C389 19 = &19 0231 C38A 00 = &00 0232 C38B 1B = &1B 0233 C38C 80 = &80 0234 C38D 1E = &1E 0235 C38E 00 = &00 0236 C38F 20 = &20 0237 C390 80 = &80 0238 C391 23 = &23 0239 C392 00 = &00 0240 C393 25 = &25 0241 C394 80 = &80 0242 C395 28 = &28 0243 C396 00 = &00 0244 C397 2A = &2A 0245 C398 80 = &80 Acorn macro assembler Page 6 VDU File - MOS01 0246 C399 2D = &2D 0247 C39A 00 = &00 0248 C39B 2F = &2F 0249 C39C 80 = &80 0250 C39D 32 = &32 0251 C39E 00 = &00 0252 C39F 34 = &34 0253 C3A0 80 = &80 0254 C3A1 37 = &37 0255 C3A2 00 = &00 0256 C3A3 39 = &39 0257 C3A4 80 = &80 0258 C3A5 3C = &3C 0259 C3A6 00 = &00 0260 C3A7 3E = &3E 0261 C3A8 80 = &80 0262 C3A9 41 = &41 0263 C3AA 00 = &00 0264 C3AB 43 = &43 0265 C3AC 80 = &80 0266 C3AD 46 = &46 0267 C3AE 00 = &00 0268 C3AF 48 = &48 0269 C3B0 80 = &80 0270 C3B1 4B = &4B 0271 C3B2 00 = &00 0272 C3B3 4D = &4D 0273 C3B4 80 = &80 0274 C3B5 0275 C3B5 ;ROW OFFSET TABLE FOR TELETEXT 0276 C3B5 0277 C3B5 00 TXTTB = &00 0278 C3B6 00 = &00 0279 C3B7 00 = &00 0280 C3B8 28 = &28 0281 C3B9 00 = &00 0282 C3BA 50 = &50 0283 C3BB 00 = &00 0284 C3BC 78 = &78 0285 C3BD 00 = &00 0286 C3BE A0 = &A0 0287 C3BF 00 = &00 0288 C3C0 C8 = &C8 0289 C3C1 00 = &00 0290 C3C2 F0 = &F0 0291 C3C3 01 = &01 0292 C3C4 18 = &18 0293 C3C5 01 = &01 0294 C3C6 40 = &40 0295 C3C7 01 = &01 0296 C3C8 68 = &68 0297 C3C9 01 = &01 0298 C3CA 90 = &90 0299 C3CB 01 = &01 0300 C3CC B8 = &B8 0301 C3CD 01 = &01 0302 C3CE E0 = &E0 0303 C3CF 02 = &02 0304 C3D0 08 = &08 0305 C3D1 02 = &02 0306 C3D2 30 = &30 0307 C3D3 02 = &02 0308 C3D4 58 = &58 0309 C3D5 02 = &02 0310 C3D6 80 = &80 0311 C3D7 02 = &02 0312 C3D8 A8 = &A8 0313 C3D9 02 = &02 0314 C3DA D0 = &D0 0315 C3DB 02 = &02 0316 C3DC F8 = &F8 0317 C3DD 03 = &03 0318 C3DE 20 = &20 0319 C3DF 03 = &03 0320 C3E0 48 = &48 0321 C3E1 03 = &03 0322 C3E2 70 = &70 0323 C3E3 03 = &03 0324 C3E4 98 = &98 0325 C3E5 03 = &03 0326 C3E6 C0 = &C0 0327 C3E7 0328 C3E7 ;NO. ROWS IN EACH MEMORY MODE 0329 C3E7 0330 C3E7 1F PROWS = &1F 0331 C3E8 1F = &1F 0332 C3E9 1F = &1F 0333 C3EA 18 = &18 0334 C3EB 1F = &1F 0335 C3EC 1F = &1F 0336 C3ED 18 = &18 0337 C3EE 18 = &18 0338 C3EF 0339 C3EF ;NO. COLS. IN EACH MEMORY MODE 0340 C3EF 0341 C3EF 4F PCOLS = &4F 0342 C3F0 27 = &27 0343 C3F1 13 = &13 0344 C3F2 4F = &4F 0345 C3F3 27 = &27 0346 C3F4 13 = &13 0347 C3F5 27 = &27 0348 C3F6 27 = &27 0349 C3F7 0350 C3F7 ;BYTES TO BE LOADED INTO mMODREG FOR DIFFERENT MODES 0351 C3F7 0352 C3F7 9C INDMOD = &9C 0353 C3F8 D8 = &D8 0354 C3F9 F4 = &F4 0355 C3FA 9C = &9C 0356 C3FB 88 = &88 0357 C3FC C4 = &C4 0358 C3FD 88 = &88 0359 C3FE 4B = &4B 0360 C3FF 0361 C3FF ;BYTES PER CHARACTER 0362 C3FF ;IN EACH MODE 0363 C3FF 0364 C3FF 08 BYTCHT = &08 0365 C400 10 = &10 0366 C401 20 = &20 Acorn macro assembler Page 7 VDU File - MOS01 0367 C402 08 = &08 0368 C403 08 = &08 0369 C404 10 = &10 0370 C405 08 = &08 0371 C406 01 = &01 0372 C407 0373 C407 ;MASK TABLES - must be contiguous 0374 C407 0375 C407 ;For each mode, the masks of each pixel, MS first 0376 C407 ;Note that it is now assumed that adjacent masks may be generated 0377 C407 ;by either ASL or LSR. 0378 C407 0379 C407 ;SIXTEEN colour mode 0380 C407 0381 C407 AA MASKTB = &AA 0382 C408 55 = &55 0383 C409 0384 C409 ;FOUR colour mode 0385 C409 88 = &88 0386 C40A 44 = &44 0387 C40B 22 = &22 0388 C40C 11 = &11 0389 C40D 0390 C40D ;TWO colour mode 0391 C40D 0392 C40D 80 BITTBL = &80 0393 C40E 40 = &40 0394 C40F 20 = &20 0395 C410 10 = &10 0396 C411 08 = &08 0397 C412 04 = &04 0398 C413 0399 C413 02 = &02 ;**** NEXT 3 BYTES USED BY CFS **** 0400 C414 ;Uses $01 of next table 0401 C414 0402 C414 ;COLOURS AVAILABLE FOR MODES 0403 C414 0404 C414 01 COLMOD = &01 0405 C415 03 = &03 0406 C416 0F = &0F 0407 C417 0408 C417 01 = &01 ;**** NEXT 3 BYTES USED BY CFS **** 0409 C418 01 = &01 0410 C419 03 = &03 0411 C41A 01 = &01 0412 C41B ;TTX - must be 0 - uses 1st byte of next table 0413 C41B 0414 C41B ;Bytes for forming ZGORA & ZGEOR 0415 C41B ;Tables have been run into each other to save bytes. 0416 C41B ;They should be as follows 0417 C41B 0418 C41B ;TBZGOO OR the OR :- $FF,$00,$00,$FF,$FF,$FF 0419 C41B ;TBZGEO EOR the OR :- $00,$00,$FF,$FF,$FF,$FF 0420 C41B ;TBZGOE OR the EOR :- $00,$FF,$00,$00,$FF,$FF 0421 C41B ;TBZGEE EOR the EOR :- $FF,$FF,$FF,$00,$00,$FF 0422 C41B 0423 C41B ;These are for the colour modes 0 to 5, being 0424 C41B ;0=Store,1=OR,2=AND,3=EOR,4=Invert,5=No change 0425 C41B 0426 C41B 00 TBZGOE = &00 0427 C41C FF TBZGOO = &FF 0428 C41D 00 TBZGEO = &00 0429 C41E 00 = &00 0430 C41F FF = &FF 0431 C420 FF TBZGEE = &FF 0432 C421 FF = &FF 0433 C422 FF = &FF 0434 C423 00 = &00 ;Uses next $00, $FF 0435 C424 0436 C424 ;~~~ COLOUR TABLES ~~~ 0437 C424 0438 C424 ;FULL COLOUR TABLES 0439 C424 ;Tables of 'full colours', 0440 C424 ;i.e. of bytes with all bits 0441 C424 ;set to 1 colour, in ascending 0442 C424 ;colour order 0443 C424 0444 C424 00 FCOLTB = &00 ;Two colour table 0445 C425 FF = &FF 0446 C426 0447 C426 ;Four colour table 0448 C426 0449 C426 00 = &00 0450 C427 0F = &0F 0451 C428 F0 = &F0 0452 C429 FF = &FF 0453 C42A 0454 C42A ;Sixteen colour table 0455 C42A 0456 C42A 00 = &00 0457 C42B 03 = &03 0458 C42C 0C = &0C 0459 C42D 0F = &0F 0460 C42E 30 = &30 0461 C42F 33 = &33 0462 C430 3C = &3C 0463 C431 3F = &3F ;INVSXT This byte used to invert graphics pixels 0464 C432 C0 = &C0 0465 C433 C3 = &C3 0466 C434 CC = &CC 0467 C435 CF = &CF 0468 C436 F0 = &F0 0469 C437 F3 = &F3 0470 C438 FC = &FC 0471 C439 FF = &FF 0472 C43A 0473 C43A ;TABLE FOR NPIX 0474 C43A 0475 C43A ;No. pixles per byte in each graphics mode 0476 C43A ;(0 if not graphics) 0477 C43A 0478 C43A 07 NPIXTB = &07 0479 C43B 03 = &03 0480 C43C 01 = &01 0481 C43D 00 = &00 ;(Non graphics) 0482 C43E 07 = &07 0483 C43F 03 = &03 0484 C440 ;Non-graphics modes - use next 2 $00s 0485 C440 0486 C440 ;MEMORY MAP TYPES 0487 C440 ;Index from MODE (0..7), to Acorn macro assembler Page 8 VDU File - MOS01 0488 C440 ;the following 5 element tables 0489 C440 0490 C440 MODETB 0491 C440 00 = &00 0492 C441 SOUNDV ;channel dependent period offset 0493 C441 C43D SCHOFF * SOUNDV -&04 0494 C441 0495 C441 00 = &00 0496 C442 00 = &00 0497 C443 01 = &01 0498 C444 02 = &02 0499 C445 02 = &02 0500 C446 03 = &03 0501 C447 ;Uses $04 of next table 0502 C447 0503 C447 0504 C447 ;EXIT WINDOW OFFSET TABLE 0505 C447 0506 C447 04 EWTBA = &04 0507 C448 00 = &00 0508 C449 06 = &06 0509 C44A 02 = &02 0510 C44B 0511 C44B 0512 C44B ;C0 control table 0513 C44B ;C1 control table 0514 C44B 0515 C44B 0D CONE = &0D 0516 C44C 05 = &05 0517 C44D 0D = &0D 0518 C44E 05 = &05 ;Uses next $04 0519 C44F 04 CZERO = &04 0520 C450 04 = &04 0521 C451 0C = &0C 0522 C452 0C = &0C 0523 C453 04 = &04 0524 C454 0525 C454 ;TABLES OF JUMP VECTORS 0526 C454 ;FOR CLEAR SCREEN 0527 C454 0528 C454 07 CLSCTA = CLASCA ;(LSB) 0529 C455 37 = CLASCB 0530 C456 7F = CLASCC 0531 C457 97 = CLASCD 0532 C458 EB = CLASCE 0533 C459 0534 C459 ;CLSCTB = CLASCA / ;(MSB) 0535 C459 ; = CLASCB / 0536 C459 ; = CLASCC / 0537 C459 ; = CLASCD / 0538 C459 ; = CLASCE / 0539 C459 0540 C459 ;NO. BYTES PER SCREEN (MSB) 0541 C459 0542 C459 50 BYTSTA = &50 0543 C45A 40 = &40 0544 C45B 28 = &28 0545 C45C 20 = &20 0546 C45D 04 = &04 0547 C45E 0548 C45E ;MSB OF SCREEN START 0549 C45E 0550 C45E 30 STSCTB = &30 0551 C45F 40 = &40 0552 C460 58 = &58 0553 C461 60 = &60 0554 C462 7C = &7C 0555 C463 0556 C463 ;BYTE WIDTH TYPES 0557 C463 ;Index from MEMODE (0..4), to 0558 C463 ;the following 3 element tables 0559 C463 0560 C463 ;Now replaced with LSRA 0561 C463 0562 C463 ;LSB OF NO. BYTES PER ROW 0563 C463 0564 C463 28 BYTRTA = &28 0565 C464 40 = &40 0566 C465 80 = &80 0567 C466 0568 C466 ;LSB OF SCREEN OFFSET TABLES 0569 C466 0570 C466 B5 TBZTBA = TXTTB 0571 C467 75 = HRGTB 0572 C468 75 = HRGTB 0573 C469 0574 C469 0575 C469 ;CRTC TABLES 0576 C469 0577 C469 ;INDEX FOR CRTC TABLES 0578 C469 0579 C469 0B CRTCX = &0B 0580 C46A 17 = &17 0581 C46B 23 = &23 0582 C46C 2F = &2F 0583 C46D 3B = &3B 0584 C46E 0585 C46E ;CRTC TABLE FOR MODES 0-2 0586 C46E 0587 C46E 7F CRTCTB = &7F 0588 C46F 50 = &50 0589 C470 62 = &62 0590 C471 28 = &28 ;VS=2 0591 C472 26 = &26 0592 C473 00 = &00 0593 C474 20 = &20 0594 C475 22 = &22 ;was $22 & then it was $23 0595 C476 01 = &01 0596 C477 07 = &07 0597 C478 67 = &67 0598 C479 08 = &08 0599 C47A 0600 C47A ;CRTC TABLE FOR MODE 3 0601 C47A 0602 C47A 7F = &7F 0603 C47B 50 = &50 0604 C47C 62 = &62 0605 C47D 28 = &28 ;VS=2 0606 C47E 1E = &1E 0607 C47F 02 = &02 0608 C480 19 = &19 Acorn macro assembler Page 9 VDU File - MOS01 0609 C481 1B = &1B ;was $1B & then it was $1C 0610 C482 01 = &01 0611 C483 09 = &09 0612 C484 67 = &67 0613 C485 09 = &09 0614 C486 0615 C486 ;CRTC TABLE FOR MODES 4-5 0616 C486 0617 C486 3F = &3F 0618 C487 28 = &28 0619 C488 31 = &31 0620 C489 24 = &24 ;VS=2 0621 C48A 26 = &26 0622 C48B 00 = &00 0623 C48C 20 = &20 0624 C48D 22 = &22 ;was $22 & then it was $23 0625 C48E 01 = &01 0626 C48F 07 = &07 0627 C490 67 = &67 0628 C491 08 = &08 0629 C492 0630 C492 ;CRTC TABLE FOR MODE 6 0631 C492 0632 C492 3F = &3F 0633 C493 28 = &28 0634 C494 31 = &31 0635 C495 24 = &24 ;VS=2 0636 C496 1E = &1E 0637 C497 02 = &02 0638 C498 19 = &19 0639 C499 1B = &1B ;was $1B & then it was $1C 0640 C49A 01 = &01 0641 C49B 09 = &09 0642 C49C 67 = &67 0643 C49D 09 = &09 0644 C49E 0645 C49E ;CRTC TABLE FOR MODE 7 0646 C49E 0647 C49E 3F = &3F 0648 C49F 28 = &28 0649 C4A0 33 = &33 0650 C4A1 24 = &24 ;VS=2 0651 C4A2 1E = &1E 0652 C4A3 02 = &02 0653 C4A4 19 = &19 0654 C4A5 1B = &1B ;was $1B & then it was $1C 0655 C4A6 93 = &93 0656 C4A7 12 = &12 0657 C4A8 72 = &72 0658 C4A9 13 = &13 0659 C4AA 0660 C4AA ;JUMP TABLES FOR PLOTTING ROUTINES 0661 C4AA 0662 C4AA 56 D1JTB = EA 0663 C4AB D3 = /(EA ) 0664 C4AC 4E = NA 0665 C4AD D3 = /(NA ) 0666 C4AE 0667 C4AE 3A D2JTBL = EB 0668 C4AF 44 = WB 0669 C4B0 12 = NB 0670 C4B1 1B = SB 0671 C4B2 0672 C4B2 D3 D2JTBH = /(EB ) 0673 C4B3 D3 = /(WB ) 0674 C4B4 D3 = /(NB ) 0675 C4B5 D3 = /(SB ) 0676 C4B6 0677 C4B6 0678 C4B6 ;TELETEXT CONVERSION TABLE 0679 C4B6 0680 C4B6 23 TTXTB = &23 0681 C4B7 5F = &5F 0682 C4B8 60 = &60 0683 C4B9 23 = &23 0684 C4BA 0685 C4BA 0686 C4BA ; font table 0687 C4BA 0688 C4BA FFSZOT ;Four,Five,Six,Zero,One,Two 0689 C4BA 04 = &04 0690 C4BB 05 = &05 0691 C4BC 06 = &06 0692 C4BD 00 = &00 0693 C4BE 01 = &01 0694 C4BF 02 = &02 0695 C4C0 0696 C4C0 0697 C4C0 LNK MOS02 0001 C4C0 0002 C4C0 TTL VDU File - MOS02 0003 C4C0 OPT MOS02 Acorn macro assembler Page 10 VDU File - MOS02 0004 C4C0 0005 C4C0 ;Last revision 30/04/82 0006 C4C0 0007 C4C0 ;30/04/82 Recoded to allow for reverse queueing 0008 C4C0 ;19/04/82 To put ASCIQ in line, and various other byte savings 0009 C4C0 ;19/11/81 No longer include bell in printer range check 0010 C4C0 0011 C4C0 0012 C4C0 ;ENTRY POINT - SELECT ROUTINE 0013 C4C0 0014 C4C0 0015 C4C0 VDU 0016 C4C0 AE 6A 02 LDX QPOSN ;Are we Qing ? 0017 C4C3 D0 4E BNE QING ;Yes?, then queue this byte 0018 C4C5 24 D0 BIT STATS 0019 C4C7 50 0F BVC NOTCEA ;In C.E. mode? 0020 C4C9 20 67 C5 JSR CSWAP ;Yes?, then swap cursors 0021 C4CC 20 60 CD JSR OCSRDL ;Delete the output cursor 0022 C4CF 30 07 BMI NOTCEA ;Are we disabled ? then skip 0023 C4D1 C9 0D CMPIM TRMCH ;No?, then is this TRMCH ? 0024 C4D3 D0 03 BNE NOTCEA 0025 C4D5 20 A8 D8 JSR CSEDEX ;Yes?, then exit C.E. mode 0026 C4D8 C9 7F NOTCEA CMPIM &7F ;No?, then form vector 0027 C4DA F0 13 BEQ ISDEL 0028 C4DC C9 20 CMPIM &20 0029 C4DE 90 11 BCC NOTDEL ; Branch if unprintable 0030 C4E0 24 D0 BIT STATS ;Printable - are we disabled ? 0031 C4E2 30 06 BMI NOTC20 ;Yes, then print it if print module on 0032 C4E4 20 A7 CF JSR VDUPR ;No?, then print to VDU 0033 C4E7 20 63 C6 JSR HT 0034 C4EA [ MOS125 = &FF 0036 C4EA | 0037 C4EA NOTC20 ;A dead 0038 C4EA A5 D0 LDA STATS 0039 C4EC 4A LSRA ;C=1 if printer module on 0040 C4ED 10 71 BPL CSWDEX ;& ditto 0041 C4EF ] 0042 C4EF 0043 C4EF A9 20 ISDEL LDAIM &20 ;(Form correct index for DEL) 0044 C4F1 0045 C4F1 A8 NOTDEL TAY 0046 C4F2 B9 33 C3 LDAAY JTBLO ;Get LSByte of jump vector 0047 C4F5 8D 5D 03 STA JVEC 0048 C4F8 B9 54 C3 LDAAY JTBHI ;Get MSByte 0049 C4FB 30 4A BMI REXEC ;No Qing required, so execute routine 0050 C4FD AA TAX ;b7=0, so Q needed - set it up 0051 C4FE 09 F0 ORAIM &F0 ;2's comp. of no. of bytes to Q 0052 C500 8D 6A 02 STA QPOSN 0053 C503 8A TXA ;Generate MSByte of address - MSNybble, plus CODORG 0054 C504 4A LSRA 0055 C505 4A LSRA 0056 C506 4A LSRA 0057 C507 4A LSRA 0058 C508 18 CLC 0059 C509 69 C3 ADCIM CODORG ;Forms the high byte of the vector 0060 C50B 8D 5E 03 STA JVEC +&01 0061 C50E 24 D0 BIT STATS ;Swap back again if C.E. 0062 C510 70 1E BVS NOTC10 0063 C512 [ MOS125 = &FF 0065 C512 | 0066 C512 ;adcim codorg never overflows (here...), C=0 0067 C512 ] 0068 C512 60 ACK RTS ;NUL points at this to save a byte 0069 C513 0070 C513 0071 C513 9D 24 02 QING STAAX QEND-&FF ;Q the byte 0072 C516 E8 INX 0073 C517 8E 6A 02 STX QPOSN ;(z preserved from INX) 0074 C51A D0 17 BNE CLCEX ;More to do?, then exit 0075 C51C 24 D0 BIT STATS ;Disabled?, then go away 0076 C51E 30 15 BMI DISABL 0077 C520 70 05 BVS NOTCEB ;C.E. mode, then do swapping 0078 C522 20 FA CC JSR RUNNER 0079 C525 18 CLC 0080 C526 60 RTS 0081 C527 0082 C527 20 67 C5 NOTCEB JSR CSWAP 0083 C52A 20 60 CD JSR OCSRDL 0084 C52D 20 FA CC JSR RUNNER 0085 C530 20 64 C5 NOTC10 JSR REXE10 0086 C533 18 CLCEX CLC 0087 C534 60 RTS 0088 C535 0089 C535 AC 5E 03 DISABL LDY JVEC +&01 ;Was this an SOH ? 0090 C538 C0 C5 CPYIM /(SOH ) 0091 C53A D0 F7 BNE CLCEX ;No?, then go home 0092 C53C 0093 C53C AA SOH TAX ;Yes, then (A)=Byte to be printed 0094 C53D A5 D0 LDA STATS ;Is printing enabled ? 0095 C53F 4A LSRA 0096 C540 90 D0 BCC ACK 0097 C542 8A TXA 0098 C543 [ MOS125 = &FF 0099 C543 | 0100 C543 18 CLC ;C=0, prevent second printing; PRINT preserves flags 0101 C544 ] 0102 C544 4C 7D E1 JMP PRINT ;print character and return, setting c=0 (done by MOS) 0103 C547 0104 C547 [ MOS125 = &FF 0127 C547 | 0128 C547 REXEC ;starting +2 from NOTC20; 1 spare byte 0129 C547 8D 5E 03 STA JVEC +&01 0130 C54A A5 D0 LDA STATS 0131 C54C 6A RORA ;Is printer module on? 0132 C54D 98 TYA ;AND Is it range $08 to $0D ? (no longer include bell) 0133 C54E 6A RORA ;+4 = +6 0134 C54F C9 84 CMPIM &84 0135 C551 49 FF EORIM &FF 0136 C553 6A RORA 0137 C554 69 43 ADCIM &43 0138 C556 98 TYA ;-2 = +4 0139 C557 ; 0140 C557 24 D0 BIT STATS ;Execute routine - are we disabled ? 0141 C559 30 24 BMI ACKQ ;Was it an ACK? (can't be an SOH cos she queues) 0142 C55B ; 0143 C55B 08 PHP ;and push c 0144 C55C 20 FA CC JSR RUNNER ;Do the routine 0145 C55F 28 PLP 0146 C560 CSWDEX ;enter with C=printer module on ;-5 = -1; 4 spare bytes 0147 C560 24 D0 BIT STATS ;Following preserves c 0148 C562 50 AE BVC ACK ;Not C.E. so exit Acorn macro assembler Page 11 VDU File - MOS02 0149 C564 20 70 CD REXE10 JSR OCSRWR ;Write output cursor 0150 C567 ] 0151 C567 0152 C567 ;CSWAP - swap input and output text cursors 0153 C567 ; invert b1 of STATS 0154 C567 0155 C567 08 CSWAP PHP ;Preserve carry 0156 C568 48 PHA 0157 C569 A2 18 LDXIM CSX-V 0158 C56B A0 64 LDYIM PCSX-V 0159 C56D 20 CC CD JSR SWAP2 0160 C570 20 09 CF JSR TADDRY ;Address this point 0161 C573 20 D8 C9 JSR CSDSP 0162 C576 A5 D0 LDA STATS 0163 C578 49 02 EORIM &02 ;Invert bit 1 of STATS 0164 C57A 85 D0 STA STATS 0165 C57C 68 PLA 0166 C57D 28 PLP ;Restore c 0167 C57E 60 RTS 0168 C57F 0169 C57F ACKQ 0170 C57F ; C=0 => character not printable, C=1 => printable 0171 C57F 49 06 EORIM ACKASC ;Was it an ACK ? 0172 C581 D0 08 BNE VDURTS ;[not ACK] 0173 C583 ; 0174 C583 ; C=0 cos ACK not printable 0175 C583 A9 7F LDAIM &7F ;Yes?, then clear b7 of STATS 0176 C585 90 20 BCC STTAND ;always jump 0177 C587 0178 C587 0179 C587 0180 C587 ;Test to see if printable ($20-$7E or $80-$FF) 0181 C587 ;Returns c=1 iff printable, c=0 otherwise 0182 C587 0183 C587 0184 C587 ;ANOMQ Returns z=0 iff cursors joined 0185 C587 0186 C587 A5 D0 ANOMQ LDA STATS 0187 C589 29 20 ANDIM &20 ;Is b5 set ? (Answer to z) 0188 C58B VDURTS 0189 C58B 60 RTS ;Returns(A)=0 if b5 clear 0190 C58C 0191 C58C ;INDIVIDUAL ROUTINES 0192 C58C 0193 C58C ;NUL ($00) - do nothing 0194 C58C 0195 C58C ;Jump table points to ACK, an RTS, to save a byte 0196 C58C 0197 C58C ;SOH ($01) - Next char to printer 0198 C58C 0199 C58C ;This is taken care of above 0200 C58C 0201 C58C 0202 C58C ;SO ($0E) - Page mode on 0203 C58C 0204 C58C A0 00 SO LDYIM &00 ;Initialise LINES 0205 C58E 8C 69 02 STY LINES 0206 C591 A9 04 LDAIM &04 ;Set b2 of STATS 0207 C593 D0 07 BNE STTOR 0208 C595 0209 C595 ;SI ($0F) - Page mode OFF 0210 C595 ; This is frigged below 0211 C595 0212 C595 ;STX ($02) - Start printer 0213 C595 0214 C595 20 39 E2 STX JSR mUPT ;inform network (A assumed to contain $02) 0215 C598 A9 94 LDAIM &94 ;Set bit 0 of STATS. This maps to $01 0216 C59A 0217 C59A ;NAK ($15) - Turn VDU off 0218 C59A 0219 C59A 49 95 NAK EORIM &95 ;Set b7 of STATS. Map $15 to $80 0220 C59C 0221 C59C 05 D0 STTOR ORA STATS 0222 C59E D0 09 BNE STTEXT ;(branch always taken unless ORed with 0) 0223 C5A0 0224 C5A0 0225 C5A0 ;ETX ($03) - Stop printer 0226 C5A0 0227 C5A0 20 39 E2 ETX JSR mUPT ;inform network (A assumed to contain $03) 0228 C5A3 A9 0A LDAIM &0A ;clear bit 0 of STATS. Maps $0A on to $FE 0229 C5A5 0230 C5A5 49 F4 SI EORIM &F4 ;Clears b2 of STATS. Maps $0F on to $FB 0231 C5A7 0232 C5A7 25 D0 STTAND AND STATS 0233 C5A9 85 D0 STTEXT STA STATS 0234 C5AB 60 EOTEXT RTS 0235 C5AC 0236 C5AC 0237 C5AC ;EOT ($04) - Separate cursors 0238 C5AC 0239 C5AC AD 61 03 EOT LDA NPIX ;Is this a graphics mode ? 0240 C5AF F0 FA BEQ EOTEXT ;NO, then return 0241 C5B1 20 27 C9 JSR ETCA ;Redisplay old cursor 0242 C5B4 A9 DF LDAIM &DF ;Clear b5 of STATS 0243 C5B6 D0 EF BNE STTAND ;(branch always taken) 0244 C5B8 0245 C5B8 ;ENQ ($05) - Join cursors 0246 C5B8 ;Store & hide current cursor 0247 C5B8 ;Set bit 5 of STATS 0248 C5B8 0249 C5B8 AD 61 03 ENQ LDA NPIX ;Is this a graphics mode ? 0250 C5BB F0 EE BEQ EOTEXT ;NO, then return 0251 C5BD ;Access R10 OF 6845. NB cannot do this through CRTCP. 0252 C5BD A9 20 LDAIM &20 ;Hide cursor 0253 C5BF 20 2A C9 JSR ETCB ; Preserves flags 0254 C5C2 D0 D8 BNE STTOR ;Set bit 5 of STATS, (A) preserved by ETCB 0255 C5C4 0256 C5C4 ;ACK ($06) - Turn VDU drivers on again 0257 C5C4 ;Clear bit 7 of STATS 0258 C5C4 0259 C5C4 ;Taken care of above 0260 C5C4 0261 C5C4 ;BELL ($07) - Ring BELL 0262 C5C4 0263 C5C4 ;The routine BELL is externally declared in file UADE90 0264 C5C4 0265 C5C4 ;Cursor primitives 0266 C5C4 0267 C5C4 ;BS ($08) - Cursor left 1 character position 0268 C5C4 0269 C5C4 20 87 C5 BS JSR ANOMQ Acorn macro assembler Page 12 VDU File - MOS02 0270 C5C7 D0 55 BNE CSAL 0271 C5C9 0272 C5C9 ;Cursor left 0273 C5C9 0274 C5C9 CE 18 03 CSL DEC CSX 0275 C5CC AE 18 03 LDX CSX ;Over LH margin ? 0276 C5CF EC 08 03 CPX TWLCOL 0277 C5D2 30 19 BMI CSLC ;Yes, then up (see below) a line 0278 C5D4 AD 4A 03 LDA CSPOSN ;Move cursor left 0279 C5D7 38 SEC 0280 C5D8 ED 4F 03 SBC BYTCH 0281 C5DB AA TAX 0282 C5DC AD 4B 03 LDA CSPOSN +&01 0283 C5DF E9 00 SBCIM &00 0284 C5E1 CD 4E 03 CMP BEGSCN ;Wraparound ? 0285 C5E4 B0 03 BCS CSLA 0286 C5E6 6D 54 03 ADC BYTSCN ;Yes, then add screen 0287 C5E9 A8 CSLA TAY 0288 C5EA 4C CC C9 JMP CSDSPA 0289 C5ED 0290 C5ED AD 0A 03 CSLC LDA TWRCOL ;Put csr = RH edge 0291 C5F0 8D 18 03 STA CSX ;& fall through to ... 0292 C5F3 0293 C5F3 ;Cursor up 0294 C5F3 0295 C5F3 CE 69 02 CSU DEC LINES ;One more line to print before page mode occurs 0296 C5F6 10 03 BPL CSUC 0297 C5F8 EE 69 02 INC LINES ;At top of page, so don't go -ve! 0298 C5FB AE 19 03 CSUC LDX CSY ;Cursor on top row ? 0299 C5FE EC 0B 03 CPX TWTROW 0300 C601 F0 06 BEQ CSUA ;Yes, then scroll 0301 C603 CE 19 03 DEC CSY 0302 C606 4C AE C6 JMP CSDA 0303 C609 0304 C609 18 CSUA CLC 0305 C60A 20 35 CD JSR ENSCRL ;Account for scroll disable 0306 C60D A9 08 LDAIM &08 ;Test hard/soft flag 0307 C60F 24 D0 BIT STATS 0308 C611 D0 05 BNE CSUB ;S3 set, soft scroll 0309 C613 20 6A C9 JSR HSCRDN ;S3 clear, hard scroll 0310 C616 D0 03 BNE CSUD ; HSCRDN returns zero false 0311 C618 20 93 CD CSUB JSR SSCRDN 0312 C61B 4C AB C6 CSUD JMP CSDC 0313 C61E A2 00 CSAL LDXIM &00 0314 C620 ; And fall through to 0315 C620 0316 C620 ;Move graphics cursor 1 character - primitives. 0317 C620 ;(X) = 0 if X cursor to be moved 0318 C620 ; 2 if Y cursor to be moved 0319 C620 ;Iff (X)=0, then if off window, LF/VT occurs 0320 C620 ;If cursor crosses margin, then goes to opposite margin. 0321 C620 ;Go down 1 character location 0322 C620 0323 C620 86 DB GCSCHD STX ZTEMP +&01 ;Store offset 0324 C622 20 1F D1 JSR WINDCS ;Window current cursor (result to ZTEMP) 0325 C625 A6 DB LDX ZTEMP +&01 ;Subtract 8 from cursor 0326 C627 38 SEC 0327 C628 BD 24 03 LDAAX GCSIR 0328 C62B E9 08 SBCIM &08 0329 C62D 9D 24 03 STAAX GCSIR 0330 C630 B0 03 BCS GCSHDA 0331 C632 DE 25 03 DECAX GCSIR+&01 0332 C635 A5 DA GCSHDA LDA ZTEMP ;Get window 0333 C637 D0 1E BNE GCSHDB ;Out of window to begin with?, then skip 0334 C639 20 1F D1 JSR WINDCS ;Window current point 0335 C63C F0 19 BEQ GCSHDB ;Still inside? , then return 0336 C63E A6 DB LDX ZTEMP +&01 ;Gone outside?, then go to high margin 0337 C640 BD 04 03 LDAAX GWRCOL 0338 C643 E0 01 CPXIM &01 ;Plot by X?, then back up 1 character 0339 C645 B0 02 BCS GCSHDC 0340 C647 E9 06 SBCIM &06 ;c=0. so subt. 7 to get char. just on screen 0341 C649 9D 24 03 GCSHDC STAAX GCSIR 0342 C64C BD 05 03 LDAAX GWRCOL+&01 0343 C64F E9 00 SBCIM &00 0344 C651 9D 25 03 STAAX GCSIR+&01 0345 C654 8A TXA ;Plot by X?, then go up a line as well 0346 C655 F0 08 BEQ CSAU 0347 C657 4C 7D CA GCSHDB JMP IEG 0348 C65A 0349 C65A 0350 C65A ;VT ($0B) - Cursor up 1 character line 0351 C65A 0352 C65A 20 87 C5 VT JSR ANOMQ 0353 C65D F0 94 BEQ CSU 0354 C65F A2 02 CSAU LDXIM &02 0355 C661 D0 52 BNE GCSCHU ;(branch always taken) 0356 C663 0357 C663 ;HT ($09) - Cursor right 1 character position 0358 C663 0359 C663 A5 D0 HT LDA STATS ;Encode ANOMQ because this routine often referenced 0360 C665 29 20 ANDIM &20 0361 C667 D0 4A BNE CSAR 0362 C669 0363 C669 ;Cursor right 0364 C669 0365 C669 AE 18 03 CSR LDX CSX ;Cursor over RH col ? 0366 C66C EC 0A 03 CPX TWRCOL 0367 C66F B0 12 BCS CSRC 0368 C671 EE 18 03 INC CSX 0369 C674 AD 4A 03 LDA CSPOSN 0370 C677 6D 4F 03 ADC BYTCH ;Add no. bytes per char 0371 C67A AA TAX 0372 C67B AD 4B 03 LDA CSPOSN +&01 ;to posn. of csr. 0373 C67E 69 00 ADCIM &00 ;sets n for test in CSDSPA 0374 C680 4C CC C9 JMP CSDSPA 0375 C683 AD 08 03 CSRC LDA TWLCOL ;Put csr = LH edge 0376 C686 8D 18 03 STA CSX ;& fall through to ... 0377 C689 0378 C689 ;Cursor down 0379 C689 0380 C689 18 CSD CLC ;do not set LEDs on first test for page wait (MOS requirement) 0381 C68A 20 C0 CA JSR PAGE ;Account for page mode 0382 C68D AE 19 03 LDX CSY ;Is cursor off bottom? 0383 C690 EC 09 03 CPX TWBROW 0384 C693 B0 05 BCS CSDD ;Yes, then scroll 0385 C695 EE 19 03 INC CSY ;No, then move down line 0386 C698 90 14 BCC CSDA ;(branch always taken) 0387 C69A 0388 C69A 20 35 CD CSDD JSR ENSCRL ;Account for scroll disable 0389 C69D A9 08 LDAIM &08 ;Test hard/soft flag 0390 C69F 24 D0 BIT STATS Acorn macro assembler Page 13 VDU File - MOS02 0391 C6A1 D0 05 BNE CSDB 0392 C6A3 20 7A C9 JSR HSCRUP ;No windows set, so use hard scroll 0393 C6A6 D0 03 BNE CSDC ; HSCRUP unsets zero 0394 C6A8 20 00 CE CSDB JSR SSCRUP ;Windows set, so use soft scroll 0395 C6AB 20 AC CE CSDC JSR CLTLIN ;Clear the line on which CSY lies 0396 C6AE 20 09 CF CSDA JSR TADDRY ;address the cursor, point guaranteed in window 0397 C6B1 90 7E BCC FSD ;and display it (TADDRY returns carry clear) 0398 C6B3 A2 00 CSAR LDXIM &00 0399 C6B5 ; And fall through to 0400 C6B5 0401 C6B5 ;Move graphics cursor 1 character - primitives. 0402 C6B5 ;(X) = 0 if Y cursor to be moved 0403 C6B5 ; 2 if X cursor to be moved 0404 C6B5 ;Iff (X)=0, then if off window, LF/VT occurs 0405 C6B5 ;If cursor crosses margin, then goes to opposite margin. 0406 C6B5 0407 C6B5 86 DB GCSCHU STX ZTEMP +&01 ;Store offset 0408 C6B7 20 1F D1 JSR WINDCS ;Window current cursor (result to ZTEMP) 0409 C6BA A6 DB LDX ZTEMP +&01 ;Add 8 to cursor 0410 C6BC 18 CLC 0411 C6BD BD 24 03 LDAAX GCSIR 0412 C6C0 69 08 ADCIM &08 0413 C6C2 9D 24 03 STAAX GCSIR 0414 C6C5 90 03 BCC GCSHUA 0415 C6C7 FE 25 03 INCAX GCSIR+&01 0416 C6CA A5 DA GCSHUA LDA ZTEMP ;Get window 0417 C6CC D0 89 BNE GCSHDB ;Out of window to begin with?, then skip 0418 C6CE 20 1F D1 JSR WINDCS ;Window current point 0419 C6D1 F0 84 BEQ GCSHDB ;Still inside? , then return 0420 C6D3 A6 DB LDX ZTEMP +&01 ;Gone outside?, then go to low margin 0421 C6D5 BD 00 03 LDAAX GWLCOL 0422 C6D8 E0 01 CPXIM &01 ;Plot by Y?, then go up a line 0423 C6DA 90 02 BCC GCSHUC 0424 C6DC 69 06 ADCIM &06 ;c=1, so add 7 to get char. just on screen 0425 C6DE 9D 24 03 GCSHUC STAAX GCSIR 0426 C6E1 BD 01 03 LDAAX GWLCOL+&01 0427 C6E4 69 00 ADCIM &00 0428 C6E6 9D 25 03 STAAX GCSIR+&01 0429 C6E9 8A TXA ;Plot by X? 0430 C6EA F0 08 BEQ CSAD ;Yes?, then go down a line as well 0431 C6EC 4C 7D CA JMP IEG ;No?, then exit 0432 C6EF 0433 C6EF 0434 C6EF ;LF ($0A) - Cursor down 1 character line 0435 C6EF 0436 C6EF 20 87 C5 LF JSR ANOMQ 0437 C6F2 F0 95 BEQ CSD 0438 C6F4 A2 02 CSAD LDXIM &02 0439 C6F6 4C 20 C6 JMP GCSCHD 0440 C6F9 0441 C6F9 ;FS ($1C) Define text area 0442 C6F9 0443 C6F9 ;QEND-3 = L.H. margin = TWLCOL 0444 C6F9 ;QEND-2 = Bottom row = TWBROW 0445 C6F9 ;QEND-1 = R.H. margin = TWRCOL 0446 C6F9 ;QEND = Top row = TWTROW 0447 C6F9 0448 C6F9 [ MOS125 = &FF 0464 C6F9 | 0465 C6F9 AE 55 03 FS LDX MODE 0466 C6FC AD 21 03 LDA QEND-&02 ;Do y co-ordinates. Get bottom (higher numbered) row 0467 C6FF CD 23 03 CMP QEND ;Top row above bottom ? 0468 C702 90 16 BCC FSF ;No?, then fail 0469 C704 DD E7 C3 CMPAX PROWS ;Is > max. no. rows? 0470 C707 F0 02 BEQ FSC 0471 C709 B0 09 BCS FSE ;Yes, then fail 0472 C70B AD 22 03 FSC LDA QEND-&01 ;Do x co-ordinates. Get RH margin 0473 C70E A8 TAY 0474 C70F DD EF C3 CMPAX PCOLS ;Is > than max. cols? 0475 C712 F0 02 BEQ FSB 0476 C714 FSE 0477 C714 B0 74 BCS PRACX ;Yes, then fail 0478 C716 38 FSB SEC 0479 C717 ED 20 03 SBC QEND-&03 ;How many cols. wide ? 0480 C71A FSF 0481 C71A 90 6E BCC PRACX ;Fail if -ve no. cols. 0482 C71C ] 0483 C71C A8 TAY 0484 C71D 20 5C CA JSR SETPWW ;Set PWWDTH 0485 C720 A9 08 LDAIM &08 ;Set bit 3 for soft scrolling 0486 C722 20 9C C5 JSR STTOR 0487 C725 A2 20 LDXIM QEND-&03-V ;copy Q to TWxxxx 0488 C727 A0 08 LDYIM TWLCOL-V 0489 C729 20 40 D4 JSR COPYF 0490 C72C 20 EB CE JSR TADDR ;Is cursor still inside 0491 C72F B0 33 BCS RS ;No, then home cursor 0492 C731 4C D8 C9 FSD JMP CSDSP 0493 C734 0494 C734 RPXLXY 0495 C734 A0 03 LDYIM &03 ;~~~ Read pixel at (x,y) ~~~ 0496 C736 B1 F0 PRAAA LDAIY WARGS ;Copy (x,y) to RPXLWS ... 0497 C738 99 28 03 STAAY RPXLWS 0498 C73B 88 DEY 0499 C73C 10 F8 BPL PRAAA 0500 C73E A9 28 LDAIM RPXLWS-V ;Convert in internal co-ordinates 0501 C740 20 CF D7 JSR RPXLD ;Read pixel if extant 0502 C743 A0 04 LDYIM &04 ;Store in (XY) +4 0503 C745 D0 3B BNE PRACB ;(branch always taken) 0504 C747 0505 C747 [ MOS125 = &FF 0516 C747 ] 0517 C747 0518 C747 ;FF ($0C) Form feed 0519 C747 0520 C747 20 87 C5 FF JSR ANOMQ ;Cursors joined ? 0521 C74A D0 78 BNE FFANOM ;Yes, then clear graphics area 0522 C74C A5 D0 LDA STATS ;Window set ? 0523 C74E 29 08 ANDIM &08 ;Test bit 3 of STATS 0524 C750 [ MOS125 = &FF 0527 C750 | 0528 C750 F0 64 BEQ FFC ;Clear?, then fast clear 0529 C752 ] 0530 C752 AE 0B 03 FFA LDX TWTROW ;Initialise cursor to top row 0531 C755 8E 19 03 FFB STX CSY ;Clear this line 0532 C758 20 AC CE JSR CLTLIN 0533 C75B AE 19 03 LDX CSY ;Move down a line 0534 C75E EC 09 03 CPX TWBROW ;On the bottom ? 0535 C761 E8 INX 0536 C762 90 F1 BCC FFB ;(INX preserves c) 0537 C764 0538 C764 ;& fall through to Acorn macro assembler Page 14 VDU File - MOS02 0539 C764 0540 C764 0541 C764 ;RS ($1E) Home character cursor 0542 C764 0543 C764 20 87 C5 RS JSR ANOMQ 0544 C767 F0 22 BEQ RSA 0545 C769 [ MOS125 = &FF 0547 C769 | 0548 C769 ;RSAN Anomalous cursor home 0549 C769 0550 C769 A2 06 RSAN LDXIM GWTROW-V ;Copy GWLCOL to GCSIR 0551 C76B A0 26 LDYIM GCSIY-V 0552 C76D 20 38 D4 JSR COPY2 ;Copy 4 bytes of RAM saves 2 bytes of ROM 0553 C770 0554 C770 ;& fall through to ... 0555 C770 0556 C770 0557 C770 ;CRAN Anomalous carriage return 0558 C770 0559 C770 A2 00 CRAN LDXIM GWLCOL-V ;Copy GWLCOL to GCSIX 0560 C772 A0 24 LDYIM GCSIX-V 0561 C774 20 38 D4 JSR COPY2 0562 C777 4C 7D CA JMP IEG 0563 C77A 0564 C77A RPALET 0565 C77A 2D 60 03 AND NCOLOR ;Read parrot 0566 C77D AA TAX 0567 C77E BD 6F 03 LDAAX PARROT 0568 C781 C8 PRACA INY 0569 C782 91 F0 PRACB STAIY WARGS 0570 C784 A9 00 LDAIM &00 0571 C786 C0 04 CPYIM &04 0572 C788 D0 F7 BNE PRACA 0573 C78A 60 PRACX RTS 0574 C78B ] 0575 C78B 0576 C78B 8D 23 03 RSA STA QEND 0577 C78E 8D 22 03 STA QEND-&01 0578 C791 0579 C791 ;& fall through to .... 0580 C791 0581 C791 ;US ($1F) Move text csr to x,y 0582 C791 0583 C791 ;Put cursor to (x,y), where 0584 C791 ;x in QEND-1 & y in QEND 0585 C791 ;If illegal, leave cursor alone 0586 C791 0587 C791 20 87 C5 US JSR ANOMQ ;Cursors joined ? 0588 C794 D0 F4 BNE PRACX ;Yes, then skip 0589 C796 20 AF C7 JSR USAF ;Remember current cursor 0590 C799 18 CLC 0591 C79A AD 22 03 LDA QEND-&01 ;Add offset to x posn 0592 C79D 6D 08 03 ADC TWLCOL 0593 C7A0 8D 18 03 STA CSX 0594 C7A3 AD 23 03 LDA QEND ;Add offset to y posn 0595 C7A6 18 CLC 0596 C7A7 6D 0B 03 ADC TWTROW 0597 C7AA [ MOS125 = &FF 0600 C7AA | 0601 C7AA 20 E8 CE JSR SYTADD ;Attempt to posn. csr 0602 C7AD ] 0603 C7AD 90 82 BCC FSD ;to a JMP CSDSP 0604 C7AF 0605 C7AF A2 18 USAF LDXIM CSX-V 0606 C7B1 A0 28 LDYIM USWS-V 0607 C7B3 4C CC CD JMP SWAP2 0608 C7B6 0609 C7B6 [ MOS125 = &FF 0610 C7B6 | 0611 C7B6 FFC 0612 C7B6 4C 9D CB JMP CLATXT ;Clear?, then fast clear 0613 C7B9 ] 0614 C7B9 0615 C7B9 ;CR ($0D) Carriage return 0616 C7B9 0617 C7B9 20 87 C5 CR JSR ANOMQ 0618 C7BC [ MOS125 = &FF 0621 C7BC | 0622 C7BC D0 B2 BNE CRAN 0623 C7BE ] 0624 C7BE 20 6E CE CRA JSR SSCRIM ;Position cursor to LH edge of window 0625 C7C1 4C AE C6 JMP CSDA ;Display cursor & TADDR 0626 C7C4 0627 C7C4 LNK MOS03 0001 C7C4 0002 C7C4 TTL VDU File - MOS03 0003 C7C4 OPT MOS03 Acorn macro assembler Page 15 VDU File - MOS03 0004 C7C4 0005 C7C4 ;Last revision 15/06/82 0006 C7C4 0007 C7C4 ;15/06/82 Route ALL unknown plot commands thru VDUVEC, even in text modes 0008 C7C4 ;02/06/82 ETB mod to redef of ASCII 0009 C7C4 ;27/05/82 DCC (programme palette) recoded 0010 C7C4 ;05/05/82 Delete anomalous TAB 0011 C7C4 ; Move NAK to MOS02 0012 C7C4 ;01/05/82 Recoded to allow for forward queueing & change in variable order 0013 C7C4 ;24/04/82 ETB Function 1 (hide/display cursor) coded 0014 C7C4 ;19/04/82 DCC & DCCB moved for byte saving 0015 C7C4 ;15/04/82 NPCOL used to fix VDU 19,0,20,0,0,0 bug 0016 C7C4 ;24/03/82 DLE leaves graphics cursor alone 0017 C7C4 ; ETB to check if font exploded before reprogramming fonts 1-3 0018 C7C4 ;21/03/82 DLE to account for non-zero origins 0019 C7C4 ;22/01/82 EIG to EIGABS in graphics window definition 0020 C7C4 ;07/01/82 Catch illegal VDU 23,n,.... commands 0021 C7C4 ;15/11/81 Vertical sync user adjustment (Paul) 0022 C7C4 0023 C7C4 ;INDIVIDUAL ROUTINES 0024 C7C4 0025 C7C4 0026 C7C4 ;DLE ($10) Clear graphics area 0027 C7C4 0028 C7C4 20 69 C7 FFANOM JSR RSAN 0029 C7C7 AD 61 03 DLE LDA NPIX ;Non-graphics ? 0030 C7CA F0 33 BEQ DLEX 0031 C7CC AE 5A 03 LDX BGCOLF ;Clear to the background colour 0032 C7CF AC 5C 03 LDY GPLBMD ;Use the background colour mode 0033 C7D2 20 C5 D0 JSR SETZG ;Set this up 0034 C7D5 A2 00 LDXIM GWLCOL-V ;Copy window params from GWTROW ... 0035 C7D7 A0 28 LDYIM DLEWS-V ;Copy window parameters to DLEWS 0036 C7D9 20 32 D4 JSR COPY8 0037 C7DC 38 SEC ;How many lines to do ? 0038 C7DD AD 06 03 LDA GWTROW 0039 C7E0 ED 02 03 SBC GWBROW 0040 C7E3 A8 TAY 0041 C7E4 C8 INY ;Increment this to distinguish between 0 & 255 0042 C7E5 8C 30 03 STY DLENLN ;Line counter 0043 C7E8 A2 2C DLEA LDXIM DLEWS+&04-V ;Point to R.H. point, containing valid Y address 0044 C7EA A0 28 LDYIM DLEWS-V ;Point to L.H. point, with irrelevant Y address 0045 C7EC 20 42 D6 JSR HPLOTA ;Clear the current line 0046 C7EF AD 2E 03 LDA DLEWS+&06 ;Decrement the current line number 0047 C7F2 D0 03 BNE DLEB 0048 C7F4 CE 2F 03 DEC DLEWS+&07 0049 C7F7 CE 2E 03 DLEB DEC DLEWS+&06 0050 C7FA CE 30 03 DEC DLENLN 0051 C7FD D0 E9 BNE DLEA 0052 C7FF 60 DLEX RTS 0053 C800 0054 C800 ;DC1 ($11) Programme foreground 0055 C800 ;or background colours for text 0056 C800 0057 C800 A0 00 DCA LDYIM &00 ;Used for storing 0058 C802 F0 02 BEQ DCABA ;(branch always taken) 0059 C804 0060 C804 ;DC2 ($12) Programme foreground 0061 C804 ;or background colours for graphics 0062 C804 ;QEND-1=mode 0063 C804 ;QEND =logical colour 0064 C804 0065 C804 A0 02 DCB LDYIM &02 0066 C806 AD 23 03 DCABA LDA QEND ;Get logical colour 0067 C809 10 01 BPL DCABB ;Foreground ? 0068 C80B C8 INY ;No, then point to background locations 0069 C80C 2D 60 03 DCABB AND NCOLOR 0070 C80F 85 DA STA ZTEMP 0071 C811 AD 60 03 LDA NCOLOR ;Sneaky offset method 0072 C814 F0 1B BEQ DCABX ;Branch for TTX 0073 C816 29 07 ANDIM &07 ;to FCOLTB. A=table base 0074 C818 18 CLC 0075 C819 65 DA ADC ZTEMP ;(A) = offset +1 0076 C81B AA TAX 0077 C81C BD 23 C4 LDAAX FCOLTB -&01 0078 C81F 99 57 03 STAAY FTCOLF ;(Y) set above to 0..3 0079 C822 [ MOS125 = &FF 0084 C822 | 0085 C822 98 TYA 0086 C823 4A LSRA ;Graphics? 0087 C824 D0 0C BNE DCBAC ;Yes, then set up GPLMDE 0088 C826 18 CLC ;A=0, C=0; SBC takes one's complement 0089 C827 ED 57 03 SBC FTCOLF ;No, then set ZORA and ZEOR 0090 C82A ] 0091 C82A 85 D3 STA ZEOR ;ZEOR = NOT foreground 0092 C82C 4D 58 03 EOR BTCOLF ;ZORA = ZEOR EOR back 0093 C82F 85 D2 STA ZORA 0094 C831 60 DCABX RTS 0095 C832 AD 22 03 DCBAC LDA QEND-&01 0096 C835 99 59 03 STAAY GPLFMD -&02 ;Y=2 or 3 (for fore or background) mode 0097 C838 60 RTS 0098 C839 0099 C839 A9 20 DCTTX LDAIM TTXBCL ;TTX load with a particular byte ($20) 0100 C83B 8D 58 03 STA BTCOLF ;Used only for screen clears 0101 C83E 60 RTS 0102 C83F 0103 C83F ;DC3 ($13) is below this routine 0104 C83F 0105 C83F 0106 C83F ;DC4 ($14) Set default physical 0107 C83F ;- logical relations 0108 C83F ;Default back & foreground clrs 0109 C83F 0110 C83F A2 05 DCD LDXIM &05 ;Programme all full colours & modes to zero 0111 C841 A9 00 LDAIM &00 0112 C843 9D 57 03 DCDA STAAX FTCOLF 0113 C846 CA DEX 0114 C847 10 FA BPL DCDA 0115 C849 [ MOS125 = &FF 0119 C849 | 0120 C849 8A TXA ;A = &FF 0121 C84A AE 60 03 LDX NCOLOR ;Set foreground colours & ZORA & ZEOR 0122 C84D F0 EA BEQ DCTTX ;Branch for TTX 0123 C84F ] 0124 C84F E0 0F CPXIM &0F 0125 C851 D0 02 BNE DCDB 0126 C853 A9 3F LDAIM INVSXT ;Don't invert flashing bit 0127 C855 8D 57 03 DCDB STA FTCOLF 0128 C858 8D 59 03 STA FGCOLF 0129 C85B 49 FF EORIM &FF 0130 C85D 85 D2 STA ZORA 0131 C85F 85 D3 STA ZEOR Acorn macro assembler Page 16 VDU File - MOS03 0132 C861 8E 1F 03 STX QEND-&04 ;set logical colour := NCOLOR 0133 C864 [ MOS125 = &FF 0166 C864 | 0167 C864 A9 07 LDAIM &07 0168 C866 E0 03 CPXIM &03 ;How many colours? 0169 C868 90 0A BCC DCDLF 0170 C86A D0 0E BNE DCDLI 0171 C86C 0172 C86C ;4 colour, use shift right of $07 0173 C86C 0174 C86C 20 7F C8 JSR DCDLJ ;Programme log.=3, phys.=7 0175 C86F CE 1F 03 DEC QEND-&04 ;Programme log.=2, phys.=3 0176 C872 A9 03 LDAIM &03 ;then 1=1, 0=0 0177 C874 0178 C874 ;2 colour (TTX also executes this rouine) 0179 C874 0180 C874 20 7F C8 DCDLF JSR DCDLJ ;Programme log.=1, phys.=7 0181 C877 CE 1F 03 DEC QEND-&04 0182 C87A 0183 C87A ;16 colours - one to one 0184 C87A 0185 C87A DCDLI 0186 C87A 0187 C87A AD 1F 03 LDA QEND-&04 0188 C87D D0 F5 BNE DCDLF 0189 C87F 8D 20 03 DCDLJ STA QEND-&03 ;& fall through to .... 0190 C882 ] 0191 C882 0192 C882 ;DC3 ($13) - Programme logical/ 0193 C882 ;physical colour relation 0194 C882 0195 C882 ;Logical colour in QEND-4 0196 C882 ;Physical colour in QEND-3 0197 C882 0198 C882 08 DCC PHP 0199 C883 78 SEI 0200 C884 AD 1F 03 LDA QEND-&04 ;Determine logical colour 0201 C887 2D 60 03 AND NCOLOR 0202 C88A AA TAX 0203 C88B AD 20 03 LDA QEND-&03 ;Get physical colour 0204 C88E 29 0F DCC1 ANDIM NPCOL ;mask off confusing bits 0205 C890 9D 6F 03 STAAX PARROT ;Write to list 0206 C893 [ MOS125 = &FF 0223 C893 | 0224 C893 86 FA STX SEIWKA 0225 C895 AD 60 03 LDA NCOLOR 0226 C898 C9 03 CMPIM &03 0227 C89A 08 PHP ;Needed later 0228 C89B 4A LSRA 0229 C89C 46 FA DCCALA LSR SEIWKA ;determine start position =Logi*16/(ncolor+1)*16 0230 C89E 6A RORA 0231 C89F B0 FB BCS DCCALA 0232 C8A1 1D 6F 03 ORAAX PARROT ;Get physical colour 0233 C8A4 A0 F0 LDYIM &F0 ;Initialise loop counter 0234 C8A6 0235 C8A6 AA DCCALB TAX ;Byte to be given to VPROC1 0236 C8A7 28 PLP ;Does NCOLOR=3? 0237 C8A8 ] 0238 C8A8 08 PHP 0239 C8A9 D0 09 BNE DCCALC ;No?, then skip 0240 C8AB [ MOS125 = &FF 0249 C8AB | 0250 C8AB 0A ASLA ;b6,b5 to b7,b6; clear b0 0251 C8AC 69 40 ADCIM &40 ;carry doesn't matter (thanks Woz) 0252 C8AE 0A ASLA ;b6 EOR b5 to C 0253 C8AF 8A TXA ;restore byte 0254 C8B0 90 02 BCC DCCALC ;If b5 & b6 both set or clear, don't invert them 0255 C8B2 49 60 EORIM &60 0256 C8B4 ] 0257 C8B4 20 38 EA DCCALC JSR MVPRC1 ;Save (X) & (Y) 0258 C8B7 98 TYA ;Loop counter 0259 C8B8 [ MOS125 = &FF 0268 C8B8 | 0269 C8B8 18 CLC 0270 C8B9 6D 60 03 ADC NCOLOR 0271 C8BC A8 TAY 0272 C8BD 8A TXA ;Restore (A) 0273 C8BE 69 10 ADCIM &10 ;c=0 0274 C8C0 C8 INY 0275 C8C1 30 E3 BMI DCCALB 0276 C8C3 ] 0277 C8C3 28 PLP 0278 C8C4 28 PLP 0279 C8C5 60 RTS 0280 C8C6 0281 C8C6 0282 C8C6 ;OSWORD call to programme palette 0283 C8C6 0284 C8C6 PRPAL 0285 C8C6 08 PHP 0286 C8C7 2D 60 03 AND NCOLOR ;Get logical colour 0287 C8CA AA TAX 0288 C8CB C8 INY ;(Y):=1 0289 C8CC B1 F0 LDAIY WARGS ;Load physical colour 0290 C8CE [ MOS125 = &FF 0292 C8CE | 0293 C8CE B0 BE BCS DCC1 ;C=1 from OSB 0294 C8D0 ] 0295 C8D0 0296 C8D0 ;SYN ($16) Change mode 0297 C8D0 0298 C8D0 AD 23 03 SYN LDA QEND ;Get the mode 0299 C8D3 4C 10 CB JMP CHMODE 0300 C8D6 0301 C8D6 ;ETB ($17) Programme soft font 0302 C8D6 ;Programme character font to user definition 0303 C8D6 ;Character to be programmed in Q+08, top row in Q+07 0304 C8D6 ;through to bottom row in Q+00 0305 C8D6 0306 C8D6 AD 1B 03 ETB LDA QEND-&08 ;Is it the soft font ? 0307 C8D9 C9 20 CMPIM &20 ;Is it a printable character ? 0308 C8DB 90 38 BCC ETBD 0309 C8DD [ MOS125 = &FF 0347 C8DD | 0348 C8DD 20 50 D0 JSR CHADDR 0349 C8E0 ;returns X=font no., Y=(ZTEMPC+&01)=hard/soft page no. 0350 C8E0 ;A=font flag mask, (ZTEMPC)=hard/soft character address 0351 C8E0 2C 67 03 BIT FNTFLG ;flag set ? 0352 C8E3 D0 1E BNE ETBB ;Yes?, then just copy defn. 0353 C8E5 0D 67 03 ORA FNTFLG 0354 C8E8 8D 67 03 STA FNTFLG Acorn macro assembler Page 17 VDU File - MOS03 0355 C8EB 84 DD STY ZTEMPB +&01 ;point to hard font 0356 C8ED BC 67 03 LDYAX PGSFNT -&01 ;point to soft font 0357 C8F0 84 DF STY ZTEMPC +&01 0358 C8F2 A6 DE LDX ZTEMPC +&00 ;save character offset 0359 C8F4 A0 00 LDYIM &00 0360 C8F6 84 DC STY ZTEMPB +&00 ;align both pointers 0361 C8F8 84 DE STY ZTEMPC +&00 0362 C8FA B1 DC ETBC LDAIY ZTEMPB ;copy from hard font 0363 C8FC 91 DE STAIY ZTEMPC ;to soft font 0364 C8FE C8 INY 0365 C8FF D0 F9 BNE ETBC 0366 C901 86 DE STX ZTEMPC +&00 ;restore character offset 0367 C903 ETBB 0368 C903 A0 07 LDYIM &07 ;& copy character into the font 0369 C905 B9 1C 03 ETBA LDAAY QEND-&07 0370 C908 91 DE STAIY ZTEMPC 0371 C90A 88 DEY 0372 C90B 10 F8 BPL ETBA 0373 C90D ] 0374 C90D 60 ETCX RTS 0375 C90E 0376 C90E JMIV25 0377 C90E AD 1F 03 LDA PLMODE 0378 C911 18 CLC 0379 C912 ; C=0 0380 C912 JMIV23 ;C=1 0381 C912 6C 26 02 JMI VDUVEC 0382 C915 ; 0383 C915 C9 01 ETBD CMPIM &01 ;Valid command ? 0384 C917 90 15 BCC ETD 0385 C919 ; C=1 0386 C919 D0 F7 BNE JMIV23 ;No?, then jump indirect to user vector with C=1 0387 C91B ; 0388 C91B 20 87 C5 JSR ANOMQ ;Anom. printing? ~~~ FUNCTION 1 Turn cursor on/off ~~~ 0389 C91E D0 ED BNE ETCX ;Yes?, then don't do it 0390 C920 A9 20 LDAIM &20 0391 C922 AC 1C 03 LDY QEND-&07 ;Hide(0) or display(1)? 0392 C925 F0 03 BEQ ETCB 0393 C927 AD 5F 03 ETCA LDA CSTEMP ;RESTORE CURSOR 0394 C92A A0 0A ETCB LDYIM &0A 0395 C92C D0 2D BNE CRTCPA ;Programme the 6845 without saving to CSTEMP 0396 C92E 0397 C92E AD 1D 03 ETD LDA QEND-&06 ;~~~ FUNCTION 0 Programme 6845 register #(Q+7) WITH (Q+6) ~~~ 0398 C931 AC 1C 03 LDY QEND-&07 0399 C934 0400 C934 C0 07 CRTCP CPYIM &07 0401 C936 90 23 BCC CRTCPA ;[register<7, so not register 7 or 10] 0402 C938 D0 03 BNE CRTCPC ;[not vertical sync position] 0403 C93A 0404 C93A 6D 90 02 ADC VERTIC ;apply user adjustment (c=1) 0405 C93D 0406 C93D C0 08 CRTCPC CPYIM &08 0407 C93F D0 07 BNE CRTCPD ;[not interlace mode register] 0408 C941 09 00 ORAIM &00 ; interlace mode register 0409 C943 30 03 BMI CRTCPD ;[do not alter interlace (probably teletext)] 0410 C945 ; 0411 C945 4D 91 02 EOR INTERL ;modify interlace 0412 C948 C0 0A CRTCPD CPYIM &0A ;Cursor start register ? 0413 C94A D0 0F BNE CRTCPA ;[not cursor start register] 0414 C94C 8D 5F 03 STA CSTEMP ;Yes?, then record this for separate cursors 0415 C94F A8 TAY 0416 C950 A5 D0 LDA STATS ;Are cursors joined ? 0417 C952 29 20 ANDIM &20 0418 C954 08 PHP ;(very nasty coding, but it is short) 0419 C955 98 TYA 0420 C956 A0 0A LDYIM &0A 0421 C958 28 PLP 0422 C959 D0 06 BNE CRTCPB ;Yes, then don't write to 6845 0423 C95B 8C 00 FE CRTCPA STY CRTCA ;Address said register 0424 C95E 8D 01 FE STA CRTCD ;and store data therein 0425 C961 60 CRTCPB RTS ;(Referenced from EM) 0426 C962 0427 C962 ;ESC ($1B) does bugger all 0428 C962 0429 C962 ;Jump table points to the RTS at ACK 0430 C962 0431 C962 ;EM ($19) - Plotting 0432 C962 0433 C962 AE 61 03 EM LDX NPIX ;Filter out non-graphics modes 0434 C965 F0 A7 BEQ JMIV25 ;[text mode] 0435 C967 4C 70 D0 JMP EMA ;Jump to graphics routines 0436 C96A 0437 C96A ;Hardware scroll down 0438 C96A ;Doesn't touch cursor 0439 C96A 0440 C96A ; These routines return z=0 0441 C96A 0442 C96A AE 50 03 HSCRDN LDX TOPSCN ;Subt. BYTROW from TOPSCN 0443 C96D AD 51 03 LDA TOPSCN+&01 0444 C970 20 DE CB JSR SUBROW 0445 C973 B0 14 BCS NEWTOP ;Wraparound? No?, then done 0446 C975 6D 54 03 ADC BYTSCN ;Yes?, then add screen length 0447 C978 90 0F BCC NEWTOP ;(branch always taken) 0448 C97A 0449 C97A AE 50 03 HSCRUP LDX TOPSCN ;Add BYTROW to TOPSCN 0450 C97D AD 51 03 LDA TOPSCN+&01 0451 C980 20 B1 CA JSR ADDROW 0452 C983 10 04 BPL NEWTOP ;Wraparound? 0453 C985 38 SEC 0454 C986 ED 54 03 SBC BYTSCN ;Yes?, then subtract off screen length 0455 C989 8D 51 03 NEWTOP STA TOPSCN +&01 0456 C98C 8E 50 03 STX TOPSCN 0457 C98F A0 0C LDYIM &0C ;Prog. START of 6845 0458 C991 D0 51 BNE AXCRTA ;(branch always taken) 0459 C993 0460 C993 ;SUB ($1A) - Sets default text 0461 C993 ;& graphics windows. 0462 C993 ;Homes both cursors 0463 C993 ;Sets graphics origin to (0,0) 0464 C993 0465 C993 ;Clear all window parameters, 0466 C993 ;Both cusors, & gr. origin 0467 C993 0468 C993 A9 00 SUB LDAIM &00 0469 C995 A2 2C LDXIM VDUWS+&04-GWLCOL ;THIS VALUE LIKELY TO CHANGE ! 0470 C997 9D 00 03 SUBA STAAX GWLCOL 0471 C99A CA DEX 0472 C99B 10 FA BPL SUBA 0473 C99D 0474 C99D ;Set other parameters 0475 C99D Acorn macro assembler Page 18 VDU File - MOS03 0476 C99D AE 55 03 LDX MODE ;Get no. of char. cols. 0477 C9A0 BC EF C3 LDYAX PCOLS ;How many columns ? 0478 C9A3 8C 0A 03 STY TWRCOL ;Default text window 0479 C9A6 20 5C CA JSR SETPWW ;Set the text width 0480 C9A9 BC E7 C3 LDYAX PROWS ;Get no. char. rows 0481 C9AC 8C 09 03 STY TWBROW ;Default text window 0482 C9AF A0 03 LDYIM &03 ;GRAPHICS WINDOW Top row 0483 C9B1 8C 23 03 STY QEND 0484 C9B4 C8 INY 0485 C9B5 8C 21 03 STY QEND-&02 ;right column 0486 C9B8 CE 22 03 DEC QEND-&01 ;now = $FF 0487 C9BB CE 20 03 DEC QEND-&03 ;now = $FF 0488 C9BE 20 0D CA JSR CAN ;Transfer to window & convert co-ords 0489 C9C1 A9 F7 LDAIM &F7 ;Clear bit 3 of STATS (default windows set) 0490 C9C3 20 A7 C5 JSR STTAND 0491 C9C6 AE 50 03 LDX TOPSCN ;Programme cursor 0492 C9C9 AD 51 03 LDA TOPSCN+&01 ;to top L.H. byte 0493 C9CC 8E 4A 03 CSDSPA STX CSPOSN 0494 C9CF 8D 4B 03 STA CSPOSN +&01 0495 C9D2 10 04 BPL CSDSP 0496 C9D4 38 SEC 0497 C9D5 ED 54 03 SBC BYTSCN 0498 C9D8 86 D8 CSDSP STX ZMEMT 0499 C9DA 85 D9 STA ZMEMT +&01 0500 C9DC AE 4A 03 LDX CSPOSN 0501 C9DF AD 4B 03 LDA CSPOSN +&01 0502 C9E2 A0 0E LDYIM &0E 0503 C9E4 48 AXCRTA PHA 0504 C9E5 AD 55 03 LDA MODE ;Is it teletext ? 0505 C9E8 C9 07 CMPIM &07 0506 C9EA 68 PLA 0507 C9EB B0 10 BCS AXCRTB 0508 C9ED 86 DA STX ZTEMP ;No?, then divide by 8 0509 C9EF 4A LSRA 0510 C9F0 66 DA ROR ZTEMP 0511 C9F2 4A LSRA 0512 C9F3 66 DA ROR ZTEMP 0513 C9F5 4A LSRA 0514 C9F6 66 DA ROR ZTEMP 0515 C9F8 A6 DA LDX ZTEMP 0516 C9FA 4C FF C9 JMP AXCRTC 0517 C9FD ;For TTX, fiddle the high address lines 0518 C9FD [ MOS125 = &FF 0521 C9FD | 0522 C9FD ;on entry C=1, A=&7C..83, normal/wrapped screen address high byte, we need: 0523 C9FD ;b5 = MA13 set, TTXVDU address mapping 0524 C9FD ;b4 = MA12 clear, no HIRES wraparound 0525 C9FD ;b3 = MA11 set, high RAM bank 0526 C9FD ;b2 = MA10 indicates TTX wraparound, needed on-chip for cursor display 0527 C9FD ;b7,6 unused 0528 C9FD E9 54 AXCRTB SBCIM &54 ;map to &28..2F 0529 C9FF ] 0530 C9FF ;Write (A) to reg. (Y) of 6845 0531 C9FF ;& (X) to reg. (Y)+1 0532 C9FF 0533 C9FF 8C 00 FE AXCRTC STY CRTCA ;Access reg. (Y) 0534 CA02 8D 01 FE STA CRTCD ;Store MSB 0535 CA05 C8 INY ;Access reg. (Y)+1 0536 CA06 8C 00 FE STY CRTCA 0537 CA09 8E 01 FE STX CRTCD ;Store LSB 0538 CA0C 60 RTS 0539 CA0D 0540 CA0D ;CAN ($18) Define graphics area 0541 CA0D 0542 CA0D ;QEND-7 = L.H. margin = GWLCOL Low byte 1st 0543 CA0D ;QEND-5 = Bottom row = GWBROW 0544 CA0D ;QEND-3 = R.H. margin = GWRCOL 0545 CA0D ;QEND-1 = Top row = GWTROW 0546 CA0D 0547 CA0D 20 55 CA CAN JSR CANB ;Swap graphics cursor with innocuous bytes in WS 0548 CA10 A2 1C LDXIM QEND-&07-V 0549 CA12 A0 2C LDYIM CDELTA-V 0550 CA14 20 C7 D3 JSR TRISA ;Calculate window differences to CDELTA 0551 CA17 0D 2D 03 ORA CDELTA+&01 ;(A) returns with CDELTA+3= DeltaY, so OR with DeltaX 0552 CA1A 30 39 BMI CANB ;If either is -ve, then illegal window 0553 CA1C A2 20 LDXIM QEND-&03-V ;Convert window to Ico-ords 0554 CA1E 20 5B D1 JSR EIGABS 0555 CA21 A2 1C LDXIM QEND-&07-V 0556 CA23 20 5B D1 JSR EIGABS 0557 CA26 AD 1F 03 LDA QEND-&04 ;Are both lower margins +ve ? 0558 CA29 0D 1D 03 ORA QEND-&06 0559 CA2C 30 27 BMI CANB ;No?, then illegal 0560 CA2E AD 23 03 LDA QEND ;Is Y valid ? 0561 CA31 D0 22 BNE CANB ;Only if MSB is zero 0562 CA33 AE 55 03 LDX MODE ;Is X valid ? 0563 CA36 AD 21 03 LDA QEND-&02 ;Divide by 8 & see if > no. of character cols 0564 CA39 85 DA STA ZTEMP 0565 CA3B AD 20 03 LDA QEND-&03 ;LSB of RH margin -1 0566 CA3E 46 DA LSR ZTEMP 0567 CA40 6A RORA 0568 CA41 46 DA LSR ZTEMP 0569 CA43 D0 10 BNE CANB 0570 CA45 6A RORA 0571 CA46 4A LSRA 0572 CA47 DD EF C3 CMPAX PCOLS 0573 CA4A F0 02 BEQ CANA 0574 CA4C 10 07 BPL CANB 0575 CA4E A0 00 CANA LDYIM GWLCOL-V ;Copy to window 0576 CA50 A2 1C LDXIM QEND-&07-V ;From Q 0577 CA52 20 32 D4 JSR COPY8 0578 CA55 A2 10 CANB LDXIM GCSR-V ;Swap GCSR with CANWS, as EIGABS corrupts this 0579 CA57 A0 28 LDYIM CANWS-V 0580 CA59 4C D4 CD JMP SWAPF 0581 CA5C 0582 CA5C ;Set printer window width 0583 CA5C ;Char. width in A 0584 CA5C ;Mode in X 0585 CA5C 0586 CA5C C8 SETPWW INY 0587 CA5D 98 TYA 0588 CA5E A0 00 LDYIM &00 0589 CA60 8C 4D 03 STY PWWDTH +&01 ;Clear MSB 0590 CA63 8D 4C 03 STA PWWDTH 0591 CA66 AD 4F 03 LDA BYTCH ;How many times to shift PWWDTH left ? 0592 CA69 4A LSRA 0593 CA6A F0 09 BEQ SETPWC ;TTX? 0594 CA6C 0E 4C 03 SETPWA ASL PWWDTH 0595 CA6F 2E 4D 03 ROL PWWDTH +&01 0596 CA72 4A LSRA 0597 CA73 90 F7 BCC SETPWA 0598 CA75 60 SETPWC RTS ;This used to be FSFAIL & ESCFL & ESCBB as well Acorn macro assembler Page 19 VDU File - MOS03 0599 CA76 0600 CA76 ;GS ($1D) Define graphics origin 0601 CA76 0602 CA76 ;GSA Define graphics origin 0603 CA76 ;The co-ordinates are in external 16 bit space. This does not 0604 CA76 ;move the windows, but does move the graphics cursors 0605 CA76 0606 CA76 A2 20 GS LDXIM QEND-&03-V 0607 CA78 A0 0C LDYIM ORG-V ;Copy the new origin (external co-ords) to ORGY.. 0608 CA7A 20 40 D4 JSR COPYF 0609 CA7D [ MOS125 = &FF 0630 CA7D | 0631 CA7D ;IEG Inverse of EIG. Converts Icursor to Ecursor 0632 CA7D 0633 CA7D A0 10 IEG LDYIM GCSR-V ;Copy GCSIY to GCSY 0634 CA7F 20 3E D4 JSR COPYFB 0635 CA82 A2 02 LDXIM &02 ;Convert y co-ordinates 0636 CA84 A0 02 LDYIM &02 ;by multiplying by 4 0637 CA86 20 99 CA JSR IEGC 0638 CA89 A2 00 LDXIM &00 ;Convert x co-ordinates 0639 CA8B A0 05 LDYIM &05 ;By multiplying by 2 0640 CA8D AD 61 03 LDA NPIX ;4, or 8, depending on (NPIX) 0641 CA90 88 IEGA DEY 0642 CA91 4A LSRA 0643 CA92 D0 FC BNE IEGA 0644 CA94 AD 56 03 LDA MEMODE ;Get memory map type 0645 CA97 F0 06 BEQ IEGE ;=0 if 20K mode in which case skip one multiplication 0646 CA99 0647 CA99 1E 10 03 IEGC ASLAX GCSR 0648 CA9C 3E 11 03 ROLAX GCSR+&01 0649 CA9F IEGE 0650 CA9F 88 DEY 0651 CAA0 D0 F7 BNE IEGC 0652 CAA2 38 SEC ;Now subtract off origin to give external co-ordinate 0653 CAA3 20 A7 CA JSR IEGD 0654 CAA6 E8 INX 0655 CAA7 BD 10 03 IEGD LDAAX GCSR 0656 CAAA FD 0C 03 SBCAX ORG 0657 CAAD 9D 10 03 STAAX GCSR 0658 CAB0 60 RTS 0659 CAB1 ] 0660 CAB1 LNK MOS04 0001 CAB1 0002 CAB1 TTL VDU File - MOS04 0003 CAB1 OPT MOS04 Acorn macro assembler Page 20 VDU File - MOS04 0004 CAB1 ;Last revision 02/06/82 0005 CAB1 0006 CAB1 ;02/06/82 Implode/Explode font change, RESET (fonts) changed 0007 CAB1 ;26/05/82 Replace table TBZTBX with LSRA 0008 CAB1 ;19/05/82 Compress PAGEE code 0009 CAB1 ;18/05/82 Conditional coding to remove bug from PAGE 0010 CAB1 ;01/05/82 Considerable recoding for new variable order & forward queueing 0011 CAB1 ;19/04/82 BYTE squashing 0012 CAB1 ;24/03/82 Add soft font implosion & explosion 0013 CAB1 ; Change refs. to BEGSCN+1 to BEGSCN 0014 CAB1 ;08/02/82 Remove initialisation of TRMCH 0015 CAB1 ;07/01/82 Remove initialisation of VDUVEC 0016 CAB1 ;16/11 Bug fix - page mode only at bottom line of window 0017 CAB1 ;14/11 Initialisation of DOTS removed 0018 CAB1 ;28/10 Initialisation of FNTFLG 0019 CAB1 0020 CAB1 ;Get address of line below 0021 CAB1 0022 CAB1 48 ADDROW PHA 0023 CAB2 8A TXA 0024 CAB3 18 CLC 0025 CAB4 6D 52 03 ADC BYTROW 0026 CAB7 AA TAX 0027 CAB8 68 PLA 0028 CAB9 6D 53 03 ADC BYTROW +&01 0029 CABC 60 RTS 0030 CABD 0031 CABD ;Is page mode on ? 0032 CABD 0033 CABD ;CTRL and SHIFT keys pressed (c=1) 0034 CABD 0035 CABD 20 F1 CA PAGEF JSR PAGED ;reset LINES, N.B. does not corrupt c 0036 CAC0 ; If c=1 => set both LEDs 0037 CAC0 20 00 EA PAGE JSR MOSTST ;pause if CTRL and SHIFT keys pressed 0038 CAC3 90 02 BCC PAGEE ;[CTRL not pressed] 0039 CAC5 30 F6 BMI PAGEF ;[CTRL and SHIFT keys pressed ,c=1] 0040 CAC7 ; CTRL without SHIFT 0041 CAC7 0042 CAC7 [ PAGEFX =0 ;TRUE if bug in page to be fixed 0043 CAC7 A5 D0 PAGEE LDA STATS 0044 CAC9 49 04 EORIM &04 ;invert page mode bit 0045 CACB 29 46 ANDIM &46 ;Exit if C.E. or scroll disabled, or not in page mode 0046 CACD D0 2A BNE PAGEX 0047 CACF | 0052 CACF ] 0053 CACF 0054 CACF AD 69 02 LDA LINES ;Is a page printed yet ? 0055 CAD2 30 22 BMI PAGEA ;If -ve, then reset (more down scrolls than up) 0056 CAD4 ; ensure on bottom line of text window 0057 CAD4 AD 19 03 LDA CSY 0058 CAD7 CD 09 03 CMP TWBROW 0059 CADA 90 1A BCC PAGEA ;[not on bottom line of text window] 0060 CADC ; deal with overlap 0061 CADC 4A LSRA 0062 CADD 4A LSRA 0063 CADE 38 SEC 0064 CADF 6D 69 02 ADC LINES 0065 CAE2 6D 0B 03 ADC TWTROW ;(c=0) 0066 CAE5 CD 09 03 CMP TWBROW 0067 CAE8 90 0C BCC PAGEA ;No, then continue 0068 CAEA 18 CLC ;do not set LEDs on first scroll test 0069 CAEB ;wait for shift key 0070 CAEB 20 00 EA PAGEC JSR MOSTST 0071 CAEE 38 SEC ;test LEDs on subsequent scroll tests 0072 CAEF 10 FA BPL PAGEC 0073 CAF1 A9 FF PAGED LDAIM &FF ;Reinitialise LINES 0074 CAF3 8D 69 02 STA LINES 0075 CAF6 EE 69 02 PAGEA INC LINES 0076 CAF9 60 PAGEX RTS 0077 CAFA 0078 CAFA ;INTIALISATION ROUTINE 0079 CAFA ;Initial mode in (A) 0080 CAFA 0081 CAFA 48 RESET PHA ;Push mode 0082 CAFB A2 7F LDXIM VEND-V ;Clear all variables 0083 CAFD A9 00 LDAIM &00 0084 CAFF 85 D0 STA STATS 0085 CB01 9D FF 02 RESETA STAAX V-&01 0086 CB04 CA DEX 0087 CB05 D0 FA BNE RESETA 0088 CB07 ; X=0 **** AND EQ status (used by FONT) **** 0089 CB07 20 FD CC JSR FONT ;Ensure font imploded 0090 CB0A 68 PLA ;Pull the mode back again 0091 CB0B A2 7F LDXIM &7F ;Initialise CHCSR to character for DEL 0092 CB0D 8E 66 03 STX CHCSR ;and fall through to ... 0093 CB10 0094 CB10 ;MODE CHANGE 0095 CB10 0096 CB10 2C 8E 02 CHMODE BIT MODEL ;adjust according to model 0097 CB13 30 02 BMI CHMOD1 ;[model B] 0098 CB15 09 04 ORAIM &04 ;model A 0099 CB17 29 07 CHMOD1 ANDIM &07 0100 CB19 AA TAX 0101 CB1A 8E 55 03 STX MODE ;Initialise MODE 0102 CB1D BD 14 C4 LDAAX COLMOD ;Get no. colours 0103 CB20 8D 60 03 STA NCOLOR ;=0 if TTX 0104 CB23 BD FF C3 LDAAX BYTCHT ;No. bytes / char. 0105 CB26 8D 4F 03 STA BYTCH 0106 CB29 BD 3A C4 LDAAX NPIXTB ;no. pixles per byte -1, =0 if non-graphics mode 0107 CB2C 8D 61 03 STA NPIX 0108 CB2F D0 02 BNE CHMODB 0109 CB31 A9 07 LDAIM &07 ;Initialise left and right masks for read character 0110 CB33 0A CHMODB ASLA ;Define left and right masks. PRESERVE c !!! 0111 CB34 A8 TAY 0112 CB35 B9 06 C4 LDAAY MASKTB -&01 ;Offset to right mask 0113 CB38 8D 63 03 STA MASKR 0114 CB3B 0A CHMODC ASLA 0115 CB3C 10 FD BPL CHMODC ;Generate left most mask 0116 CB3E 8D 62 03 STA MASKL ;c=0 - preserve until byte width type generated 0117 CB41 BC 40 C4 LDYAX MODETB ;Memory map type 0118 CB44 8C 56 03 STY MEMODE 0119 CB47 B9 4F C4 LDAAY CZERO ;Initialise C0 0120 CB4A 20 1F EA JSR CREG ;must preserve c=0 0121 CB4D B9 4B C4 LDAAY CONE 0122 CB50 20 1F EA JSR CREG 0123 CB53 B9 59 C4 LDAAY BYTSTA ;Total bytes dsp.'ed 0124 CB56 8D 54 03 STA BYTSCN 0125 CB59 B9 5E C4 LDAAY STSCTB ;Addr. 1st to disp'ed 0126 CB5C 8D 4E 03 STA BEGSCN 0127 CB5F [ MOS125 = &FF 0133 CB5F | Acorn macro assembler Page 21 VDU File - MOS04 0134 CB5F 98 TYA ;Get byte width type 0135 CB60 49 07 EORIM &07 0136 CB62 4A LSRA 0137 CB63 AA TAX 0138 CB64 CA DEX ;Map (0,1,2,3,4) to (2,2,1,1,0) 0139 CB65 ] 0140 CB65 BD 66 C4 LDAAX TBZTBA ;LSB of table addr. 0141 CB68 85 E0 STA ZTBL 0142 CB6A A9 C3 LDAIM /(HRGTB ) ;MSB of same (always the same) 0143 CB6C 85 E1 STA ZTBL +&01 0144 CB6E BD 63 C4 LDAAX BYTRTA ;Byte width of row 0145 CB71 8D 52 03 STA BYTROW 0146 CB74 8E 53 03 STX BYTROW +&01 0147 CB77 A9 43 LDAIM &43 ;Preserve b6, b1 & b0 of STATS only 0148 CB79 20 A7 C5 JSR STTAND ;Clear all others 0149 CB7C AE 55 03 LDX MODE ;Indirect mode to mMODREG 0150 CB7F BD F7 C3 LDAAX INDMOD ;from this table 0151 CB82 20 27 EA JSR MVPRC0 ;as close as possible to the reprogramming of the 6845 0152 CB85 0153 CB85 ;PROGRAMME THE 6845 0154 CB85 0155 CB85 08 PHP 0156 CB86 78 SEI 0157 CB87 BE 69 C4 LDXAY CRTCX ;Get the table to Xmt 0158 CB8A A0 0B LDYIM &0B ;No. bytes to feed it 0159 CB8C BD 6E C4 CRTCLP LDAAX CRTCTB ;Load byte to 0160 CB8F 20 34 C9 JSR CRTCP ;Programme the 6845 and save value of cursor start 0161 CB92 CA DEX 0162 CB93 88 DEY 0163 CB94 10 F6 BPL CRTCLP 0164 CB96 28 PLP 0165 CB97 0166 CB97 20 3F C8 JSR DCD ;Default log.phys. cols. 0167 CB9A 20 93 C9 JSR SUB ;Clear any windowing 0168 CB9D 0169 CB9D ;fall through to ..... 0170 CB9D 0171 CB9D A2 00 CLATXT LDXIM &00 ;TOPSCN:=BEGSCN 0172 CB9F AD 4E 03 LDA BEGSCN ;Load must be in this to ensure n=0, tested in CSDSPA 0173 CBA2 8E 50 03 STX TOPSCN 0174 CBA5 8D 51 03 STA TOPSCN +&01 0175 CBA8 20 CC C9 JSR CSDSPA ;Home cursor 0176 CBAB A0 0C LDYIM &0C ;Take divided address 0177 CBAD 20 FF C9 JSR AXCRTC 0178 CBB0 AD 58 03 LDA BTCOLF 0179 CBB3 AE 56 03 LDX MEMODE ;Get mem.map type 0180 CBB6 BC 54 C4 LDYAX CLSCTA ;Set up jump vector 0181 CBB9 8C 5D 03 STY JVEC 0182 CBBC A0 CC LDYIM /(CLASCA ) ;Used to be LDYAX CLSCTB 0183 CBBE 8C 5E 03 STY JVEC +&01 0184 CBC1 A2 00 LDXIM &00 0185 CBC3 8E 69 02 STX LINES ;Initialise the number of lines scrolled 0186 CBC6 8E 18 03 STX CSX 0187 CBC9 8E 19 03 STX CSY 0188 CBCC 6C 5D 03 JMI JVEC 0189 CBCF 0190 CBCF RCHDEF 0191 CBCF 20 50 D0 JSR CHADDR ;Read character definition 0192 CBD2 A0 00 LDYIM &00 ;Address character (start of defn. now in ZTEMPC) 0193 CBD4 B1 DE PRABA LDAIY ZTEMPC ;Copy definition 0194 CBD6 C8 INY 0195 CBD7 91 F0 STAIY WARGS 0196 CBD9 C0 08 CPYIM &08 0197 CBDB D0 F7 BNE PRABA 0198 CBDD 60 RTS 0199 CBDE 0200 CBDE [ MOS125 = &FF 0201 CBDE | 0202 CBDE ;Get the next line up, 0203 CBDE ;test if wraparound 0204 CBDE ;This is here as padding 0205 CBDE 0206 CBDE 48 SUBROW PHA 0207 CBDF 8A TXA 0208 CBE0 38 SEC 0209 CBE1 ED 52 03 SBC BYTROW 0210 CBE4 AA TAX 0211 CBE5 68 PLA 0212 CBE6 ED 53 03 SBC BYTROW +&01 0213 CBE9 CD 4E 03 CMP BEGSCN 0214 CBEC 60 RTS 0215 CBED 0216 CBED ;NORTH 0217 CBED 0218 CBED ; Returns zero false 0219 CBED 38 NBDY SEC 0220 CBEE A5 D6 LDA ZMEMG 0221 CBF0 ED 52 03 SBC BYTROW 0222 CBF3 85 D6 STA ZMEMG 0223 CBF5 A5 D7 LDA ZMEMG +&01 0224 CBF7 ED 53 03 SBC BYTROW +&01 0225 CBFA CD 4E 03 CMP BEGSCN ;Wraparound ? 0226 CBFD B0 03 BCS NBDYA 0227 CBFF 6D 54 03 ADC BYTSCN 0228 CC02 85 D7 NBDYA STA ZMEMG +&01 0229 CC04 A0 07 LDYIM &07 0230 CC06 60 RTS 0231 CC07 ] 0232 CC07 0233 CC07 9D 00 30 CLASCA STAAX &3000 ;Modes 1-3 (20K) 0234 CC0A 9D 00 31 STAAX &3100 0235 CC0D 9D 00 32 STAAX &3200 0236 CC10 9D 00 33 STAAX &3300 0237 CC13 9D 00 34 STAAX &3400 0238 CC16 9D 00 35 STAAX &3500 0239 CC19 9D 00 36 STAAX &3600 0240 CC1C 9D 00 37 STAAX &3700 0241 CC1F 9D 00 38 STAAX &3800 0242 CC22 9D 00 39 STAAX &3900 0243 CC25 9D 00 3A STAAX &3A00 0244 CC28 9D 00 3B STAAX &3B00 0245 CC2B 9D 00 3C STAAX &3C00 0246 CC2E 9D 00 3D STAAX &3D00 0247 CC31 9D 00 3E STAAX &3E00 0248 CC34 9D 00 3F STAAX &3F00 0249 CC37 9D 00 40 CLASCB STAAX &4000 ;Mode 3 (16k) 0250 CC3A 9D 00 41 STAAX &4100 0251 CC3D 9D 00 42 STAAX &4200 0252 CC40 9D 00 43 STAAX &4300 0253 CC43 9D 00 44 STAAX &4400 0254 CC46 9D 00 45 STAAX &4500 Acorn macro assembler Page 22 VDU File - MOS04 0255 CC49 9D 00 46 STAAX &4600 0256 CC4C 9D 00 47 STAAX &4700 0257 CC4F 9D 00 48 STAAX &4800 0258 CC52 9D 00 49 STAAX &4900 0259 CC55 9D 00 4A STAAX &4A00 0260 CC58 9D 00 4B STAAX &4B00 0261 CC5B 9D 00 4C STAAX &4C00 0262 CC5E 9D 00 4D STAAX &4D00 0263 CC61 9D 00 4E STAAX &4E00 0264 CC64 9D 00 4F STAAX &4F00 0265 CC67 9D 00 50 STAAX &5000 0266 CC6A 9D 00 51 STAAX &5100 0267 CC6D 9D 00 52 STAAX &5200 0268 CC70 9D 00 53 STAAX &5300 0269 CC73 9D 00 54 STAAX &5400 0270 CC76 9D 00 55 STAAX &5500 0271 CC79 9D 00 56 STAAX &5600 0272 CC7C 9D 00 57 STAAX &5700 0273 CC7F 9D 00 58 CLASCC STAAX &5800 ;Modes 4,5 (10K) 0274 CC82 9D 00 59 STAAX &5900 0275 CC85 9D 00 5A STAAX &5A00 0276 CC88 9D 00 5B STAAX &5B00 0277 CC8B 9D 00 5C STAAX &5C00 0278 CC8E 9D 00 5D STAAX &5D00 0279 CC91 9D 00 5E STAAX &5E00 0280 CC94 9D 00 5F STAAX &5F00 0281 CC97 9D 00 60 CLASCD STAAX &6000 ;Mode 6 (8k) 0282 CC9A 9D 00 61 STAAX &6100 0283 CC9D 9D 00 62 STAAX &6200 0284 CCA0 9D 00 63 STAAX &6300 0285 CCA3 9D 00 64 STAAX &6400 0286 CCA6 9D 00 65 STAAX &6500 0287 CCA9 9D 00 66 STAAX &6600 0288 CCAC 9D 00 67 STAAX &6700 0289 CCAF 9D 00 68 STAAX &6800 0290 CCB2 9D 00 69 STAAX &6900 0291 CCB5 9D 00 6A STAAX &6A00 0292 CCB8 9D 00 6B STAAX &6B00 0293 CCBB 9D 00 6C STAAX &6C00 0294 CCBE 9D 00 6D STAAX &6D00 0295 CCC1 9D 00 6E STAAX &6E00 0296 CCC4 9D 00 6F STAAX &6F00 0297 CCC7 9D 00 70 STAAX &7000 0298 CCCA 9D 00 71 STAAX &7100 0299 CCCD 9D 00 72 STAAX &7200 0300 CCD0 9D 00 73 STAAX &7300 0301 CCD3 9D 00 74 STAAX &7400 0302 CCD6 9D 00 75 STAAX &7500 0303 CCD9 9D 00 76 STAAX &7600 0304 CCDC 9D 00 77 STAAX &7700 0305 CCDF 9D 00 78 STAAX &7800 0306 CCE2 9D 00 79 STAAX &7900 0307 CCE5 9D 00 7A STAAX &7A00 0308 CCE8 9D 00 7B STAAX &7B00 0309 CCEB 9D 00 7C CLASCE STAAX &7C00 ;Mode 7 (1k = TTX) 0310 CCEE 9D 00 7D STAAX &7D00 0311 CCF1 9D 00 7E STAAX &7E00 0312 CCF4 9D 00 7F STAAX &7F00 0313 CCF7 E8 INX 0314 CCF8 F0 61 BEQ ENSCRX 0315 CCFA 6C 5D 03 RUNNER JMI JVEC 0316 CCFD 0317 CCFD [ MOS125 = &FF 0332 CCFD ] 0333 CCFD 0334 CCFD FONT 0335 CCFD ; 0336 CCFD ; implode font 0337 CCFD ; 0338 CCFD A9 0F LDAIM &0F ;Fonts 1,2,3 hard (set 0). MSb not used 0339 CCFF 8D 67 03 STA FNTFLG 0340 CD02 ; 0341 CD02 A9 0C LDAIM SFPAGE 0342 CD04 A0 06 LDYIM &06 ;Set Fonts 1 to 7 to page SFPAGE 0343 CD06 99 68 03 FIMPA STAAY PGSFNT 0344 CD09 88 DEY 0345 CD0A 10 FA BPL FIMPA 0346 CD0C ; 0347 CD0C ; test operation type 0348 CD0C ; 0349 CD0C ; force X in range 0350 CD0C E0 07 CPXIM &07 0351 CD0E 90 02 BCC FONTOK ;[X <= 6] 0352 CD10 A2 06 LDXIM &06 0353 CD12 FONTOK ;0 <= X <= 6 0354 CD12 8E 46 02 STX FONTSW ;record font state 0355 CD15 ; 0356 CD15 AD 43 02 LDA IHWM 0357 CD18 ; 0358 CD18 ; explode fonts that lie within extension pages 0359 CD18 ; 0360 CD18 A2 00 LDXIM &00 0361 CD1A FEXPA 0362 CD1A EC 46 02 CPX FONTSW 0363 CD1D B0 0B BCS FEXPA0 0364 CD1F ; C=0 0365 CD1F BC BA C4 LDYAX FFSZOT 0366 CD22 99 68 03 STAAY PGSFNT 0367 CD25 ; C=0 0368 CD25 69 01 ADCIM &01 0369 CD27 E8 INX 0370 CD28 D0 F0 BNE FEXPA ;[ALWAYS jump] 0371 CD2A FEXPA0 0372 CD2A ; 0373 CD2A ;X = FONTSW 0374 CD2A 8D 44 02 STA HWM 0375 CD2D ; 0376 CD2D A8 TAY 0377 CD2E F0 2B BEQ FONT0 0378 CD30 A2 11 LDXIM SVHWMC 0379 CD32 4C 6F F1 JMP SVOP 0380 CD35 0381 CD35 0382 CD35 LNK MOS05 0001 CD35 0002 CD35 TTL VDU File - MOS05 0003 CD35 OPT MOS05 Acorn macro assembler Page 23 VDU File - MOS05 0004 CD35 ; 0005 CD35 ;Last update 05/05/82 0006 CD35 0007 CD35 ;05/05/82 RSAN corrected 0008 CD35 ;05/05/82 TADDRY changed to allow for only 1 table 0009 CD35 ;01/05/82 Recoded using new variable order & manifests 0010 CD35 ;01/05/82 Recode for new order of variables 0011 CD35 ;22/04/82 Encode ADDSCN & SUBSCN 0012 CD35 ;19/04/82 Comments added plus small byte squash 0013 CD35 ;25/03/82 Change all refs. to BEGSCN+1 to BEGSCN 0014 CD35 0015 CD35 ;Account for scroll disabling if needs be 0016 CD35 ;Requires c=1 if scroll DOWN (cursor up) & vice versa 0017 CD35 ;If scroll enabled (b1 of STATS =0) adjusts PCSY unless on a margin 0018 CD35 ;If scroll disabled, wraps cursor, pulls return address from stack 0019 CD35 ;and jumps to CSDA. 0020 CD35 0021 CD35 A9 02 ENSCRL LDAIM &02 ;Is scroll disabled ? 0022 CD37 24 D0 BIT STATS 0023 CD39 D0 02 BNE ENSCRM ;Yes?, then skip 0024 CD3B 50 32 BVC ENSCRR ;Or is CE set ? 0025 CD3D AD 09 03 ENSCRM LDA TWBROW ;Assume scroll up (so go to bottom row) 0026 CD40 90 03 BCC ENSCRN ;Unless c=1 0027 CD42 AD 0B 03 LDA TWTROW ;Whence scroll DOWN (& go to top row) 0028 CD45 70 08 ENSCRN BVS ENSCRO ;If OUTPUT cursor, skip 0029 CD47 8D 19 03 STA CSY ;(this assumes windows are rectangular!) 0030 CD4A 68 PLA ;Cheat return stack 0031 CD4B 68 PLA 0032 CD4C 4C AE C6 JMP CSDA 0033 CD4F 08 ENSCRO PHP ;To preserve carry 0034 CD50 CD 65 03 CMP PCSY ;Would the input cursor like to go off screen ? 0035 CD53 F0 19 BEQ ENSCRP ;Yes?, then don't readdress it 0036 CD55 28 PLP ;Restore the carry, to see which way to go 0037 CD56 90 04 BCC ENSCRQ 0038 CD58 CE 65 03 DEC PCSY ;Scroll DOWN, so follow it down 0039 CD5B [ MOS125 = &FF 0040 CD5B | 0041 CD5B FONT0 0042 CD5B ] 0043 CD5B 60 ENSCRX RTS ;May be referenced from MOS04 0044 CD5C EE 65 03 ENSCRQ INC PCSY ;Scroll UP, so go up as well 0045 CD5F 60 RTS 0046 CD60 0047 CD60 ;OCSRDL Delete output cursor 0048 CD60 0049 CD60 08 OCSRDL PHP 0050 CD61 48 PHA 0051 CD62 AC 4F 03 LDY BYTCH 0052 CD65 88 DEY ;TTX? 0053 CD66 D0 0A BNE OCSRIV ;Not TTX?, then same as writing cursor, as it inverts 0054 CD68 AD 38 03 LDA TTXTMP ;TTX?, then write remebered byte 0055 CD6B 91 D8 STAIY ZMEMT ;(Y)=0 0056 CD6D 68 OCSREX PLA ;& exit 0057 CD6E 28 ENSCRP PLP ;Get the stack correct 0058 CD6F 60 ENSCRR RTS 0059 CD70 0060 CD70 ;OCSRWR Write output cursor 0061 CD70 0062 CD70 [ MOS125 = &FF 0084 CD70 | 0085 CD70 08 OCSRWR PHP 0086 CD71 48 PHA 0087 CD72 A9 3F OCSRIV LDAIM INVSXT 0088 CD74 AC 4F 03 LDY BYTCH 0089 CD77 C0 20 CPYIM &20 ;Mode 2 ? 0090 CD79 F0 13 BEQ OCSRIW ;Yes?, then don't invert the flashing bit 0091 CD7B A9 FF LDAIM &FF 0092 CD7D 88 DEY ;TTX? 0093 CD7E D0 08 BNE OCSRIU 0094 CD80 B1 D8 LDAIY ZMEMT ;(Y)=0 Yes?, then read byte directly from screen 0095 CD82 8D 38 03 STA TTXTMP ;and store it out of harm's way (no plotting in this mode) 0096 CD85 4D 66 03 EOR CHCSR ;Write the cursor 0097 CD88 48 OCSRIU PHA 0098 CD89 51 D8 EORIY ZMEMT ;Invert the character cell 0099 CD8B 91 D8 STAIY ZMEMT 0100 CD8D 68 PLA 0101 CD8E 88 OCSRIW DEY 0102 CD8F 10 F7 BPL OCSRIU 0103 CD91 30 DA BMI OCSREX ; Branch always 0104 CD93 ] 0105 CD93 0106 CD93 ;Soft scrolling (non-anom.) 0107 CD93 0108 CD93 ;Scroll DOWN 0109 CD93 0110 CD93 20 5B CE SSCRDN JSR SSCRIN ;Initialise 0111 CD96 AD 09 03 LDA TWBROW ;1st receive address is bottom LH point 0112 CD99 8D 19 03 STA CSY ;(CSX initialised in SSCRIN) 0113 CD9C 20 09 CF JSR TADDRY ;address bottom LH point (guaranteed in window) 0114 CD9F 20 DE CB SSCRDA JSR SUBROW ;Get the address of the LH point of the next line up 0115 CDA2 B0 03 BCS SSCRDB ;Wraparound between these two lines? NO, then continue 0116 CDA4 6D 54 03 ADC BYTSCN ;Yes,then add screen and note we must scroll slowly! 0117 CDA7 85 DB SSCRDB STA ZTEMP +&01 ;store transmit address 0118 CDA9 86 DA STX ZTEMP 0119 CDAB 85 DC STA ZTEMPB ;& MSB of next receive address (LSB is not changed) 0120 CDAD [ MOS125 = &FF 0127 CDAD | 0128 CDAD 90 0A BCC SSCRDC ;c unchanged since just after SSCRDA 0129 CDAF 20 DE CB SSCRDE JSR SUBROW ;Get next line up 0130 CDB2 90 05 BCC SSCRDC ;Wraparound occured ?, then slow scroll to be safe 0131 CDB4 20 38 CE JSR XMIT ;Scroll fast is possible 0132 CDB7 F0 03 BEQ SSCRDD ;xmit returns EQ 0133 CDB9 20 73 CE SSCRDC JSR SSCRS ;Scroll slowly ! 0134 CDBC ] 0135 CDBC A5 DC SSCRDD LDA ZTEMPB ;MSB of next receive address 0136 CDBE A6 DA LDX ZTEMP ;LSB of same 0137 CDC0 85 D9 STA ZMEMT +&01 ;Initialise next receive address 0138 CDC2 86 D8 STX ZMEMT 0139 CDC4 C6 DE DEC ZTEMPC ;Any more lines to copy ? 0140 CDC6 D0 D7 BNE SSCRDA ;Don't bother to copy last line 0141 CDC8 A2 28 SSCREX LDXIM SSWS-V ;Preserve or restore current text cursor 0142 CDCA A0 18 LDYIM CSX-V 0143 CDCC A9 02 SWAP2 LDAIM &02 0144 CDCE D0 06 BNE SWAP 0145 CDD0 A2 24 SWAPB LDXIM GCSIR-V ;SPLOTY requires c preserved 0146 CDD2 A0 14 SWAPC LDYIM OLDCS-V 0147 CDD4 0148 CDD4 ;SWAPF swaps 4 bytes between (V)+(X) & (V)+(Y) 0149 CDD4 0150 CDD4 A9 04 SWAPF LDAIM &04 ;by falling through to ... 0151 CDD6 Acorn macro assembler Page 24 VDU File - MOS05 0152 CDD6 ;SWAP swaps (A) bytes between (V)+(X) & (V)+(Y) 0153 CDD6 0154 CDD6 85 DA SWAP STA ZTEMP 0155 CDD8 BD 00 03 SWAPA LDAAX V 0156 CDDB 48 PHA 0157 CDDC B9 00 03 LDAAY V 0158 CDDF 9D 00 03 STAAX V 0159 CDE2 68 PLA 0160 CDE3 99 00 03 STAAY V 0161 CDE6 E8 INX 0162 CDE7 C8 INY 0163 CDE8 C6 DA DEC ZTEMP 0164 CDEA D0 EC BNE SWAPA 0165 CDEC 60 RTS 0166 CDED 0167 CDED 0168 CDED [ MOS125 = &FF 0169 CDED | 0170 CDED ;(SORTY exits with (X)<(Y)) 0171 CDED 0172 CDED A2 20 SORTA LDXIM NEWPT-V 0173 CDEF A0 14 LDYIM OLDCS-V 0174 CDF1 BD 02 03 SORTY LDAAX V+&02 0175 CDF4 D9 02 03 CMPAY V+&02 0176 CDF7 BD 03 03 LDAAX V+&03 0177 CDFA F9 03 03 SBCAY V+&03 0178 CDFD 10 D5 BPL SWAPF 0179 CDFF 60 RTS 0180 CE00 ] 0181 CE00 0182 CE00 ;Soft scroll UP 0183 CE00 0184 CE00 20 5B CE SSCRUP JSR SSCRIN ;Initialise 0185 CE03 AC 0B 03 LDY TWTROW ;Receive from top line, LH column 0186 CE06 8C 19 03 STY CSY 0187 CE09 20 09 CF JSR TADDRY ;Get 1st receive address (point guaranteed in window) 0188 CE0C 20 B1 CA SSCRUA JSR ADDROW ;Get line below 0189 CE0F 10 04 BPL SSCRUE ;Wraparound ? 0190 CE11 38 SEC ;Yes, then correct and scroll slowly 0191 CE12 ED 54 03 SBC BYTSCN 0192 CE15 85 DB SSCRUE STA ZTEMP +&01 ;Transmit address 0193 CE17 86 DA STX ZTEMP 0194 CE19 85 DC STA ZTEMPB ;MSB of next receive addr., LSB is preserved 0195 CE1B [ MOS125 = &FF 0202 CE1B | 0203 CE1B B0 0A BCS SSCRUC ;(c unchanged since just after SSCRUA) 0204 CE1D 20 B1 CA SSCRUB JSR ADDROW ;Get next line down 0205 CE20 30 05 BMI SSCRUC ;Wraparound ?, then scroll slowly to be safe 0206 CE22 20 38 CE JSR XMIT ;No?, then we can scroll fast 0207 CE25 F0 03 BEQ SSCRUD ;xmit returns EQ 0208 CE27 20 73 CE SSCRUC JSR SSCRS ;Scroll slowly 0209 CE2A ] 0210 CE2A A5 DC SSCRUD LDA ZTEMPB ;Load next receive address 0211 CE2C A6 DA LDX ZTEMP 0212 CE2E 85 D9 STA ZMEMT +&01 ;and store it 0213 CE30 86 D8 STX ZMEMT 0214 CE32 C6 DE DEC ZTEMPC ;any more lines to copy ? 0215 CE34 D0 D6 BNE SSCRUA ;don't bother with the last line 0216 CE36 F0 90 BEQ SSCREX ; Jump always 0217 CE38 0218 CE38 ;XMIT - Fast soft scroll 0219 CE38 ;Copy PWWDTH bytes from (ZTEMP) to (ZMEMT) 0220 CE38 0221 CE38 AE 4D 03 XMIT LDX PWWDTH +&01 ;How many pages? 0222 CE3B F0 10 BEQ XMITB ;None?, then attempt fractional 0223 CE3D A0 00 LDYIM &00 0224 CE3F B1 DA XMITA LDAIY ZTEMP ;Inner loop - copy complete page 0225 CE41 91 D8 STAIY ZMEMT 0226 CE43 C8 INY 0227 CE44 D0 F9 BNE XMITA 0228 CE46 E6 D9 INC ZMEMT +&01 ;Prepare to copy next page 0229 CE48 E6 DB INC ZTEMP +&01 0230 CE4A CA DEX ;Any more complete pages to copy ? 0231 CE4B D0 F2 BNE XMITA 0232 CE4D AC 4C 03 XMITB LDY PWWDTH ;Copy fractional page? 0233 CE50 F0 08 BEQ XMITD ;No?, then exit 0234 CE52 88 XMITC DEY 0235 CE53 B1 DA LDAIY ZTEMP ;Yes?, then do so 0236 CE55 91 D8 STAIY ZMEMT 0237 CE57 98 TYA 0238 CE58 D0 F8 BNE XMITC 0239 CE5A 60 XMITD RTS ;Referenced below 0240 CE5B 0241 CE5B ;SSCRIN Soft scroll initialisation 0242 CE5B 0243 CE5B ;(SSWS) := (CSX)(CSY) 0244 CE5B ;(CSX) := (TWLCOL) 0245 CE5B ;(ZTEMPC) := No. of rows to scroll, minus one 0246 CE5B 0247 CE5B 20 C8 CD SSCRIN JSR SSCREX ;Store current text cursor for future reference 0248 CE5E 38 SEC ;Determine no. of rows to scroll 0249 CE5F AD 09 03 LDA TWBROW ;i.e. no. rows in window minus 1 0250 CE62 ED 0B 03 SBC TWTROW 0251 CE65 85 DE STA ZTEMPC 0252 CE67 D0 05 BNE SSCRIM 0253 CE69 68 PLA ;If zero lines to scroll, then cheat stack 0254 CE6A 68 PLA 0255 CE6B 4C C8 CD JMP SSCREX ;& restore cursor 0256 CE6E 0257 CE6E AD 08 03 SSCRIM LDA TWLCOL ;Put x cursor on LH margin 0258 CE71 10 70 BPL CLTLND 0259 CE73 0260 CE73 0261 CE73 ;SSCRS Slow soft scroll 0262 CE73 ;Scrolls 1 row of characters, one by one from (ZTEMP) to (ZMEMT), 0263 CE73 ;preserving the LSB of ZTEMP. 0264 CE73 ;Requires that ZMEMT & ZTEMP be juxtaposed. 0265 CE73 ;Checks for wraparound after each character is copied 0266 CE73 0267 CE73 A5 DA SSCRS LDA ZTEMP ;Push LSB of ZTEMP 0268 CE75 48 PHA 0269 CE76 38 SEC ;Calc no. chars to copy -1 0270 CE77 AD 0A 03 LDA TWRCOL 0271 CE7A ED 08 03 SBC TWLCOL 0272 CE7D 85 DF STA ZTEMPC +&01 ;No. of columns to be scrolled (for loop) 0273 CE7F AC 4F 03 SSCRSA LDY BYTCH 0274 CE82 88 DEY 0275 CE83 B1 DA SSCRSB LDAIY ZTEMP ;~~~ Copy 1 character ~~~ 0276 CE85 91 D8 STAIY ZMEMT ;by copying (BYTCH) consecutive bytes 0277 CE87 88 DEY 0278 CE88 10 F9 BPL SSCRSB Acorn macro assembler Page 25 VDU File - MOS05 0279 CE8A A2 02 LDXIM &02 ;Now add BYTCH to ZMEMT & ZTEMP, 0280 CE8C 18 SSCRSC CLC ;checking for wraparound on both 0281 CE8D B5 D8 LDAZX ZMEMT ;uses ZX mode, hence need for ZMEMT to be next to ZTEMP 0282 CE8F 6D 4F 03 ADC BYTCH 0283 CE92 95 D8 STAZX ZMEMT 0284 CE94 B5 D9 LDAZX ZMEMT +&01 0285 CE96 69 00 ADCIM &00 0286 CE98 10 04 BPL SSCRSD ;Did wraparound occur? 0287 CE9A 38 SEC 0288 CE9B ED 54 03 SBC BYTSCN 0289 CE9E 95 D9 SSCRSD STAZX ZMEMT +&01 0290 CEA0 CA DEX 0291 CEA1 CA DEX 0292 CEA2 F0 E8 BEQ SSCRSC ;(Do ZMEMT) 0293 CEA4 C6 DF DEC ZTEMPC +&01 ;Any more characters? 0294 CEA6 10 D7 BPL SSCRSA 0295 CEA8 68 PLA ;Restore LSB of ZMEMT 0296 CEA9 85 DA STA ZTEMP 0297 CEAB 60 RTS 0298 CEAC 0299 CEAC ;Clear the line of text addressed by CSY 0300 CEAC ;Preserve CSY & CSX 0301 CEAC 0302 CEAC AD 18 03 CLTLIN LDA CSX ;Push the current X cursor position 0303 CEAF 48 PHA 0304 CEB0 20 6E CE JSR SSCRIM ;CSX = Left margin of window 0305 CEB3 20 09 CF JSR TADDRY ;Init. ZMEMT 0306 CEB6 38 SEC 0307 CEB7 AD 0A 03 LDA TWRCOL 0308 CEBA ED 08 03 SBC TWLCOL 0309 CEBD 85 DC STA ZTEMPB ;Column count 0310 CEBF AD 58 03 CLTLNA LDA BTCOLF ;get colour 0311 CEC2 AC 4F 03 LDY BYTCH ;Bytes / character 0312 CEC5 88 CLTNB DEY ;Inner loop - clear one character cell 0313 CEC6 91 D8 STAIY ZMEMT ;(preserves z from previous DEY) 0314 CEC8 D0 FB BNE CLTNB ;1 char cell 0315 CECA 8A TXA ;Update ZMEMT 0316 CECB 18 CLC 0317 CECC 6D 4F 03 ADC BYTCH 0318 CECF AA TAX 0319 CED0 A5 D9 LDA ZMEMT +&01 0320 CED2 69 00 ADCIM &00 0321 CED4 10 04 BPL CLNLC ;Wraparound ? 0322 CED6 38 SEC ;Yes, then subtract off the number of bytes per screen 0323 CED7 ED 54 03 SBC BYTSCN 0324 CEDA 86 D8 CLNLC STX ZMEMT 0325 CEDC 85 D9 STA ZMEMT +&01 0326 CEDE C6 DC DEC ZTEMPB ;One less character to clear 0327 CEE0 10 DD BPL CLTLNA ;Any more? 0328 CEE2 68 PLA 0329 CEE3 8D 18 03 CLTLND STA CSX 0330 CEE6 38 FAIL SEC 0331 CEE7 60 RTS 0332 CEE8 0333 CEE8 0334 CEE8 ;Addresses CSX,CSY to memory locn. on screen. 0335 CEE8 ;Checks that CSX & CSY are in window 0336 CEE8 ;Returns with no action and c=1 if outside. 0337 CEE8 ;If OK, initialises ZMEMT and CSPOSN 0338 CEE8 ;Exits with cursor address in (AX) 0339 CEE8 ;For cursor display, follow immediately with 0340 CEE8 ;JSR CSDSP 0341 CEE8 0342 CEE8 [ MOS125 = &FF 0355 CEE8 | 0356 CEE8 8D 19 03 SYTADD STA CSY 0357 CEEB AE 18 03 TADDR LDX CSX ;Check window of CSX 0358 CEEE EC 08 03 CPX TWLCOL ;Lower than LH margin ? 0359 CEF1 90 F3 BCC FAIL 0360 CEF3 EC 0A 03 CPX TWRCOL ;Higher than RH edge ? 0361 CEF6 90 02 BCC TADDRX 0362 CEF8 D0 EC BNE FAIL 0363 CEFA AE 19 03 TADDRX LDX CSY ;Check CSY 0364 CEFD EC 0B 03 CPX TWTROW 0365 CF00 90 E4 BCC FAIL 0366 CF02 EC 09 03 CPX TWBROW 0367 CF05 90 02 BCC TADDRY 0368 CF07 D0 DD BNE FAIL 0369 CF09 ] 0370 CF09 0371 CF09 ;End of windowing, now calc. memory posn. 0372 CF09 ;As TADDR with no bounds checking 0373 CF09 ;Returns carry clear 0374 CF09 0375 CF09 AD 19 03 TADDRY LDA CSY ;Twice row no. to Y 0376 CF0C 0A ASLA 0377 CF0D A8 TAY ;(c=0 at this point) 0378 CF0E B1 E0 LDAIY ZTBL ;MSB 0379 CF10 85 D9 STA ZMEMT+&01 0380 CF12 C8 INY 0381 CF13 A9 02 LDAIM &02 0382 CF15 2D 56 03 AND MEMODE ;Non-zero if table offset is to be halved 0383 CF18 08 PHP 0384 CF19 B1 E0 LDAIY ZTBL ;LSB 0385 CF1B 28 PLP 0386 CF1C F0 03 BEQ TADDRH 0387 CF1E 46 D9 LSR ZMEMT+&01 0388 CF20 6A RORA 0389 CF21 6D 50 03 TADDRH ADC TOPSCN ;c=0 Add LSB 0390 CF24 85 D8 STA ZMEMT 0391 CF26 A5 D9 LDA ZMEMT+&01 ;Add MSB 0392 CF28 6D 51 03 ADC TOPSCN+&01 0393 CF2B A8 TAY ;Xfr MSB to Y 0394 CF2C ;Mpy. CSX by BYTCH 0395 CF2C AD 18 03 LDA CSX 0396 CF2F AE 4F 03 LDX BYTCH ;Is it TTX ? 0397 CF32 CA DEX 0398 CF33 F0 12 BEQ TADDRE ;Skip mult. if TTX 0399 CF35 E0 0F CPXIM &0F ;4 colour (16 bytes) ? 0400 CF37 F0 03 BEQ TADDRF 0401 CF39 90 02 BCC TADDRG ;Less ? Then 2 colour 0402 CF3B 0A ASLA ;Must have been 16 colour 0403 CF3C 0A TADDRF ASLA ;4 colour 0404 CF3D 0A TADDRG ASLA ;2 colour 0405 CF3E 0A ASLA 0406 CF3F 90 02 BCC TADDRB 0407 CF41 C8 INY ;c=1?, then inc. MSB by 2 0408 CF42 C8 INY 0409 CF43 0A TADDRB ASLA 0410 CF44 90 02 BCC TADDRC 0411 CF46 C8 INY ;c=1, then inc. MSB by 1 Acorn macro assembler Page 26 VDU File - MOS05 0412 CF47 18 TADDRE CLC 0413 CF48 65 D8 TADDRC ADC ZMEMT ;(c=0), add LSB of row offset 0414 CF4A 85 D8 STA ZMEMT 0415 CF4C 8D 4A 03 STA CSPOSN 0416 CF4F AA TAX ;LSB is returned by this routine in X 0417 CF50 98 TYA ;MSB to A 0418 CF51 69 00 ADCIM &00 0419 CF53 8D 4B 03 STA CSPOSN +&01 ;Store to cursor before wraparound 0420 CF56 10 04 BPL TADDRD ;Wraparound ? 0421 CF58 38 SEC ;Yes, then subt. scn. 0422 CF59 ED 54 03 SBC BYTSCN 0423 CF5C 85 D9 TADDRD STA ZMEMT +&01 ;Store physical address to ZMEMT 0424 CF5E 18 CLC ;indicate successful addressing 0425 CF5F 60 RTS 0426 CF60 0427 CF60 ;PRINT CHARACTER TO VDU 0428 CF60 0429 CF60 0430 CF60 0431 CF60 0432 CF60 ;ANOMALOUS PRINTING 0433 CF60 0434 CF60 AE 59 03 PRANM LDX FGCOLF ;Printing to be in foreground graphics colour 0435 CF63 AC 5B 03 LDY GPLFMD ;In the current foreground colour mode 0436 CF66 20 C5 D0 PRANC JSR SETZG ;Initialise ZGORA & ZGEOR 0437 CF69 0438 CF69 ;The graphics cursor is copied to 2 locations, APCS1 0439 CF69 ;and APCS2 . The latter is left untouched until the end of the printing, 0440 CF69 ;when it is restored to the GCSIY. The former is copied to the GCSIY 0441 CF69 ;after every column of pixels is printed, with the X cursor incremented 0442 CF69 ;each time. 0443 CF69 0444 CF69 20 3C D4 JSR COPYFA ;Copy GCSIY to APCS2 ... 0445 CF6C A0 00 LDYIM &00 ;Initialise row counter 0446 CF6E 84 DC PRANMC STY ZTEMPB 0447 CF70 [ MOS125 = &FF 0449 CF70 ] 0450 CF70 B1 DE LDAIY ZTEMPC ;Anything to do ? 0451 CF72 F0 13 BEQ PRANMG ;No, then skip 0452 CF74 85 DD STA ZTEMPB +&01 0453 CF76 10 03 PRANMA BPL PRANMD 0454 CF78 20 F5 D0 JSR WPLOTA ;Yes, then plot if inside window 0455 CF7B EE 24 03 PRANMD INC GCSIX ;Increment X cursor 0456 CF7E D0 03 BNE PRANME 0457 CF80 EE 25 03 INC GCSIX +&01 0458 CF83 06 DD PRANME ASL ZTEMPB +&01 0459 CF85 D0 EF BNE PRANMA 0460 CF87 A2 28 PRANMG LDXIM APCS1-V ;Restore previous x cursor 0461 CF89 A0 24 LDYIM GCSIR-V 0462 CF8B 20 38 D4 JSR COPY2 0463 CF8E AC 26 03 LDY GCSIY ;Decrement Igraphics Y cursor 0464 CF91 D0 03 BNE PRANMF 0465 CF93 CE 27 03 DEC GCSIY +&01 0466 CF96 CE 26 03 PRANMF DEC GCSIY 0467 CF99 A4 DC LDY ZTEMPB ;Do next row 0468 CF9B C8 INY 0469 CF9C C0 08 CPYIM &08 0470 CF9E D0 CE BNE PRANMC 0471 CFA0 A2 28 LDXIM APCS1 ;Finished, so restore grpahics cursor 0472 CFA2 A0 24 LDYIM GCSIR-V 0473 CFA4 4C 40 D4 JMP COPYF ; (branch always taken) 0474 CFA7 0475 CFA7 [ MOS125 = &FF 0491 CFA7 ] 0492 CFA7 0493 CFA7 ;NON-ANOMALOUS 0494 CFA7 0495 CFA7 ;Character to be printed in (A) 0496 CFA7 0497 CFA7 ;Set up address of bytes to be 0498 CFA7 ;copied from soft font. Result 0499 CFA7 ;to ZTEMP 0500 CFA7 0501 CFA7 AE 60 03 VDUPR LDX NCOLOR ;TTX? 0502 CFAA F0 44 BEQ PTTX 0503 CFAC 20 50 D0 JSR CHADDR ;Point (ZTEMPC) to character in soft font 0504 CFAF AE 60 03 VDUPRB LDX NCOLOR ;Because CHADDR now destroys (X) 0505 CFB2 A5 D0 LDA STATS ;Is this anomalous printing ? 0506 CFB4 29 20 ANDIM &20 0507 CFB6 D0 A8 BNE PRANM ;Anom. printing 0508 CFB8 0509 CFB8 ;Now select the mode 0510 CFB8 0511 CFB8 A0 07 LDYIM &07 ;No. rows (except TTX) 0512 CFBA E0 03 CPXIM &03 0513 CFBC F0 47 BEQ PFOUR ;4 colour mode ? 0514 CFBE B0 71 BCS PSXTN ;16 colour mode ? 0515 CFC0 0516 CFC0 ;TWO colour mode 0517 CFC0 0518 CFC0 B1 DE PTWO LDAIY ZTEMPC 0519 CFC2 05 D2 ORA ZORA 0520 CFC4 45 D3 EOR ZEOR 0521 CFC6 91 D8 STAIY ZMEMT 0522 CFC8 88 DEY 0523 CFC9 10 F5 BPL PTWO 0524 CFCB 60 RTS 0525 CFCC 0526 CFCC ;TELETEXT mode 0527 CFCC 0528 CFCC [ MOS125 = &FF 0538 CFCC | 0539 CFCC A9 7F DELA LDAIM &7F ;Point to DEL, only unprintable char. in hard font =$FF...$FF 0540 CFCE 20 50 D0 JSR CHADDR 0541 CFD1 AE 5A 03 LDX BGCOLF ;Force this to be graphics background colour 0542 CFD4 A0 00 LDYIM &00 ;Mode is STORE 0543 CFD6 F0 8E BEQ PRANC 0544 CFD8 0545 CFD8 ;DEL ($7F) Delete previous char 0546 CFD8 0547 CFD8 20 C4 C5 DEL JSR BS ;Move back 1 character 0548 CFDB 20 87 C5 JSR ANOMQ 0549 CFDE D0 EC BNE DELA 0550 CFE0 AE 60 03 LDX NCOLOR 0551 CFE3 F0 08 BEQ PTTXSP ;TTX space 0552 CFE5 85 DE STA ZTEMPC ;(A)=0 from ANOMQ 0553 CFE7 A9 C0 LDAIM HFMSB +&01 ;Point to hard font version of space 0554 CFE9 85 DF STA ZTEMPC +&01 0555 CFEB D0 C2 BNE VDUPRB ;always branch 0556 CFED 0557 CFED A9 20 PTTXSP LDAIM &20 ;Print TTX space Acorn macro assembler Page 27 VDU File - MOS05 0558 CFEF 38 SEC ;write to screen 0559 CFF0 PTTX ;C=1 from NOTCEA->VDUPR 0560 CFF0 TTXFRM ;transform once for ASCII->Teletext, twice for Teletext->ASCII 0561 CFF0 49 23 EORIM &23 ;is character ASCII &23, hash? 0562 CFF2 F0 04 BEQ PTTX5F ;then replace with Teletext &5F 0563 CFF4 49 7C PTTX23 EORIM &23:EOR:&5F ;else is it ASCII &5F, underscore? 0564 CFF6 F0 04 BEQ PTTX60 ;then replace with Teletext &60 0565 CFF8 49 3F PTTX5F EORIM &5F:EOR:&60 ;else is it ASCII &60, sterling? 0566 CFFA F0 F8 BEQ PTTX23 ;then replace with Teletext &23 (won't loop!) 0567 CFFC 49 60 PTTX60 EORIM &60 ;else undo our fiddling 0568 CFFE 90 02 BCC PTTXC ;if C=0 then transform only else C=1, write to screen 0569 D000 81 D8 STAIX ZMEMT ;as (X)=0 0570 D002 PTTXC 0571 D002 60 RTS 0572 D003 ] 0573 D003 0574 D003 ;FOUR colour mode 0575 D003 0576 D003 [ MOS125 = &FF 0603 D003 | 0604 D003 A8 PFOURA TAY 0605 D004 88 DEY 0606 D005 B1 DE PFOUR LDAIY ZTEMPC ;Get bit pattern 0607 D007 48 PHA ;Push for L.S.Nybble 0608 D008 4A LSRA 0609 D009 4A LSRA 0610 D00A 4A LSRA 0611 D00B 4A LSRA 0612 D00C AA TAX 0613 D00D BD 1F C3 LDAAX BPFTB ;Get expanded patten 0614 D010 05 D2 ORA ZORA ;of M.S.Nybble 0615 D012 45 D3 EOR ZEOR 0616 D014 91 D8 STAIY ZMEMT 0617 D016 ; same size, reduce stack load 0618 D016 68 PLA ;Get L.S.Nybble 0619 D017 29 0F ANDIM &0F 0620 D019 AA TAX 0621 D01A 98 TYA 0622 D01B 49 08 EORIM &08 ;Access next char. cell 0623 D01D A8 TAY 0624 D01E BD 1F C3 LDAAX BPFTB 0625 D021 05 D2 ORA ZORA 0626 D023 45 D3 EOR ZEOR 0627 D025 91 D8 STAIY ZMEMT 0628 D027 98 TYA 0629 D028 49 08 EORIM &08 0630 D02A D0 D7 BNE PFOURA 0631 D02C ] 0632 D02C 60 PSXTC RTS ;Also used by PSXTN 0633 D02D 0634 D02D ;SIXTEEN colour mode 0635 D02D 0636 D02D [ MOS125 = &FF 0661 D02D | 0662 D02D PSXTB ;Ref.the 1st cell again 0663 D02D F0 FD BEQ PSXTC ;Finished ? 0664 D02F A8 TAY ;No, then carry on .. 0665 D030 88 DEY 0666 D031 0667 D031 B1 DE PSXTN LDAIY ZTEMPC ;Get bit pattern 0668 D033 0A PSXTA ASLA 0669 D034 2A ROLA 0670 D035 85 DC STA ZTEMPB 0671 D037 29 01 ANDIM &01 0672 D039 2A ROLA ;(A)=next 2 bits 0673 D03A AA TAX ;Get expanded bit pattern 0674 D03B BD 2F C3 LDAAX BPSTB 0675 D03E 05 D2 ORA ZORA 0676 D040 45 D3 EOR ZEOR 0677 D042 91 D8 STAIY ZMEMT 0678 D044 98 TYA ;Access next char. cell 0679 D045 E9 17 SBCIM &17 ;c=0, subtract $18 0680 D047 B0 E4 BCS PSXTB 0681 D049 29 1F ANDIM &1F ;c=0 before & after 0682 D04B A8 TAY 0683 D04C A5 DC LDA ZTEMPB 0684 D04E 90 E3 BCC PSXTA ;(branch always taken) 0685 D050 ] 0686 D050 0687 D050 ;Addresses character in soft font. 0688 D050 ;Takes (ascii) value in A, multiplies by 8, adds appropriate font address 0689 D050 ;(assumed to be on page boudary), and puts result to ZTEMPC. 0690 D050 ;This addresses top row of character, subsequent rows being in the 0691 D050 ;following 7 bytes. 0692 D050 0693 D050 [ MOS125 = &FF 0713 D050 | 0714 D050 0A CHADDR ASLA ;ZTEMPC:=8*CHAR. + MSB of font 0715 D051 2A ROLA 0716 D052 2A ROLA 0717 D053 AA TAX 0718 D054 29 F8 ANDIM &F8 0719 D056 85 DE STA ZTEMPC ;Store LSB of addr. 0720 D058 8A TXA 0721 D059 29 03 ANDIM &03 ;Get page number of character 0722 D05B 2A ROLA 0723 D05C AA TAX 0724 D05D 29 03 ANDIM &03 0725 D05F 69 BF ADCIM HFMSB ;MSB of hard font - overwrite if soft font (c=0 from last ROLA) 0726 D061 A8 TAY 0727 D062 BD 0D C4 LDAAX BITTBL ;Which bit in the flag byte is to be tested 0728 D065 2C 67 03 BIT FNTFLG ;Test to see if soft or hard font 0729 D068 F0 03 BEQ CHADDS ;Clear, thus hard font 0730 D06A BC 67 03 LDYAX PGSFNT -&01 ;Load soft font page number 0731 D06D 84 DF CHADDS STY ZTEMPC +&01 ;Store MSByte 0732 D06F 60 RTS 0733 D070 ] 0734 D070 LNK MOS06 0001 D070 0002 D070 TTL VDU File - MOS06 0003 D070 OPT MOS06 Acorn macro assembler Page 28 VDU File - MOS06 0004 D070 0005 D070 ;Last revision 15/05/82 0006 D070 0007 D070 ;15/06/82 Adjust bad plot mode indirection code 0008 D070 ;05/05/82 GADDR converted such that it takes only 1 table. 0009 D070 ; Moved to MOS11 0010 D070 ;01/05/82 Recode to allow for new order of variables 0011 D070 ;21/04/82 Conditional assembly of start/end point double plotting. 0012 D070 ;22/01/82 Provide EIGABS 0013 D070 ;07/01/82 Put X to LSB of pointer 0014 D070 0015 D070 ;******* PLOTTING ******* 0016 D070 0017 D070 ;Prologue - converts from external to internal 0018 D070 ;co-ords, and distinguishes between types of 0019 D070 ;line & triangles 0020 D070 0021 D070 A2 20 EMA LDXIM NEWPT-V ;Convert external to internal 0022 D072 [ MOS125 = &FF 0025 D072 | 0026 D072 AD 1F 03 LDA PLMODE ;Get plot mode 0027 D075 48 PHA 0028 D076 20 5D D1 JSR EIGC ;for the 4 bytes starting at Q 0029 D079 68 PLA 0030 D07A ] 0031 D07A C9 04 CMPIM &04 ;BASIC's MOVE command 0032 D07C F0 6D BEQ EMAEX 0033 D07E A0 05 LDYIM &05 ;Point to do damn' all mode (for plotting that produces no change) 0034 D080 29 03 ANDIM &03 0035 D082 F0 0E BEQ EMAA ;No change, then exit 0036 D084 4A LSRA ;Is it odd ? 0037 D085 B0 03 BCS EMAF ;No?, then invert 0038 D087 88 DEY ;(Y) = 4. Point to INVERT values of table 0039 D088 D0 08 BNE EMAA ;(Branch always taken) 0040 D08A AA EMAF TAX 0041 D08B BC 5B 03 LDYAX GPLFMD 0042 D08E BD 59 03 LDAAX FGCOLF 0043 D091 AA TAX 0044 D092 20 C5 D0 EMAA JSR SETZG 0045 D095 0046 D095 ;What's to be done ? 0047 D095 0048 D095 AD 1F 03 LDA PLMODE ;Get plot mode 0049 D098 ;* TAY 0050 D098 30 23 BMI EXGREF ;Negative, then reference external routine 0051 D09A 0A ASLA ;Get type of operation 0052 D09B 10 3B BPL EMAD ;Is it a line? 0053 D09D 29 F0 ANDIM &F0 ;Get rid of irrelevant data 0054 D09F 0A ASLA ;Is it point ($80, will be shifted out) ? 0055 D0A0 F0 46 BEQ EMAC 0056 D0A2 49 40 EORIM &40 ;Triangles? 0057 D0A4 F0 14 BEQ EMAG 0058 D0A6 48 PHA 0059 D0A7 20 EE D0 JSR EMAEY ;Copy newpoint to internal cursor 0060 D0AA 68 PLA 0061 D0AB 49 60 EORIM &60 ;SPLOT 0062 D0AD F0 11 BEQ EME ;($60=$20 EOR $40) 0063 D0AF C9 40 CMPIM &40 ;SPLOT looking for b/g ($60 = $40 EOR $60 EOR $40) 0064 D0B1 D0 0A BNE EXGREF 0065 D0B3 A9 02 LDAIM &02 ;This is what is EORed with the flag register 0066 D0B5 85 DC STA ZTEMPB 0067 D0B7 4C BB D4 JMP SCHEAT 0068 D0BA 0069 D0BA 4C 9B D5 EMAG JMP EMC ;Jump to triangles 0070 D0BD EXGREF 0071 D0BD ;* TYA ;Restore plot mode to A 0072 D0BD 4C 0E C9 JMP JMIV25 0073 D0C0 0074 D0C0 85 DC EME STA ZTEMPB ;(A)=0 .This is what is EORed with the flag register 0075 D0C2 4C 74 D4 JMP SPLOT ;Fill plot 0076 D0C5 0077 D0C5 ;Set up ZGORA & ZGEOR, using 0078 D0C5 ;(X)=Full colour byte 0079 D0C5 ;(Y)=Plot mode 0080 D0C5 0081 D0C5 8A SETZG TXA 0082 D0C6 19 1C C4 ORAAY TBZGOO 0083 D0C9 59 1D C4 EORAY TBZGEO 0084 D0CC 85 D4 STA ZGORA 0085 D0CE 8A TXA 0086 D0CF 19 1B C4 ORAAY TBZGOE 0087 D0D2 59 20 C4 EORAY TBZGEE 0088 D0D5 85 D5 STA ZGEOR 0089 D0D7 60 RTS 0090 D0D8 0091 D0D8 ;Plot a line or curve 0092 D0D8 0093 D0D8 0A EMAD ASLA ;Is it a line or curve ? 0094 D0D9 30 E2 BMI EXGREF ;Curve, so reference user routine 0095 D0DB 0A ASLA 0096 D0DC 0A ASLA ;It's a line, so is the first point to be plotted again? 0097 D0DD 10 03 BPL EMAB ;No, then skip this, as routine plots both anyway 0098 D0DF ; 0099 D0DF [ STARTP=0 0102 D0DF | 0103 D0DF ; plot end point twice 0104 D0DF 20 FD D0 JSR WPLOT 0105 D0E2 ] 0106 D0E2 ; 0107 D0E2 20 C5 D1 EMAB JSR LINE 0108 D0E5 4C EB D0 JMP EMAEX 0109 D0E8 0110 D0E8 ;Plot a point 0111 D0E8 0112 D0E8 20 FD D0 EMAC JSR WPLOT ;Plot only if it is in window 0113 D0EB ;SPLOTY requires that EMAEX preserves carry 0114 D0EB 20 D0 CD EMAEX JSR SWAPB ;Swap current cursor with last cursor 0115 D0EE A0 24 EMAEY LDYIM GCSIR-V ;Copy new point to Icursor 0116 D0F0 A2 20 EMAEZ LDXIM NEWPT-V 0117 D0F2 4C 40 D4 JMP COPYF 0118 D0F5 0119 D0F5 ;WPLOT windows point at NEWPT and plots it if inside 0120 D0F5 0121 D0F5 A2 24 WPLOTA LDXIM GCSIR-V ;WPLOTA does this to current graphics cursor 0122 D0F7 20 EF D7 JSR GADDV ;WPLOTB does this for any point pointed to by X 0123 D0FA F0 06 BEQ PLOT 0124 D0FC 60 RTS 0125 D0FD 20 ED D7 WPLOT JSR GADDW ;Window & address NEWPT 0126 D100 D0 13 BNE PLOTEX ;Out of window, then exit 0127 D102 0128 D102 ;otherwise fall through to ..... Acorn macro assembler Page 29 VDU File - MOS06 0129 D102 0130 D102 ;PLOT plots a point 0131 D102 ;Requires LINEY, ZMEMG, ZGORA, ZGEOR 0132 D102 ;Uses ZTEMP as work byte 0133 D102 ;Alters 1 byte on screen 0134 D102 0135 D102 AC 1A 03 PLOT LDY YLINE 0136 D105 A5 D1 PLOTS LDA ZMASK 0137 D107 25 D4 AND ZGORA 0138 D109 11 D6 ORAIY ZMEMG 0139 D10B 85 DA STA ZTEMP 0140 D10D A5 D5 LDA ZGEOR 0141 D10F 25 D1 AND ZMASK 0142 D111 45 DA EOR ZTEMP 0143 D113 91 D6 STAIY ZMEMG 0144 D115 60 PLOTEX RTS 0145 D116 0146 D116 B1 D6 PLOTFF LDAIY ZMEMG ;Plots a full byte 0147 D118 05 D4 ORA ZGORA 0148 D11A 45 D5 EOR ZGEOR 0149 D11C [ MOS125 = &7F 0150 D11C WRSC 0151 D11C ] 0152 D11C 91 D6 STAIY ZMEMG 0153 D11E 60 RTS 0154 D11F 0155 D11F ;WIND windows the point at V+(X), as follows 0156 D11F ;If the point is below the lower limit, the window is 1 0157 D11F ;If the point is above the upper limit, the window is 2 0158 D11F ;If the point is within both limits, the window is 0 0159 D11F ;The total window, returned in A (with z set appropriately) 0160 D11F ;is 4 times the window in the Y direction, plus the window 0161 D11F ;in the X direction. 0162 D11F ;The routine uses ZTEMP as a work byte 0163 D11F ;All windows, as specified by GWxxxx are reckoned as inclusive, 0164 D11F ;with the high byte last. 0165 D11F ;The order of the windows in RAM is reckoned as follows 0166 D11F ;GWLCOL, GWBROW, GWRCOL, GWTROW 0167 D11F 0168 D11F A2 24 WINDCS LDXIM GCSIR-V ;Special entry point to window graphics cursor 0169 D121 0170 D121 A0 00 WIND LDYIM &00 ;Initialise result 0171 D123 84 DA STY ZTEMP 0172 D125 A0 02 LDYIM &02 ;Do the Y co-ords 0173 D127 20 3A D1 JSR WINDA 0174 D12A 06 DA ASL ZTEMP ;Mult. the Y window by 4 0175 D12C 06 DA ASL ZTEMP 0176 D12E CA DEX 0177 D12F CA DEX 0178 D130 A0 00 LDYIM &00 ;Do the X window 0179 D132 20 3A D1 JSR WINDA 0180 D135 E8 INX ;Restore X 0181 D136 E8 INX 0182 D137 A5 DA LDA ZTEMP 0183 D139 60 RTS 0184 D13A 0185 D13A ;Subtract margin from point to obtain sign of difference 0186 D13A 0187 D13A BD 02 03 WINDA LDAAX V+&02 ;(LSB) 0188 D13D D9 00 03 CMPAY GWLCOL ;(LSB of lower limit) 0189 D140 BD 03 03 LDAAX V+&03 ;(MSB) 0190 D143 F9 01 03 SBCAY GWLCOL+&01 ;(MSB of lower limit) 0191 D146 30 10 BMI WINDAA 0192 D148 B9 04 03 LDAAY GWRCOL ;(LSB of upper limit) 0193 D14B DD 02 03 CMPAX V+&02 ;(LSB) 0194 D14E B9 05 03 LDAAY GWRCOL+&01 ;(MSB of upper limit) 0195 D151 FD 03 03 SBCAX V+&03 ;(MSB) 0196 D154 10 04 BPL WINDAB ;Is this <= upper limit ? 0197 D156 E6 DA INC ZTEMP 0198 D158 E6 DA WINDAA INC ZTEMP 0199 D15A 60 WINDAB RTS ;No longer referenced from EIG, incidentally, saving TWO WHOLE BYTES !! 0200 D15B 0201 D15B ;EIGABS in some embarassment is to provide EIG in ABSOLUTE co-ords 0202 D15B 0203 D15B A9 FF EIGABS LDAIM &FF 0204 D15D [ MOS125 = &FF 0206 D15D ] 0207 D15D 0208 D15D ;Convert external to internal co-ordinates 0209 D15D 0210 D15D ;EIG converts from external co-ords (either relative or abs) 0211 D15D ;and produces internal ones in situ. No windowing is done. 0212 D15D ;Requires (X) = the offset from V of the points to be converted 0213 D15D ;b2 of PLMODE = 0 for relative co-ords (add the Ecursor) 0214 D15D ; 1 for absolute co-ords (add the origin) 0215 D15D ;GCSR, ORGX, ORGY as usual 0216 D15D ;Writes the transformed co-ordinates from whence they came 0217 D15D ;Also writes new point to external cursor (GCSX,GCSY) 0218 D15D ;hence in triangle relative mode, the points are relative 0219 D15D ;to the last specified, not the original cursor 0220 D15D 0221 D15D ;a) Add the cursor to current posn. if relative 0222 D15D ;& add origin in both cases 0223 D15D 0224 D15D [ MOS125 = &FF 0226 D15D ] 0227 D15D 85 DA EIGC STA ZTEMP 0228 D15F A0 02 LDYIM &02 ;Do this for Y co-ordinates 0229 D161 20 83 D1 JSR EIGS 0230 D164 20 BA D1 JSR DIVAXT ;1024 points vertically 0231 D167 A0 00 LDYIM &00 0232 D169 CA DEX 0233 D16A CA DEX 0234 D16B 20 83 D1 JSR EIGS ;Do this for X co-ordinates 0235 D16E 0236 D16E ;b) scale down by the necessary factor 0237 D16E ;(EIGS has already divided by 2) 0238 D16E 0239 D16E AC 61 03 LDY NPIX ;How many pixles ? 0240 D171 C0 03 CPYIM &03 0241 D173 F0 05 BEQ EIGA ;4?, then divide by 4 0242 D175 B0 06 BCS EIGB ;8?, then divide by 2 0243 D177 20 BA D1 JSR DIVAXT ;2?, then divide by 8 0244 D17A 20 BA D1 EIGA JSR DIVAXT 0245 D17D AD 56 03 EIGB LDA MEMODE ;Is it a 10K mode? 0246 D180 D0 38 BNE DIVAXT ;YES, then another divide by 2 0247 D182 60 RTS ; NO, then skip 0248 D183 0249 D183 18 EIGS CLC 0250 D184 A5 DA LDA ZTEMP ;Test b2 of plot mode, for rel./abs. 0251 D186 29 04 ANDIM &04 Acorn macro assembler Page 30 VDU File - MOS06 0252 D188 F0 09 BEQ EIGSA ;Clear, so relative ( & skip ) 0253 D18A BD 02 03 LDAAX V+&02 ;(LSB) ~~~ ABSOLUTE ~~~ 0254 D18D 48 PHA 0255 D18E BD 03 03 LDAAX V+&03 ;(MSB) 0256 D191 90 0E BCC EIGSB ;(branch always taken) 0257 D193 BD 02 03 EIGSA LDAAX V+&02 ;~~~ RELATIVE ~~~ 0258 D196 79 10 03 ADCAY GCSR ;so add prev. cursor (LSB) 0259 D199 48 PHA 0260 D19A BD 03 03 LDAAX V+&03 ;(MSB) 0261 D19D 79 11 03 ADCAY GCSR+&01 0262 D1A0 18 CLC 0263 D1A1 99 11 03 EIGSB STAAY GCSR+&01 ;Update MSB of cursor 0264 D1A4 79 0D 03 ADCAY ORG+&01 ;Now add origin for both addressing modes ! 0265 D1A7 9D 03 03 STAAX V+&03 ;(MSB) 0266 D1AA 68 PLA ;Pull LSByte 0267 D1AB 99 10 03 STAAY GCSR ;Update LSB of cursor 0268 D1AE 18 CLC 0269 D1AF 79 0C 03 ADCAY ORG ;(LSB) 0270 D1B2 9D 02 03 STAAX V+&02 0271 D1B5 90 03 BCC DIVAXT 0272 D1B7 FE 03 03 INCAX V+&03 ;Carry into MSB if needs be 0273 D1BA 0274 D1BA ;Divide this by 2 by falling through to ... 0275 D1BA 0276 D1BA BD 03 03 DIVAXT LDAAX V+&03 ;Signed division by 2 0277 D1BD 0A ASLA ;(Screen now 1280 by 1024) 0278 D1BE 7E 03 03 RORAX V+&03 0279 D1C1 7E 02 03 RORAX V+&02 0280 D1C4 [ MOS125 = &FF 0281 D1C4 | 0282 D1C4 LINEX1 0283 D1C4 ] 0284 D1C4 60 RTS 0285 D1C5 0286 D1C5 [ MOS125 = &FF 0315 D1C5 ] 0316 D1C5 0317 D1C5 LNK MOS07 0001 D1C5 TTL VDU File - MOS07 0002 D1C5 OPT MOS07 Acorn macro assembler Page 31 VDU File - MOS07 0003 D1C5 0004 D1C5 ;Last revision 01/05/82 0005 D1C5 0006 D1C5 ;01/05/82 Recoded to allow for new order of variables & manifests 0007 D1C5 ;21/04/82 LINE rewritten 0008 D1C5 ;19/04/82 One byte saved in SB 0009 D1C5 ;25/03/82 Change all refs. to BEGSCN+1 to BEGSCN 0010 D1C5 ;14/11/81 Variable mark space on DOTS removed 0011 D1C5 0012 D1C5 ;******* PLOTTING ******* 0013 D1C5 0014 D1C5 ;LINE plots straight line from cursor to new point 0015 D1C5 ;taking account windowing, & plotting partial lines 0016 D1C5 ;if necessary 0017 D1C5 0018 D1C5 ;Requires GCSIR = the current cursor position (I co-ords) 0019 D1C5 ;NEWPT = the point to plotted to (I co-ords) 0020 D1C5 ;Windowing is assumed of neither 0021 D1C5 0022 D1C5 0023 D1C5 ;Plot a straight line 0024 D1C5 0025 D1C5 20 C3 D3 LINE JSR LINSA ;Find DeltaX & DeltaY to LDELTA 0026 D1C8 ;LINSB Returns n=1 iff MOD DeltaX < MOD DeltaY 0027 D1C8 ;Encoded version of a previous routine 0028 D1C8 0029 D1C8 AD 2B 03 LDA LDELTA+&03 ;DY, MSB Are the deltas of the same sign? 0030 D1CB [ MOS125 = &FF 0043 D1CB | 0044 D1CB AA TAX 0045 D1CC 4D 29 03 EOR LDELTA+&01 ;DX, MSB 0046 D1CF 0A ASLA 0047 D1D0 AD 2A 03 LDA LDELTA+&02 0048 D1D3 B0 0A BCS LINSBA 0049 D1D5 CD 28 03 CMP LDELTA ;YES, then compare DeltaY - DeltaX 0050 D1D8 8A TXA 0051 D1D9 ED 29 03 SBC LDELTA+&01 0052 D1DC 4C E7 D1 JMP LINSBB 0053 D1DF 18 LINSBA CLC ;NO, then add 0054 D1E0 6D 28 03 ADC LDELTA 0055 D1E3 8A TXA 0056 D1E4 6D 29 03 ADC LDELTA+&01 0057 D1E7 ] 0058 D1E7 6A LINSBB RORA ;c to b7 of A 0059 D1E8 A2 00 LDXIM &00 0060 D1EA 4D 2B 03 EOR LDELTA+&03 ;If DY < 0, then invert b7 of A. Sets n as required 0061 D1ED ; 0062 D1ED 10 02 BPL LINEA 0063 D1EF A2 02 LDXIM &02 0064 D1F1 86 DE LINEA STX ZTEMPC ;0 if p.b.X, 2 if p.b.Y 0065 D1F3 BD AA C4 LDAAX D1JTB ;JVEC initialisation (D1 jump vector) 0066 D1F6 8D 5D 03 STA JVEC 0067 D1F9 BD AB C4 LDAAX D1JTB+&01 0068 D1FC 8D 5E 03 STA JVEC+&01 0069 D1FF [ MOS125 = &FF 0076 D1FF | 0077 D1FF A9 24 LDAIM GCSIR-V ;+ve, then LSTART from GCSIR... 0078 D201 BC 29 03 LDYAX LDELTA+&01 ;Sign of D1 0079 D204 30 02 BMI LINEC 0080 D206 A9 20 LDAIM NEWPT-V ;Copy LSTART from new point 0081 D208 85 DF LINEC STA ZTEMPC+&01 ;Offset of LSTART (=PStart of old) 0082 D20A AA TAX 0083 D20B ] 0084 D20B A0 2C LDYIM LSTART-V ;Copy to LSTART 0085 D20D 20 40 D4 JSR COPYF 0086 D210 A5 DF LDA ZTEMPC+&01 ;Get Horizontal co-ordinate of other (end) point 0087 D212 49 04 EORIM &04 ;This requires NEWPT to be multiple of 8 & GCSIR 4 above it 0088 D214 85 DD STA ZTEMPB+&01 0089 D216 05 DE ORA ZTEMPC ;Get Hend (horizontal co-ordinate of endpoint) 0090 D218 AA TAX 0091 D219 20 36 D4 JSR COPY2H 0092 D21C [ MOS125 = &FF 0107 D21C | 0108 D21C A2 2C LDXIM LSTART-V ;Window start point LSTART 0109 D21E 20 21 D1 JSR WIND 0110 D221 85 DC STA ZTEMPB 0111 D223 C9 01 CMPIM &01 ;C=1 iff start point not inside 0112 D225 AD 1F 03 LDA PLMODE ;Initialise dotted line test 0113 D228 29 10 ANDIM &10 ;Isolate b4 0114 D22A F0 02 BEQ LINED 0115 D22C A9 80 LDAIM &80 ;now $80 if plot dotted line, $00 if full line 0116 D22E 90 02 LINED BCC LINEL 0117 D230 09 40 ORAIM &40 ;Start point not inside, so slow plot 0118 D232 85 DB LINEL STA ZTEMP+&01 0119 D234 A6 DD LDX ZTEMPB+&01 ;Window other point 0120 D236 ] 0121 D236 20 21 D1 JSR WIND 0122 D239 24 DC BIT ZTEMPB ;Anything to do ? 0123 D23B [ MOS125 = &FF 0126 D23B | 0127 D23B D0 87 BNE LINEX1 ;No, then exit 0128 D23D ] 0129 D23D A6 DE LINEE LDX ZTEMPC ;Isolate 2nd horizontal window 0130 D23F F0 02 BEQ LINEF 0131 D241 4A LSRA 0132 D242 4A LSRA 0133 D243 29 02 LINEF ANDIM &02 0134 D245 F0 07 BEQ LINEG ;Zero, so Hend is in window 0135 D247 8A TXA ;Point X to upper margin! 0136 D248 09 04 ORAIM GWRCOL-V ;Assumes GWLCOL-V is a multiple of 4 0137 D24A AA TAX ;Endpoint outside horizontal window, 0138 D24B 20 36 D4 JSR COPY2H ;so alter Hend to high margin 0139 D24E 20 E2 D3 LINEG JSR LINSG ;Get L values & MOD deltas 0140 D251 A5 DE LDA ZTEMPC 0141 D253 49 02 EORIM &02 0142 D255 AA TAX ;Unsigned D2 0143 D256 A8 TAY 0144 D257 AD 29 03 LDA LDELTA+&01 ;Sign of D2 ? 0145 D25A 4D 2B 03 EOR LDELTA+&03 0146 D25D 10 01 BPL LINEH 0147 D25F E8 INX ;Signed D2 - E,W,N,S 0148 D260 BD AE C4 LINEH LDAAX D2JTBL ;Initialise D2 jump vector 0149 D263 8D 32 03 STA D2JVEC 0150 D266 BD B2 C4 LDAAX D2JTBH 0151 D269 8D 33 03 STA D2JVEC+&01 0152 D26C A9 7F LDAIM &7F ;dotted line initialisation 0153 D26E 8D 34 03 STA DOTFLG 0154 D271 24 DB BIT ZTEMP+&01 0155 D273 70 29 BVS LINEI ;Slow plot , so set ZTEMPC strangely 0156 D275 BD 47 C4 LDAAX EWTBA ;(4,0,6,2) Calculate V points 0157 D278 AA TAX Acorn macro assembler Page 32 VDU File - MOS07 0158 D279 38 SEC 0159 D27A BD 00 03 LDAAX GWLCOL 0160 D27D F9 2C 03 SBCAY LSTART 0161 D280 85 DA STA ZTEMP 0162 D282 BD 01 03 LDAAX GWLCOL+&01 0163 D285 F9 2D 03 SBCAY LSTART+&01 0164 D288 A4 DA LDY ZTEMP 0165 D28A AA TAX ;Ensure +ve 0166 D28B 10 04 BPL LINEH1 0167 D28D 20 51 D4 JSR NEGAY 0168 D290 [ MOS125 = &FF 0170 D290 | 0171 D290 AA TAX ;MSB of no. V points 0172 D291 LINEH1 0173 D291 ] 0174 D291 C8 INY ;Increment this no. 0175 D292 D0 01 BNE LINEH2 0176 D294 E8 INX 0177 D295 8A LINEH2 TXA ;MSB non-zero ? 0178 D296 F0 02 BEQ LINEH3 0179 D298 A0 00 LDYIM &00 ;Yes, then no limit to no. of vertical points 0180 D29A 84 DF LINEH3 STY ZTEMPC+&01 ; Zero is always set here 0181 D29C F0 09 BEQ LINEJ1 0182 D29E 8A LINEI TXA ;b7 = sign of D2. b1=D2 0183 D29F 4A LSRA 0184 D2A0 6A RORA 0185 D2A1 09 02 ORAIM &02 0186 D2A3 45 DE EOR ZTEMPC 0187 D2A5 85 DE STA ZTEMPC 0188 D2A7 A2 2C LINEJ1 LDXIM LSTART-V ;Address the first point 0189 D2A9 20 F4 D7 JSR GADDR ;Now loads YLINE to Y 0190 D2AC A6 DC LDX ZTEMPB 0191 D2AE D0 02 BNE LINEN 0192 D2B0 C6 DD DEC ZTEMPB+&01 0193 D2B2 CA LINEN DEX 0194 D2B3 ; 0195 D2B3 ; Fall through to main plot routine 0196 D2B3 ; 0197 D2B3 A5 DB LINEJ LDA ZTEMP +&01 ;Was midpoint or DOTS referenced ? 0198 D2B5 F0 1F BEQ DOTYES ;No?, then run along 0199 D2B7 10 10 BPL MPTEST ;No, then do midpoint test 0200 D2B9 2C 34 03 BIT DOTFLG ;b7 set, then dotted 0201 D2BC 10 05 BPL DOTY ;Branch if last was a space 0202 D2BE CE 34 03 DEC DOTFLG ;now to $7F 0203 D2C1 D0 23 BNE DOTNO ;(branch always taken) 0204 D2C3 EE 34 03 DOTY INC DOTFLG ;to $80 0205 D2C6 0A ASLA 0206 D2C7 10 0D BPL DOTYES ;No?, then plot the point 0207 D2C9 86 DC MPTEST STX ZTEMPB ;Store X temporarily 0208 D2CB A2 2C LDXIM LSTART-V ;Window the point at Q +0D (PStart) 0209 D2CD 20 EF D7 JSR GADDV ;& address if window was successful 0210 D2D0 A6 DC LDX ZTEMPB ;Restore X 0211 D2D2 09 00 ORAIM &00 ;To TSTA (a la 6800) (result of window) 0212 D2D4 D0 10 BNE DOTNO ;Outside?, then skip the plot 0213 D2D6 A5 D1 DOTYES LDA ZMASK ;Plot the point 0214 D2D8 25 D4 AND ZGORA 0215 D2DA 11 D6 ORAIY ZMEMG 0216 D2DC 85 DA STA ZTEMP 0217 D2DE A5 D5 LDA ZGEOR 0218 D2E0 25 D1 AND ZMASK 0219 D2E2 45 DA EOR ZTEMP 0220 D2E4 91 D6 STAIY ZMEMG 0221 D2E6 0222 D2E6 ;L := L - DeltaV 0223 D2E6 0224 D2E6 38 DOTNO SEC 0225 D2E7 AD 35 03 LDA LPARMS ;L,LSB 0226 D2EA ED 37 03 SBC LPARMS+&02 ;DeltaV,LSB 0227 D2ED 8D 35 03 STA LPARMS 0228 D2F0 AD 36 03 LDA LPARMS+&01 ;L,MSB 0229 D2F3 ED 38 03 SBC LPARMS+&03 ;DeltaV,MSB 0230 D2F6 B0 11 BCS LINED1 ;Skip if D2 not to be taken ( L > 0 ) 0231 D2F8 85 DA STA ZTEMP ;D2 must be taken, thus 0232 D2FA AD 35 03 LDA LPARMS ;L := L + DeltaH 0233 D2FD 6D 39 03 ADC LPARMS+&04 ;LSB of DeltaH (c=0) 0234 D300 8D 35 03 STA LPARMS 0235 D303 A5 DA LDA ZTEMP 0236 D305 6D 3A 03 ADC LPARMS+&05 ;MSB of DeltaH 0237 D308 18 CLC ;Do do D2 0238 D309 8D 36 03 LINED1 STA LPARMS+&01 ;Store MSB of L, preserving c 0239 D30C 08 PHP ;Needed for decrementing no. of V points 0240 D30D B0 09 BCS LINEE1 ;Don't do D2 if you're not meant to 0241 D30F 6C 32 03 JMI D2JVEC ;Jump to D2, through JVEC2, to xB (below) 0242 D312 88 NB DEY 0243 D313 10 03 BPL LINEE1 ;~~~~~~~~~~~~~~ D2 KING MOVES ~~~~~~~~~~~~~~ 0244 D315 20 ED CB JSR NBDY 0245 D318 6C 5D 03 LINEE1 JMI JVEC 0246 D31B C8 SB INY 0247 D31C C0 08 CPYIM &08 0248 D31E D0 F8 BNE LINEE1 0249 D320 18 CLC ; encoded version of SBDY 0250 D321 A5 D6 LDA ZMEMG 0251 D323 6D 52 03 ADC BYTROW 0252 D326 85 D6 STA ZMEMG 0253 D328 A5 D7 LDA ZMEMG +&01 0254 D32A 6D 53 03 ADC BYTROW +&01 0255 D32D 10 04 BPL SBDYA 0256 D32F 38 SEC 0257 D330 ED 54 03 SBC BYTSCN 0258 D333 85 D7 SBDYA STA ZMEMG +&01 0259 D335 A0 00 LDYIM &00 0260 D337 6C 5D 03 JMI JVEC 0261 D33A 46 D1 EB LSR ZMASK 0262 D33C 90 DA BCC LINEE1 0263 D33E 20 A3 D3 JSR EBDY 0264 D341 6C 5D 03 JMI JVEC 0265 D344 06 D1 WB ASL ZMASK 0266 D346 90 D0 BCC LINEE1 0267 D348 20 B3 D3 JSR WBDY 0268 D34B 6C 5D 03 JMI JVEC 0269 D34E 88 NA DEY 0270 D34F 10 0C BPL LINEF1 ;~~~~~~~~~~~~~~ D1 KING MOVES ~~~~~~~~~~~~~~ 0271 D351 20 ED CB JSR NBDY 0272 D354 D0 07 BNE LINEF1 ; NBDY returns Zero false 0273 D356 46 D1 EA LSR ZMASK 0274 D358 90 03 BCC LINEF1 0275 D35A 20 A3 D3 JSR EBDY 0276 D35D 28 LINEF1 PLP ;Did D2 occur ? Result to c (c=0 if it did) 0277 D35E E8 INX ;Inc no. H points left to plot (following preserves c) 0278 D35F D0 04 BNE LINEG1 0279 D361 E6 DD INC ZTEMPB +&01 Acorn macro assembler Page 33 VDU File - MOS07 0280 D363 F0 0A BEQ LINEX ;Zero?, then exit 0281 D365 24 DB LINEG1 BIT ZTEMP +&01 ;Was midpoint referenced? (preserves c) 0282 D367 70 07 BVS FRIGA ;Yes, then go to the nasty bit 0283 D369 B0 35 BCS LINEK ;D2 ?, then test V window. c from last PLP 0284 D36B C6 DF DEC ZTEMPC +&01 ;Off V window ?, then exit 0285 D36D D0 31 BNE LINEK 0286 D36F 60 LINEX RTS 0287 D370 A5 DE FRIGA LDA ZTEMPC ;Which direction was D2 ? 0288 D372 86 DC STX ZTEMPB 0289 D374 29 02 ANDIM &02 0290 D376 AA TAX 0291 D377 B0 19 BCS FRIGC ;No D2?, then skip the adjustment of V 0292 D379 24 DE BIT ZTEMPC ;Was D2 +ve ? 0293 D37B 30 0A BMI FRIGB 0294 D37D FE 2C 03 INCAX LSTART ;D2 +ve, so increment V co-ord 0295 D380 D0 10 BNE FRIGC 0296 D382 FE 2D 03 INCAX LSTART+&01 0297 D385 90 0B BCC FRIGC ;(branch always taken) 0298 D387 BD 2C 03 FRIGB LDAAX LSTART ;D2 -ve, so dec. the V co-ord. 0299 D38A D0 03 BNE FRIGF 0300 D38C DE 2D 03 DECAX LSTART+&01 0301 D38F DE 2C 03 FRIGF DECAX LSTART 0302 D392 8A FRIGC TXA ;Get offset of D1 0303 D393 49 02 EORIM &02 0304 D395 AA TAX 0305 D396 FE 2C 03 INCAX LSTART ;D1 +ve,so inc. H co-ord 0306 D399 D0 03 BNE FRIGD 0307 D39B FE 2D 03 INCAX LSTART+&01 0308 D39E A6 DC FRIGD LDX ZTEMPB 0309 D3A0 4C B3 D2 LINEK JMP LINEJ 0310 D3A3 0311 D3A3 ;BOUNDARY ROUTINES 0312 D3A3 0313 D3A3 [ MOS125 = &FF 0329 D3A3 ] 0330 D3A3 0331 D3A3 ;EAST 0332 D3A3 0333 D3A3 AD 62 03 EBDY LDA MASKL 0334 D3A6 85 D1 STA ZMASK 0335 D3A8 A5 D6 LDA ZMEMG 0336 D3AA 69 07 ADCIM &07 ;c=1 from branch not taken to call this 0337 D3AC 85 D6 STA ZMEMG 0338 D3AE 90 02 BCC EBDYA 0339 D3B0 E6 D7 INC ZMEMG +&01 0340 D3B2 60 EBDYA RTS 0341 D3B3 0342 D3B3 ;WEST 0343 D3B3 0344 D3B3 AD 63 03 WBDY LDA MASKR ;encoded version of WBDY 0345 D3B6 85 D1 STA ZMASK 0346 D3B8 A5 D6 LDA ZMEMG 0347 D3BA D0 02 BNE WBDYA 0348 D3BC C6 D7 DEC ZMEMG +&01 0349 D3BE E9 08 WBDYA SBCIM &08 ;c=1 from failure of BCC 0350 D3C0 85 D6 STA ZMEMG 0351 D3C2 60 RTS 0352 D3C3 0353 D3C3 LNK MOS08 0001 D3C3 0002 D3C3 TTL VDU File - MOS08 0003 D3C3 OPT MOS08 Acorn macro assembler Page 34 VDU File - MOS08 0004 D3C3 0005 D3C3 ;Last revision 18/05/82 0006 D3C3 ; 0007 D3C3 ;18/05/82 External graphics cursor now updated on exit of SPLOT 0008 D3C3 ;04/05/82 SPLOT routine entered 0009 D3C3 ;01/05/82 Recoded using new variable order & manifests 0010 D3C3 ;21/04/82 Most of this deleted ! LINSG modified for new LINE routine 0011 D3C3 ;19/04/82 Byte saving in LINSCE 0012 D3C3 0013 D3C3 ;LINSA calculates Delta X & Delta Y 0014 D3C3 ;(New point - cursor), where both are in Ico-ords 0015 D3C3 ;Max. I value always assumed to be $8000, as arithmetic 0016 D3C3 ;is performed in 2's comp., 16 bit 0017 D3C3 ;New point in NEWPT, results to LDELTA 0018 D3C3 0019 D3C3 A0 28 LINSA LDYIM LDELTA-V ;Offset of results from V 0020 D3C5 A2 20 LDXIM NEWPT-V ;Offset of operands, from V 0021 D3C7 0022 D3C7 ;fall through to ....... 0023 D3C7 0024 D3C7 ;TRISA calculates Delta X & Delta Y for operands starting 0025 D3C7 ;at V+(X), and results to V+(Y). Calculation from 0026 D3C7 ;(Point at (V+(X)+4)) - (Point at (V+(X))) 0027 D3C7 0028 D3C7 20 CE D3 TRISA JSR TRISAA 0029 D3CA E8 INX 0030 D3CB E8 INX 0031 D3CC C8 INY 0032 D3CD C8 INY 0033 D3CE 38 TRISAA SEC 0034 D3CF BD 04 03 LDAAX V+&04 0035 D3D2 FD 00 03 SBCAX V 0036 D3D5 99 00 03 STAAY V 0037 D3D8 BD 05 03 LDAAX V+&05 0038 D3DB FD 01 03 SBCAX V+&01 0039 D3DE 99 01 03 STAAY V+&01 0040 D3E1 60 RTS 0041 D3E2 0042 D3E2 ;LINSG calculates no. H points before H exit 0043 D3E2 ;putting 2's comp. to ZTEMPB,ZTEMPB +01 (LSB 1st). 0044 D3E2 ;Initialises MOD DELTAs & L 0045 D3E2 ;Requires ZTEMPB as usual, destroying original data 0046 D3E2 0047 D3E2 A5 DE LINSG LDA ZTEMPC ;Calc. MOD DELTAs. 0048 D3E4 D0 07 BNE LINSGB ;Plot by Y, so straight copy 0049 D3E6 A2 28 LDXIM LDELTA-V ;Swap DeltaX & DeltaY 0050 D3E8 A0 2A LDYIM LDELTA+&02-V 0051 D3EA 20 CC CD JSR SWAP2 0052 D3ED A2 28 LINSGB LDXIM LDELTA-V ;Copy from modified DX & DY (now DH & DV) 0053 D3EF A0 37 LDYIM LPARMS+&02-V ;to LPARMS+2=LDELTA 0054 D3F1 20 40 D4 JSR COPYF ;Copy 4 bytes 0055 D3F4 0056 D3F4 ;Initialise No. H points 0057 D3F4 0058 D3F4 38 SEC 0059 D3F5 A6 DE LDX ZTEMPC 0060 D3F7 AD 30 03 LDA HEND ;He, LSB 0061 D3FA FD 2C 03 SBCAX LSTART ;HSt, LSB 0062 D3FD A8 TAY 0063 D3FE AD 31 03 LDA HEND+&01 ;He, MSB 0064 D401 FD 2D 03 SBCAX LSTART+&01 ;HSt, MSB 0065 D404 30 03 BMI LINSGA ;Ensure in 2's comp. 0066 D406 20 51 D4 JSR NEGAY 0067 D409 85 DD LINSGA STA ZTEMPB +&01 0068 D40B 84 DC STY ZTEMPB 0069 D40D 0070 D40D ;now initialise L & MODULO the DH & DV 0071 D40D 0072 D40D A2 35 LDXIM LPARMS-V ;Point to the deltas 0073 D40F 0074 D40F ;& fall through to ... 0075 D40F 0076 D40F ;TRISB Set up L & MODULO deltas. 0077 D40F ;Assumes V+(X) points to LL,LH,DVL,DVH,DHL,DHH 0078 D40F ;Sets all Dxy to ABS in situ. Sets L := DH/2 (2 byte arith) 0079 D40F 0080 D40F 20 1D D4 TRISB JSR TRISBA ;Do DH 0081 D412 4A LSRA 0082 D413 9D 01 03 STAAX V+&01 ;Initialise LH 0083 D416 98 TYA ;Now do LL 0084 D417 6A RORA 0085 D418 9D 00 03 STAAX V 0086 D41B CA DEX ;Now DV 0087 D41C CA DEX 0088 D41D BC 04 03 TRISBA LDYAX V+&04 ;LSB 0089 D420 BD 05 03 LDAAX V+&05 ;MSB 0090 D423 10 0C BPL TRISBB ;Find ABS value 0091 D425 20 51 D4 JSR NEGAY 0092 D428 9D 05 03 STAAX V+&05 ;PAIN - why the hell isn't there a STYAX on this wretched chip ?? 0093 D42B 48 PHA 0094 D42C 98 TYA 0095 D42D 9D 04 03 STAAX V+&04 0096 D430 68 PLA 0097 D431 60 TRISBB RTS 0098 D432 0099 D432 0100 D432 ;COPYF copies 4 bytes from (V)+(X) to (V)+(Y) 0101 D432 0102 D432 A9 08 COPY8 LDAIM &08 0103 D434 D0 0C BNE COPY 0104 D436 0105 D436 A0 30 COPY2H LDYIM HEND-V 0106 D438 A9 02 COPY2 LDAIM &02 0107 D43A D0 06 BNE COPY 0108 D43C 0109 D43C A0 28 COPYFA LDYIM APCS1-V 0110 D43E A2 24 COPYFB LDXIM GCSIR-V 0111 D440 A9 04 COPYF LDAIM &04 ;SPLOTY requires that c preserved 0112 D442 85 DA COPY STA ZTEMP 0113 D444 BD 00 03 COPYA LDAAX V 0114 D447 99 00 03 STAAY V 0115 D44A E8 INX 0116 D44B C8 INY 0117 D44C C6 DA DEC ZTEMP 0118 D44E D0 F4 BNE COPYA 0119 D450 60 RTS 0120 D451 0121 D451 48 NEGAY PHA ;Negate (AY) - push MSB 0122 D452 98 TYA 0123 D453 49 FF EORIM &FF 0124 D455 A8 TAY Acorn macro assembler Page 35 VDU File - MOS08 0125 D456 68 PLA 0126 D457 49 FF EORIM &FF 0127 D459 [ MOS125 = &FF 0133 D459 | 0134 D459 C0 FF CPYIM &FF 0135 D45B C8 INY 0136 D45C 69 00 ADCIM &00 0137 D45E 60 RTS 0138 D45F ] 0139 D45F 0140 D45F 20 ED D7 SPF JSR GADDW ;Address new point COMMON CODE 0141 D462 D0 08 BNE SPFA ;Off window?, then exit 0142 D464 B1 D6 LDAIY ZMEMG ;Get the current byte 0143 D466 4D 5A 03 EOR BGCOLF ;Set b/g pixels to zero 0144 D469 85 DA STA ZTEMP 0145 D46B 60 RTS 0146 D46C 68 SPFA PLA 0147 D46D 68 PLA 0148 D46E 0149 D46E ; & fall through to 0150 D46E 0151 D46E EE 26 03 SPLOTY INC GCSIY ;Failed, so make the L.H. cursor > R.H. 0152 D471 4C FA D4 JMP SPLOTX 0153 D474 0154 D474 ;SPLOT plots from the new point left & right 0155 D474 ; until it finds a pixel which is NOT background colour 0156 D474 ; It scans a byte at a time if possible, taking a lot 0157 D474 ; of code. 0158 D474 0159 D474 0160 D474 20 5F D4 SPLOT JSR SPF 0161 D477 25 D1 AND ZMASK ;Is the new point in b/g? 0162 D479 D0 F3 BNE SPLOTY ;No?, then exit 0163 D47B A2 00 LDXIM &00 ;Set up for plotting to the left 0164 D47D 20 43 D5 JSR SPS ;Corrupts all registers 0165 D480 F0 2D BEQ SPLOTE ;Nothing to do 0166 D482 AC 1A 03 LDY YLINE 0167 D485 06 D1 ASL ZMASK ;Don't want to plot the midpoint again 0168 D487 B0 05 BCS SPLOTB ;So move left 0169 D489 20 2D D5 JSR SPB ;Plot the LH fractional byte 0170 D48C 90 21 BCC SPLOTE ;No complete bytes to attempt? 0171 D48E 0172 D48E 20 B3 D3 SPLOTB JSR WBDY ;Do complete bytes left 0173 D491 B1 D6 LDAIY ZMEMG ;(NB WBDY assumes c=1) 0174 D493 4D 5A 03 EOR BGCOLF 0175 D496 85 DA STA ZTEMP 0176 D498 D0 12 BNE SPLOTD ;Not a complete byte of b/g? 0177 D49A 38 SEC ;Go for next byte - add to pixel counter 0178 D49B 8A TXA 0179 D49C 6D 61 03 ADC NPIX 0180 D49F 90 04 BCC SPLOTC 0181 D4A1 E6 DB INC ZTEMP+&01 ;MSB of pixel counter 0182 D4A3 10 07 BPL SPLOTD ;Reached margin? Then skip 0183 D4A5 AA SPLOTC TAX ;Not reached margin - then 0184 D4A6 20 16 D1 JSR PLOTFF 0185 D4A9 38 SEC ;carry on 0186 D4AA B0 E2 BCS SPLOTB ;(branch always taken). Sorry about the last comment 0187 D4AC 0188 D4AC 20 2D D5 SPLOTD JSR SPB ;Do whatever is right of the line 0189 D4AF A0 00 SPLOTE LDYIM &00 ;Translate back to Ico-ords 0190 D4B1 20 5D D5 JSR SPU 0191 D4B4 0192 D4B4 A0 20 LDYIM NEWPT-V ;Entry point for look for b/g colour 0193 D4B6 A2 24 LDXIM GCSIR-V ;Swap newpoint (in GCSIR) & calculated RH endpoint 0194 D4B8 20 D4 CD JSR SWAPF 0195 D4BB 0196 D4BB 20 5F D4 SCHEAT JSR SPF ;Address midpoint again held in NEWPT 0197 D4BE A2 04 LDXIM &04 ;Set up for plotting right 0198 D4C0 20 43 D5 JSR SPS ;Musn't corrupt ZTEMP 0199 D4C3 8A TXA ;Plot the midpoint 0200 D4C4 D0 02 BNE SPLOTA 0201 D4C6 C6 DB DEC ZTEMP+&01 0202 D4C8 CA SPLOTA DEX 0203 D4C9 0204 D4C9 20 00 D5 SPLOTL JSR SPA ;Do this RH fractional byte 0205 D4CC 90 27 BCC SPLOTK ;No full bytes to attempt? 0206 D4CE 0207 D4CE 20 A3 D3 SPLOTI JSR EBDY ;Full bytes right 0208 D4D1 B1 D6 LDAIY ZMEMG 0209 D4D3 4D 5A 03 EOR BGCOLF 0210 D4D6 85 DA STA ZTEMP 0211 D4D8 0212 D4D8 A5 DC LDA ZTEMPB 0213 D4DA D0 ED BNE SPLOTL 0214 D4DC 0215 D4DC A5 DA LDA ZTEMP 0216 D4DE D0 12 BNE SPLOTJ ;This isn't a full byte 0217 D4E0 38 SEC ;Add (NPIX)+1=no.pixels to counter 0218 D4E1 8A TXA 0219 D4E2 6D 61 03 ADC NPIX 0220 D4E5 90 04 BCC SPLOTF 0221 D4E7 E6 DB INC ZTEMP+&01 0222 D4E9 10 07 BPL SPLOTJ ;Skip if hit margin 0223 D4EB AA SPLOTF TAX 0224 D4EC 20 16 D1 JSR PLOTFF 0225 D4EF 38 SEC 0226 D4F0 B0 DC BCS SPLOTI ;(branch always taken) 0227 D4F2 0228 D4F2 20 00 D5 SPLOTJ JSR SPA 0229 D4F5 A0 04 SPLOTK LDYIM &04 ;Convert to address of LH endpoint 0230 D4F7 20 5D D5 JSR SPU 0231 D4FA 20 EB D0 SPLOTX JSR EMAEX ;Finished 0232 D4FD 4C 7D CA JMP IEG ;update external cursor 0233 D500 0234 D500 ;SPA Plots fractional LH byte on RH line end 0235 D500 0236 D500 A5 D1 SPA LDA ZMASK ;Push the initial combined mask 0237 D502 [ MOS125 = &FF 0239 D502 ] 0240 D502 18 CLC 0241 D503 90 0E BCC SPAF ;(branch always taken) 0242 D505 0243 D505 68 SPAA PLA ;Try next pixel - pull combined mask 0244 D506 E8 INX ;Increment the pixel counter 0245 D507 D0 04 BNE SPAB 0246 D509 E6 DB INC ZTEMP+&01 0247 D50B 10 16 BPL SPAE ;Exit if all pixels plotted 0248 D50D 46 D1 SPAB LSR ZMASK ;Shift mask 0249 D50F B0 12 BCS SPAE ;Exit if shifted out of character cell 0250 D511 05 D1 ORA ZMASK ;Continue forming combined mask 0251 D513 [ MOS125 = &FF Acorn macro assembler Page 36 VDU File - MOS08 0254 D513 | 0255 D513 48 SPAF PHA ;& push it again 0256 D514 A5 D1 LDA ZMASK ;START HERE 0257 D516 ] 0258 D516 24 DA BIT ZTEMP ;Is this pixel b/g colour ? 0259 D518 0260 D518 08 PHP ;Invert z flag if needs be 0261 D519 68 PLA 0262 D51A 45 DC EOR ZTEMPB ;By inverting it with ZTEMPB (0 or 2) 0263 D51C [ MOS125 = &FF 0268 D51C | 0269 D51C 29 02 ANDIM &02 ;No shorter but saves 5 cycles and ZTEMPB can't corrupt PSR 0270 D51E 0271 D51E D0 E5 BNE SPAA ;Z now inverted, NE means NOT background, so loop 0272 D520 ] 0273 D520 68 PLA ;Found it?, then pull combined mask 0274 D521 45 D1 EOR ZMASK ;& delete this pixel from it 0275 D523 85 D1 SPAE STA ZMASK ;These must preserve c! 0276 D525 4C 02 D1 JMP PLOT 0277 D528 0278 D528 [ MOS125 = &FF 0301 D528 | 0302 D528 SPBD 0303 D528 45 D1 EOR ZMASK 0304 D52A 4A LSRA 0305 D52B 90 F6 BCC SPAE ;(branch always taken) 0306 D52D 0307 D52D ;SPB Plots fractional RH byte on LH line end 0308 D52D 0309 D52D A9 00 SPB LDAIM &00 0310 D52F 0A SPBE ASLA ;CC preserved via SPAE->PLOT and seen by caller 0311 D530 05 D1 ORA ZMASK 0312 D532 24 DA BIT ZTEMP 0313 D534 D0 F2 BNE SPBD 0314 D536 E8 INX 0315 D537 D0 04 BNE SPBB 0316 D539 E6 DB INC ZTEMP+&01 0317 D53B 10 E6 BPL SPAE 0318 D53D C9 80 SPBB CMPIM &80 0319 D53F 90 EE BCC SPBE 0320 D541 B0 E0 BCS SPAE ;(branch always taken) 0321 D543 ] 0322 D543 0323 D543 ;SPS Set up pixel counter 0324 D543 0325 D543 BD 00 03 SPS LDAAX GWLCOL 0326 D546 38 SEC 0327 D547 ED 20 03 SBC NEWPT 0328 D54A A8 TAY 0329 D54B BD 01 03 LDAAX GWLCOL+&01 0330 D54E ED 21 03 SBC NEWPT+&01 0331 D551 30 03 BMI SPSA ;Ensure this is -ve 0332 D553 20 51 D4 JSR NEGAY 0333 D556 85 DB SPSA STA ZTEMP+&01 ;Store MSB 0334 D558 98 TYA 0335 D559 AA TAX ;LSB to X 0336 D55A 05 DB ORA ZTEMP+&01 ;Set z=1 if nothing to do 0337 D55C 60 RTS 0338 D55D 0339 D55D ;SPU Work out the internal co-ordinates of where we are 0340 D55D 0341 D55D 84 DA SPU STY ZTEMP 0342 D55F 8A TXA 0343 D560 A8 TAY 0344 D561 A5 DB LDA ZTEMP+&01 0345 D563 30 02 BMI SPUA ;This byte is $00 at most 0346 D565 A9 00 LDAIM &00 ;although it can get a $01 in it 0347 D567 A6 DA SPUA LDX ZTEMP 0348 D569 D0 03 BNE SPUB 0349 D56B 20 51 D4 JSR NEGAY 0350 D56E 48 SPUB PHA 0351 D56F 18 CLC 0352 D570 98 TYA 0353 D571 7D 00 03 ADCAX GWLCOL 0354 D574 8D 20 03 STA NEWPT 0355 D577 68 PLA 0356 D578 7D 01 03 ADCAX GWLCOL+&01 0357 D57B 8D 21 03 STA NEWPT+&01 0358 D57E 60 RTS 0359 D57F 0360 D57F CSREAD 0361 D57F A9 03 LDAIM &03 ;Convert internal co-ordiantes at OLDCS & GCSIR 0362 D581 20 86 D5 JSR SPCA 0363 D584 A9 07 LDAIM &07 0364 D586 48 SPCA PHA 0365 D587 20 D0 CD JSR SWAPB ;Swap old cursor with cursor 0366 D58A 20 7D CA JSR IEG ;Convert to external co-ordiantes 0367 D58D A2 03 LDXIM &03 ;& copy it 0368 D58F 68 PLA 0369 D590 A8 TAY 0370 D591 BD 10 03 SPCB LDAAX GCSR 0371 D594 91 F0 STAIY WARGS 0372 D596 88 DEY 0373 D597 CA DEX 0374 D598 10 F7 BPL SPCB 0375 D59A 60 RTS 0376 D59B 0377 D59B LNK MOS10 0001 D59B 0002 D59B TTL VDU File - MOS10 0003 D59B OPT MOS10 Acorn macro assembler Page 37 VDU File - MOS10 0004 D59B 0005 D59B ;Last revision 10/05/82 0006 D59B 0007 D59B ;10/05/82 Save 1 byte by BCS HPLOT -> BCC TRSRTS 0008 D59B ;05/05/82 HPLOT uses PLOTFF 0009 D59B ;01/05/82 Recoded using manifests & new ordering of static variables 0010 D59B ;07/02/82 Zero height triangles not so disasterous (GPT) 0011 D59B 0012 D59B ;TRIANGLE PLOTTING 0013 D59B 0014 D59B ;INITIALISATION 0015 D59B 0016 D59B A2 20 EMC LDXIM NEWPT-V ;Copy new point & graphics cursor to a safe place 0017 D59D A0 3E LDYIM GCSTMP-V 0018 D59F 20 32 D4 JSR COPY8 0019 D5A2 20 ED CD JSR SORTA ;Sort into Y co-ords, in order NEWPT=Lo, GCSIR=Hi, OLDCS=Med 0020 D5A5 A2 14 LDXIM OLDCS-V 0021 D5A7 A0 24 LDYIM GCSIR-V 0022 D5A9 20 F1 CD JSR SORTY 0023 D5AC 20 ED CD JSR SORTA 0024 D5AF A2 20 LDXIM NEWPT-V ;Set paramters for hypotenuse ... 0025 D5B1 A0 2A LDYIM HDELTA-V ;Find Deltas 0026 D5B3 20 C7 D3 JSR TRISA 0027 D5B6 AD 2B 03 LDA HDELTA+&01 ;Copy sign of DeltaX to determine direction 0028 D5B9 8D 32 03 STA HDIREC 0029 D5BC A2 28 LDXIM HPARMS 0030 D5BE 20 0F D4 JSR TRISB ;complete definition of hypotenuse parameters 0031 D5C1 A0 2E LDYIM HSTART-V ;Copy NEWPT to PStart of hypotenuse 0032 D5C3 20 F0 D0 JSR EMAEZ 0033 D5C6 ;Swap Y co-ords 2 & 3, to give 1st side 0034 D5C6 20 D0 CD JSR SWAPB ;Y co-ords now in order Lo, Med, Hi 0035 D5C9 18 CLC ;Don't plot the last line 0036 D5CA 20 F4 D5 JSR TRSF ;Do the lower half of the triangle 0037 D5CD ;Swap points to enable set up of 2nd side 0038 D5CD 20 D0 CD JSR SWAPB ;Y co-ords now Lo, Hi, Med 0039 D5D0 A2 20 LDXIM NEWPT-V ;swap Y co-ords 1 & 3 to give 2nd side 0040 D5D2 20 D2 CD JSR SWAPC ;& now Med, Hi, Lo 0041 D5D5 38 SEC ;Do plot the last line 0042 D5D6 20 F4 D5 JSR TRSF ;& plot the top half 0043 D5D9 A2 3E LDXIM GCSTMP-V ;Restore original graphics cursor & new point 0044 D5DB A0 20 LDYIM NEWPT-V 0045 D5DD 20 32 D4 JSR COPY8 0046 D5E0 4C EB D0 JMP EMAEX ;& do things to the cursors 0047 D5E3 0048 D5E3 [ MOS125 = &FF 0059 D5E3 ] 0060 D5E3 0061 D5E3 CSRPOS 0062 D5E3 AD 18 03 LDA CSX ;~~~ Read text cursor position ~~~ 0063 D5E6 38 SEC 0064 D5E7 ED 08 03 SBC TWLCOL 0065 D5EA AA TAX 0066 D5EB AD 19 03 LDA CSY 0067 D5EE 38 SEC 0068 D5EF ED 0B 03 SBC TWTROW 0069 D5F2 A8 TAY 0070 D5F3 60 TRSRTS RTS ;No, then return 0071 D5F4 0072 D5F4 ;TRSF Initialises a parameter list for ULN 0073 D5F4 ;Sets up the "sides" (as opposed to the hypoteneuse) only. Skips if 0074 D5F4 ;the 2 Y values are equal, otherwise calls HPLOT & ULN the requisite 0075 D5F4 ;number of times 0076 D5F4 ;Assumes the points forming the side to be initialised are in 0077 D5F4 ;NEWPT & GCSIR 0078 D5F4 0079 D5F4 08 TRSF PHP ;Push carry - is set if last line is to be plotted 0080 D5F5 A2 20 LDXIM NEWPT-V ;Set up triangle parameters 0081 D5F7 A0 35 LDYIM SDELTA-V ;Find deltas (sides only) 0082 D5F9 20 C7 D3 JSR TRISA 0083 D5FC AD 36 03 LDA SDELTA+&01 ;Find direction by sign of DeltaX 0084 D5FF 8D 3D 03 STA SDIREC 0085 D602 A2 33 LDXIM SPARMS-V ;Find MOD Deltas, and initialise L 0086 D604 20 0F D4 JSR TRISB 0087 D607 A0 39 LDYIM SSTART-V ;Copy NEWPT to SSTART 0088 D609 20 F0 D0 JSR EMAEZ 0089 D60C 38 SEC ;How many Y values are there to be done ? 0090 D60D AD 22 03 LDA NEWPT+&02 0091 D610 ED 26 03 SBC GCSIY 0092 D613 8D 1B 03 STA TRINLN ;Result (2's comp.) to TRINLN 0093 D616 AD 23 03 LDA NEWPT+&03 0094 D619 ED 27 03 SBC GCSIY+&01 0095 D61C 8D 1C 03 STA TRINLN+&01 ;(MSB) 0096 D61F 0D 1B 03 ORA TRINLN ;Anything to do? 0097 D622 F0 17 BEQ TRSFA 0098 D624 20 3E D6 TRSFB JSR HPLOT ;Plot the line 0099 D627 A2 33 LDXIM SPARMS-V ;Move the side up 0100 D629 20 0E D7 JSR ULN 0101 D62C A2 28 LDXIM HPARMS-V ;Move the hypoteneuse up 0102 D62E 20 0E D7 JSR ULN 0103 D631 EE 1B 03 INC TRINLN ;Any more lines ? 0104 D634 D0 EE BNE TRSFB ;Yes, then loop, otherwise 0105 D636 EE 1C 03 INC TRINLN+&01 0106 D639 D0 E9 BNE TRSFB 0107 D63B 0108 D63B 28 TRSFA PLP ;Plot the last line? 0109 D63C 90 B5 BCC TRSRTS ;No, if c=0 0110 D63E 0111 D63E ;HPLOT Fast plot of horizontal line 0112 D63E ;Plots horizontal line in current colour from points defined 0113 D63E ;at SSTART & HSTART, or, if entered at HPLOTA, from 0114 D63E ;GWTROW+(X) to GWTROW+(Y). 0115 D63E ;Y co-ordinate taken from point at (X) 0116 D63E 0117 D63E A2 39 HPLOT LDXIM SSTART-V ;Initialise point pointers 0118 D640 A0 2E LDYIM HSTART-V 0119 D642 86 DE HPLOTA STX ZTEMPC ;Store these point pointers 0120 D644 BD 00 03 LDAAX V ;Is x co-ord. of (X)<(Y) ? 0121 D647 D9 00 03 CMPAY V 0122 D64A BD 01 03 LDAAX V+&01 0123 D64D F9 01 03 SBCAY V+&01 0124 D650 30 06 BMI HPLOTB ;No, then swap (X) < = > (Y) 0125 D652 98 TYA 0126 D653 A4 DE LDY ZTEMPC 0127 D655 AA TAX 0128 D656 86 DE STX ZTEMPC 0129 D658 84 DF HPLOTB STY ZTEMPC +&01 0130 D65A 0131 D65A ;ZTEMPC & X now contain the offset from V to the L.H. point 0132 D65A ;& ZTEMPC +01 & Y the offset from V to the R.H. point 0133 D65A 0134 D65A B9 00 03 LDAAY V ;Push R.H. x co-ordinate Acorn macro assembler Page 38 VDU File - MOS10 0135 D65D 48 PHA 0136 D65E B9 01 03 LDAAY V+&01 0137 D661 48 PHA 0138 D662 A6 DF LDX ZTEMPC +&01 ;Window the R.H. point 0139 D664 20 21 D1 JSR WIND 0140 D667 F0 0D BEQ HPLOTC ;Within window?, then plot to this point 0141 D669 C9 02 CMPIM &02 ;Only other allowed value of this window is 2 0142 D66B D0 3D BNE HPLOTX ;Exit if this isn't =2 0143 D66D A2 04 LDXIM GWRCOL-V ;It was 2?, then copy R.H. margin to x co-ord of RH point 0144 D66F A4 DF LDY ZTEMPC+&01 0145 D671 20 38 D4 JSR COPY2 0146 D674 A6 DF LDX ZTEMPC+&01 0147 D676 20 F4 D7 HPLOTC JSR GADDR ;Address (modified) RH end point 0148 D679 A6 DE LDX ZTEMPC ;Window L.H. end point 0149 D67B 20 21 D1 JSR WIND 0150 D67E 4A LSRA ;Only allowed values of this window are 0 & 1 0151 D67F D0 29 BNE HPLOTX ;Neither of those?, then exit 0152 D681 90 02 BCC HPLOTD ;Window was zero, then don't modify L.H. end point 0153 D683 A2 00 LDXIM GWLCOL-V ;L.H. endpoint was to the left of L. margin, so plot to latter 0154 D685 A4 DF HPLOTD LDY ZTEMPC +&01 ;Point to R.H. end point 0155 D687 38 SEC ;to determine no. of points needed 0156 D688 B9 00 03 LDAAY V ;Generate no. of points to be plotted 0157 D68B FD 00 03 SBCAX V 0158 D68E 85 DC STA ZTEMPB 0159 D690 B9 01 03 LDAAY V+&01 0160 D693 FD 01 03 SBCAX V+&01 0161 D696 85 DD STA ZTEMPB +&01 0162 D698 A9 00 LDAIM &00 ;Generate the mask for the R.H. fractional byte 0163 D69A 0A HPLOTG ASLA 0164 D69B 05 D1 ORA ZMASK ;Generate R.H fractional mask 0165 D69D A4 DC LDY ZTEMPB 0166 D69F D0 14 BNE HPLOTE 0167 D6A1 C6 DD DEC ZTEMPB +&01 ;No more points to be plotted ? 0168 D6A3 10 10 BPL HPLOTE 0169 D6A5 85 D1 STA ZMASK ;No?, then plot this byte only 0170 D6A7 20 02 D1 JSR PLOT 0171 D6AA A6 DF HPLOTX LDX ZTEMPC+&01 ;Restore R.H. end point's x co-ordinate 0172 D6AC 68 PLA 0173 D6AD 9D 01 03 STAAX V+&01 0174 D6B0 68 PLA 0175 D6B1 9D 00 03 STAAX V 0176 D6B4 60 RTS 0177 D6B5 C6 DC HPLOTE DEC ZTEMPB 0178 D6B7 AA TAX ;Continue with generation of R.H. fractional byte mask 0179 D6B8 10 E0 BPL HPLOTG ;until b7 of this mask is set, whence is the mask complete 0180 D6BA 85 D1 STA ZMASK 0181 D6BC 20 02 D1 JSR PLOT ;Plot R.H. fractional byte 0182 D6BF A6 DC LDX ZTEMPB ;LSB of no. points to be plotted, excl RH fractional byte 0183 D6C1 E8 INX ;Increment this, for no. points is inclusive 0184 D6C2 D0 02 BNE HPLOTL 0185 D6C4 E6 DD INC ZTEMPB +&01 0186 D6C6 8A HPLOTL TXA 0187 D6C7 48 PHA ;Needed for the determination of the LH fractional byte 0188 D6C8 46 DD LSR ZTEMPB +&01 ;Divide no. points by no.pixels to give no. bytes 0189 D6CA 6A RORA 0190 D6CB AC 61 03 LDY NPIX 0191 D6CE C0 03 CPYIM &03 0192 D6D0 F0 05 BEQ HPLOTP 0193 D6D2 90 04 BCC HPLOTQ 0194 D6D4 46 DD LSR ZTEMPB +&01 ;y>3, i.e 8 pixels per byte 0195 D6D6 6A RORA 0196 D6D7 [ MOS125 = &FF 0198 D6D7 | 0199 D6D7 HPLOTP ;y=3, i.e. 4 pixels per byte 0200 D6D7 ;ZTEMPB +&01 dead; C dead as A must not exceed &4F 0201 D6D7 ] 0202 D6D7 4A LSRA 0203 D6D8 AC 1A 03 HPLOTQ LDY YLINE ;Prepare ye the way of the loop 0204 D6DB AA TAX ;Contains the nuber of complete bytes to be filled in 0205 D6DC F0 0F BEQ HPLOTF ;None?, then skip to plotting of L.H. fractional byte 0206 D6DE 0207 D6DE 98 HPLOTI TYA ;MAIN FULL BYTE LOOP 0208 D6DF 38 SEC ;Move Y back 8 bytes 0209 D6E0 E9 08 SBCIM &08 0210 D6E2 A8 TAY 0211 D6E3 B0 02 BCS HPLOTH ;Carry generated? 0212 D6E5 C6 D7 DEC ZMEMG +&01 ;Yes?, then decrement MSB of IY vector 0213 D6E7 20 16 D1 HPLOTH JSR PLOTFF ;Plot the bugger ! 0214 D6EA CA DEX ;Any more ? 0215 D6EB D0 F1 BNE HPLOTI ;Yes, then loop again 0216 D6ED 0217 D6ED 68 HPLOTF PLA ;Pull the LSB of the number of points to plotted 0218 D6EE 2D 61 03 AND NPIX ;No. of points in L.H. fractional byte 0219 D6F1 F0 B7 BEQ HPLOTX ;Leave if nothing to do 0220 D6F3 AA TAX ;Generate the mask for the LH fractional byte 0221 D6F4 A9 00 LDAIM &00 0222 D6F6 0A HPLOTJ ASLA 0223 D6F7 0D 63 03 ORA MASKR 0224 D6FA CA DEX 0225 D6FB D0 F9 BNE HPLOTJ 0226 D6FD 85 D1 STA ZMASK 0227 D6FF 98 TYA 0228 D700 38 SEC ;Move Y back 8 bytes again 0229 D701 E9 08 SBCIM &08 0230 D703 A8 TAY 0231 D704 B0 02 BCS HPLOTK ;Carry generated 0232 D706 C6 D7 DEC ZMEMG +&01 ;Yes?, then decrement MSB of IY vector 0233 D708 20 05 D1 HPLOTK JSR PLOTS ;Plot the L.H. fractional byte 0234 D70B 4C AA D6 JMP HPLOTX 0235 D70E 0236 D70E ;ULN Increments the current graphics line which is drawing the triangle 0237 D70E ;It varies the X points according to the values of the MOD deltas, and 0238 D70E ;the direction byte. 0239 D70E ;As input, it requires in X the offset of the parameter list from V. 0240 D70E ;The parameter list is assumed to be in the following order : 0241 D70E ;Bytes 0-1 "L", the variable used in determining the steps left/right 0242 D70E ;Bytes 2-3 MOD Delta X 0243 D70E ;Bytes 4-5 MOD Delta Y 0244 D70E ;Bytes 6-9 Point from which the line is to be drawn (XL,XH,YL,YH) 0245 D70E ;Byte A Direction - +ve if x increasing as Y does, else -ve 0246 D70E 0247 D70E FE 08 03 ULN INCAX V+&08 ;Increment Y value of point to be drawn from/to 0248 D711 D0 03 BNE ULNA 0249 D713 FE 09 03 INCAX V+&09 0250 D716 38 ULNA SEC ;L := L - MOD(DeltaX) 0251 D717 BD 00 03 LDAAX V 0252 D71A FD 02 03 SBCAX V+&02 0253 D71D 9D 00 03 STAAX V 0254 D720 BD 01 03 LDAAX V+&01 0255 D723 FD 03 03 SBCAX V+&03 0256 D726 9D 01 03 STAAX V+&01 Acorn macro assembler Page 39 VDU File - MOS10 0257 D729 10 2F BPL ULNB ;+ve?, then skip the move X part following 0258 D72B [ MOS125 = &FF 0270 D72B | 0271 D72B 18 ULNF CLC 0272 D72C BD 0A 03 LDAAX V+&0A ;Move X, which direction ? 0273 D72F 30 0A BMI ULNC ;Skip if move left 0274 D731 FE 06 03 INCAX V+&06 ;Move right, therefore increment the X value 0275 D734 D0 10 BNE ULND 0276 D736 FE 07 03 INCAX V+&07 0277 D739 90 0B BCC ULND ;always branch 0278 D73B BD 06 03 ULNC LDAAX V+&06 ;Move left, therefore decrement X value 0279 D73E D0 03 BNE ULNE 0280 D740 DE 07 03 DECAX V+&07 0281 D743 DE 06 03 ULNE DECAX V+&06 0282 D746 ULND ;L := L + MOD DeltaY 0283 D746 ] 0284 D746 BD 00 03 LDAAX V 0285 D749 7D 04 03 ADCAX V+&04 0286 D74C 9D 00 03 STAAX V 0287 D74F BD 01 03 LDAAX V+&01 0288 D752 7D 05 03 ADCAX V+&05 0289 D755 9D 01 03 STAAX V+&01 0290 D758 30 D1 BMI ULNF ;Move left/right again ? TRAP HORIZONTAL LINES BEFORE !! 0291 D75A 60 ULNB RTS 0292 D75B LNK MOS11 0001 D75B 0002 D75B TTL VDU File - MOS11 0003 D75B OPT MOS11 Acorn macro assembler Page 40 VDU File - MOS11 0004 D75B 0005 D75B ;Last revision 05/05/82 0006 D75B 0007 D75B ;05/05/82 Move GADDR here. Change to tabke with 1 entry only 0008 D75B ;01/05/82 Recoded to account for new ordering of variables 0009 D75B ;24/04/82 READCH returns mode in Y, char. in X (AGAIN!) 0010 D75B ;19/04/82 Improved exit at RPXLC 0011 D75B ;16/04/82 improved READCH code 0012 D75B ;25/03/82 Change order of READCH character search 0013 D75B ;22/01/82 Change EIG to EIGABS for READPX 0014 D75B ;07/01/82 Rewrite READCH for non-TTX (GPT) 0015 D75B ;16/11/81 Fix to READCH change (15/11) 0016 D75B ;15/11/81 READCH returns mode in Y, char. in X 0017 D75B ;09/11/81 (Paul) Read start of VDU space coping with model A 0018 D75B 0019 D75B ;READCH Reads the character at the current cursor location, 0020 D75B ;returning the result in A. 0021 D75B ;If the character is not found, 0 is returned. 0022 D75B ;Assumes new font splitting, using FNTFLG & PGSFNT 0023 D75B 0024 D75B READCH 0025 D75B AC 60 03 LDY NCOLOR ;Is it TTX? 0026 D75E D0 0F BNE READCE 0027 D760 B1 D8 LDAIY ZMEMT ;Yes, then read character direct (Y=0) 0028 D762 [ MOS125 = &FF 0038 D762 | 0039 D762 ;CS from OSB or RDCHK->RDCHGY->COPYCH 0040 D762 ;(or RDCHGS->GKEY..RDCHGY->COPYCH after hacking) 0041 D762 18 CLC ;transform only 0042 D763 20 F0 CF JSR TTXFRM ;convert ASCII to Teletext 0043 D766 20 F0 CF JSR TTXFRM ;and again to convert Teletext to ASCII 0044 D769 AA TAX 0045 D76A AC 55 03 READKE LDY MODE ;Only way of getting the mode 0046 D76D 8A TXA 0047 D76E ] 0048 D76E 60 RTS 0049 D76F 0050 D76F 0051 D76F 20 99 D7 READCE JSR PTCNV ;Get the bit pattern to READWS 0052 D772 [ MOS125 = &FF 0055 D772 | 0056 D772 A9 20 LDAIM &20 ;First character to be checked 0057 D774 READKF ;Address charcter 0058 D774 ] 0059 D774 48 PHA 0060 D775 20 50 D0 JSR CHADDR ;Result to ZTEMPC 0061 D778 68 PLA 0062 D779 AA TAX 0063 D77A A0 07 READKA LDYIM &07 ;Compare this character 0064 D77C B9 28 03 READKB LDAAY READWS ;Get bit pattern 0065 D77F D1 DE CMPIY ZTEMPC ;Compare with font 0066 D781 D0 07 BNE READKC ;Different?, then not this character 0067 D783 88 DEY ;Same?, then look at next row down 0068 D784 10 F6 BPL READKB 0069 D786 [ MOS125 = &FF 0071 D786 ] 0072 D786 E0 7F CPXIM &7F ;Is it a DEL? 0073 D788 D0 E0 BNE READKE ;No?, then you have found it 0074 D78A E8 READKC INX ;Next character up 0075 D78B A5 DE LDA ZTEMPC ;LSB of font pointer up by 8 0076 D78D 18 CLC 0077 D78E 69 08 ADCIM &08 0078 D790 85 DE STA ZTEMPC 0079 D792 D0 E6 BNE READKA ;More on this page? 0080 D794 8A TXA ;Finished search? 0081 D795 D0 DD BNE READKF ;No?, then try next page 0082 D797 F0 D1 BEQ READKE ;(branch always taken) 0083 D799 0084 D799 ;Converts the 8,16 or 32 byte character on the screen to an 8 byte 0085 D799 ;bit pattern in Q .. Q+07. Not very fast, in particular, the 8 byte 0086 D799 ;version could be speeded up. Background text colour is recognized 0087 D799 ;as 'background', even if cursors are joined. Anything else is 0088 D799 ;recognised as 'foreground' 0089 D799 0090 D799 ;ZTEMP is the row number (7..0) 0091 D799 ;ZTEMP +01 is he bit pattern being formed from this row 0092 D799 ;ZTEMPB is the mask being used to isolate the current pixel 0093 D799 0094 D799 A0 07 PTCNV LDYIM &07 ;The row to be converted 0095 D79B [ MOS125 = &FF 0111 D79B | 0112 D79B ;Adds 4 bytes but OS 1.25 gets them anyway 0113 D79B ;to remain parallel with 1.26 until GADDR 0114 D79B PTCNVA ;Start of 'convert 1 row' loop 0115 D79B A9 01 LDAIM &01 ;The bit pattern to be formed 0116 D79D 85 DB STA ZTEMP +&01 ;Finshed when a carry shifted out 0117 D79F CD 63 03 CMP MASKR ;C=0 if >1bpp 0118 D7A2 PTCNVB 0119 D7A2 B1 D8 LDAIY ZMEMT ;Get the byte to be tested 0120 D7A4 4D 58 03 EOR BTCOLF ;Isolate back from foreground 0121 D7A7 B0 1D BCS PTCNVF ;Write byte directly if 1bpp 0122 D7A9 85 DC STA ZTEMPB 0123 D7AB AD 62 03 LDA MASKL ;Isolates the pixel to be tested in the current byte 0124 D7AE 24 DC PTCNVC BIT ZTEMPB ;Are any of the bits in this pixel set ? 0125 D7B0 F0 01 BEQ PTCNVD ;No?, then this pixel was background 0126 D7B2 38 SEC ;Yes?, then it was foreground 0127 D7B3 26 DB PTCNVD ROL ZTEMP +&01 ;Shift this bit into the bit pattern 0128 D7B5 6A RORA ;Isolate the next pixel 0129 D7B6 90 F6 BCC PTCNVC ;carry clear, then continue 0130 D7B8 30 06 BMI PTCNVE ;pattern overflow?, then this pattern is complete 0131 D7BA ] 0132 D7BA 98 TYA ;c=1, then examine the next byte in the row 0133 D7BB 69 07 ADCIM &07 ;(c=1), by adding 8 to Y 0134 D7BD A8 TAY 0135 D7BE 90 E2 BCC PTCNVB ;and continue (branch always taken) 0136 D7C0 [ MOS125 = &FF 0139 D7C0 | 0140 D7C0 98 PTCNVE TYA ;Restore Y 0141 D7C1 29 07 ANDIM &07 0142 D7C3 A8 TAY 0143 D7C4 A5 DB LDA ZTEMP +&01 ;bit pattern finished, store it in the READWS 0144 D7C6 PTCNVF 0145 D7C6 ] 0146 D7C6 99 28 03 STAAY READWS 0147 D7C9 88 DEY ;& do the next row up 0148 D7CA 10 CF BPL PTCNVA 0149 D7CC [ MOS125 = &FF 0150 D7CC | 0151 D7CC A9 FF RPXLC LDAIM &FF ;Return $FF if point was outside graphics window 0152 D7CE ] 0153 D7CE 60 RTS ;or return Acorn macro assembler Page 41 VDU File - MOS11 0154 D7CF 0155 D7CF ;RPXL Reads the pixel at V+(A), 0156 D7CF ;returning $FF if the cursor is out of the window, else the logical 0157 D7CF ;colour at the cursor. 0158 D7CF ;Assumes the current cursor in internal representation is GCSIY... 0159 D7CF 0160 D7CF 48 RPXLD PHA 0161 D7D0 AA TAX ;Convert to Ico-ords 0162 D7D1 20 5B D1 JSR EIGABS 0163 D7D4 68 PLA 0164 D7D5 AA TAX 0165 D7D6 20 EF D7 JSR GADDV 0166 D7D9 D0 F1 BNE RPXLC ;Out of window?, then return $FF. 0167 D7DB B1 D6 LDAIY ZMEMG 0168 D7DD [ MOS125 = &FF 0181 D7DD | 0182 D7DD 85 DA STA ZTEMP 0183 D7DF B0 01 RPXLA BCS RPXLB ;kick the bit out again if it wasn't relevant 0184 D7E1 4A LSRA 0185 D7E2 06 DA RPXLB ASL ZTEMP ;Shift out the leftmost bit 0186 D7E4 2A ROLA ;& shift into the byte to receive the pixel's logical colour 0187 D7E5 06 D1 ASL ZMASK ;unless the bit was irrelevant 0188 D7E7 D0 F6 BNE RPXLA ;Have we finished ? 0189 D7E9 2D 60 03 AND NCOLOR 0190 D7EC ] 0191 D7EC 60 RPXLX RTS ;& finish 0192 D7ED 0193 D7ED ;Window a point, & plot if in window 0194 D7ED 0195 D7ED A2 20 GADDW LDXIM NEWPT-V ;Do this for new point 0196 D7EF 20 21 D1 GADDV JSR WIND ;Do this for general point. Is it in window ? 0197 D7F2 D0 F8 BNE RPXLX ;No, then skip the windowing 0198 D7F4 0199 D7F4 ;otherwise fall through to ... 0200 D7F4 0201 D7F4 ;GADDR Addresses a single pixel on the graphics screen 0202 D7F4 ;Results are not guaranteed unless point is on screen 0203 D7F4 ;Requires :- 0204 D7F4 ;(X) = offset from V of point to be addressed. 0205 D7F4 ;Format of the pointed at point is INTERNAL co-ords, non-inverted Y axis 0206 D7F4 ;with 4 bytes of XL,XH,YL,YH. 0207 D7F4 ;ZTBL points to row offset table as per character writing 0208 D7F4 ;TOPSCN as usual. 0209 D7F4 ;NPIX = No. pixles per byte 0210 D7F4 ;Wraparound may occur on ends of lines only, thus hardware must display 0211 D7F4 ;ALL the characters in the display area (OK for modes as proposed). 0212 D7F4 ;Sets the following variables 0213 D7F4 ;YLINE = line offset within character cell (0..7) 0214 D7F4 ;ZMEMG = 1st byte of character cell 0215 D7F4 ;ZMASK = mask 0216 D7F4 0217 D7F4 BD 02 03 GADDR LDAAX V+&02 ;(Y,LSB) MSB assumed 0 0218 D7F7 49 FF EORIM &FF ;Invert Y axis 0219 D7F9 A8 TAY 0220 D7FA 29 07 ANDIM &07 ;Get YLINE = 3 least significant bits of Y 0221 D7FC 8D 1A 03 STA YLINE 0222 D7FF 98 TYA 0223 D800 4A LSRA ;Get twice the character row (for 2 byte entry lookup table) 0224 D801 4A LSRA 0225 D802 4A LSRA 0226 D803 0A ASLA ;c=0 guaranteed (better than AND $FE : CLC) 0227 D804 A8 TAY ;Character row offset 0228 D805 B1 E0 LDAIY ZTBL ;Add row offset to TOPSCN 0229 D807 85 DA STA ZTEMP ;MSB 0230 D809 C8 INY 0231 D80A B1 E0 LDAIY ZTBL ;LSB 0232 D80C AC 56 03 LDY MEMODE 0233 D80F F0 03 BEQ GADDRD ; Divide by 2 if 10K mode (can only be 0 or 2) 0234 D811 46 DA LSR ZTEMP 0235 D813 6A RORA 0236 D814 6D 50 03 GADDRD ADC TOPSCN ;c=0 guaranteed before this add 0237 D817 85 D6 STA ZMEMG 0238 D819 A5 DA LDA ZTEMP 0239 D81B 6D 51 03 ADC TOPSCN+&01 0240 D81E 85 D7 STA ZMEMG +&01 0241 D820 0242 D820 ;Now calculate the X offset 0243 D820 0244 D820 BD 01 03 LDAAX V+&01 ;(MSB,X) 0245 D823 85 DA STA ZTEMP 0246 D825 BD 00 03 LDAAX V ;(LSB,X) 0247 D828 48 PHA ;Push the LSB of the X co-ordinate 0248 D829 2D 61 03 AND NPIX ;Calc. ZMASK (NB, c=0 from prev. addition) 0249 D82C 6D 61 03 ADC NPIX ;This gives the correct starting position 0250 D82F A8 TAY ;within the table, plus 1 0251 D830 B9 06 C4 LDAAY MASKTB-&01 ;So compensate by subtracting one here 0252 D833 85 D1 STA ZMASK 0253 D835 68 PLA ;Retrieve the LSB of X co-ordinate 0254 D836 AC 61 03 LDY NPIX 0255 D839 C0 03 CPYIM &03 ;Divide by NPIX, and mult. by 8 0256 D83B F0 05 BEQ GADDRA ;4 pixles/byte - mult. by 2 0257 D83D B0 06 BCS GADDRB ;8 pixles/byte - don't do anything 0258 D83F 0A ASLA ;2 pixles per byte - mult. by 4 0259 D840 26 DA ROL ZTEMP 0260 D842 0A GADDRA ASLA 0261 D843 26 DA ROL ZTEMP 0262 D845 29 F8 GADDRB ANDIM &F8 ;Ignore any low order bits 0263 D847 18 CLC ;Calculate the final address, LSB 1st 0264 D848 65 D6 ADC ZMEMG 0265 D84A 85 D6 STA ZMEMG 0266 D84C A5 DA LDA ZTEMP 0267 D84E 65 D7 ADC ZMEMG +&01 0268 D850 10 04 BPL GADDRC ;Skip wraparound if < $8000 0269 D852 38 SEC ;Correct by subtracting off screen if it is 0270 D853 ED 54 03 SBC BYTSCN 0271 D856 85 D7 GADDRC STA ZMEMG +&01 ;Store final address, MSB 0272 D858 AC 1A 03 LDY YLINE 0273 D85B A9 00 COPYZX LDAIM &00 ;Sets z=1 0274 D85D 60 RTS 0275 D85E 0276 D85E ;VDUB for cursor control keys 0277 D85E 0278 D85E VDUB 0279 D85E 48 PHA 0280 D85F A9 A0 LDAIM &A0 ;To see if the cursors are joined or drivers disabled when BIT is done 0281 D861 AE 6A 02 LDX QPOSN ;Qing bytes ? 0282 D864 D0 40 BNE VDUBEX ;Yes?, then ignore this 0283 D866 24 D0 BIT STATS ;Are the drivers enabled ? 0284 D868 D0 3C BNE VDUBEX ;Leave if not, or cursors joined 0285 D86A 70 19 BVS VDUBA ;Are we in cursor edit mode ? Yes?, then skip 0286 D86C AD 5F 03 LDA CSTEMP ;Flash the cursor at twice the rate Acorn macro assembler Page 42 VDU File - MOS11 0287 D86F 29 9F ANDIM &9F ;Sets b5=0, b6=1 of r10 of 6845, giving fast flashing cursor 0288 D871 09 40 ORAIM &40 0289 D873 20 2A C9 JSR ETCB ;Store in r10 of 6845, don't save to CSTEMP 0290 D876 A2 18 LDXIM CSX-V ;Set b1 of STATS or store CSX to PCSX 0291 D878 A0 64 LDYIM PCSX-V 0292 D87A 20 38 D4 JSR COPY2 0293 D87D 20 70 CD JSR OCSRWR ;Print the output cursor 0294 D880 A9 02 LDAIM &02 ;Set b1 of STATS 0295 D882 20 9C C5 JSR STTOR 0296 D885 A9 BF VDUBA LDAIM &BF ;Clear b6 of STATS 0297 D887 20 A7 C5 JSR STTAND 0298 D88A 68 PLA ;Restore input character to routine 0299 D88B 29 7F ANDIM &7F ;Kill the parity bit 0300 D88D 20 C0 C4 JSR VDU ;Execute cursor movement on input cursor 0301 D890 A9 40 LDAIM &40 ;Set b6 of STATS 0302 D892 4C 9C C5 JMP STTOR 0303 D895 0304 D895 ;Copy key in cursor editing 0305 D895 0306 D895 COPYCH 0307 D895 A9 20 LDAIM &20 ;Cursors joined ? 0308 D897 24 D0 BIT STATS 0309 D899 50 C0 BVC COPYZX ;Not C.E. mode, then do nothing 0310 D89B D0 BE BNE COPYZX ;Cursors joined, so do nothing 0311 D89D 20 5B D7 JSR READCH ;Read character at cursor position 0312 D8A0 F0 05 BEQ COPYCX ;Not recognised?, then exit with no further action 0313 D8A2 48 PHA ;Move input cursor right 0314 D8A3 20 63 C6 JSR HT ;But with no scrolling 0315 D8A6 68 VDUBEX PLA 0316 D8A7 60 COPYCX RTS 0317 D8A8 0318 D8A8 ;CSEDEX Finish cursor edit mode 0319 D8A8 0320 D8A8 A9 BD CSEDEX LDAIM &BD ;Clear b1 & b6 from STATS 0321 D8AA 20 A7 C5 JSR STTAND 0322 D8AD 20 27 C9 JSR ETCA ;Restore cursor from CSTEMP to r10 of 6845 0323 D8B0 A9 0D LDAIM TRMCH ;Restore (A) 0324 D8B2 60 RTS 0325 D8B3 0326 D8B3 TOPCMD 0327 D8B3 AE 55 03 LDX MODE ;~~~ Beginning of screen memory ~~~ 0328 D8B6 0329 D8B6 ;& fall through to .... 0330 D8B6 0331 D8B6 TOPMDX 0332 D8B6 8A TXA ;Don't trust (X) anymore .... 0333 D8B7 29 07 ANDIM &07 0334 D8B9 A8 TAY 0335 D8BA ; read VDU low water mark for mode Y 0336 D8BA BE 40 C4 LDXAY MODETB ;~~~ Read beginning of memory for mode (Y) ~~~ 0337 D8BD BD 5E C4 LDAAX STSCTB ;A := hi-byte of lwm address 0338 D8C0 A2 00 LDXIM &00 ;Used later 0339 D8C2 ; check model type 0340 D8C2 2C 8E 02 BIT MODEL 0341 D8C5 30 07 BMI PRBB1 ;[model B, all modes permissable] 0342 D8C7 ; model A 0343 D8C7 ; return HWM of zero for modes 0 to 3 0344 D8C7 ; (cos they require between 16K and 20K) 0345 D8C7 29 3F ANDIM &3F ;correct for 16K m/c (model A) 0346 D8C9 C0 04 CPYIM &04 ;fault modes<=3 on model A 0347 D8CB B0 01 BCS PRBB1 ;[mode>=4] 0348 D8CD 8A TXA ;model A and mode<=3. Sets (A):=0 0349 D8CE PRBB1 ;return low water mark 0350 D8CE A8 TAY 0351 D8CF 60 RTS 0352 D8D0 0353 D8D0 ENDVDU ;end of VDU code 0354 D8D0 ; Now test code layout for correctness 0355 D8D0 0356 D8D0 0000 T1 * SOH:SHR:&8-CODORG:SHR:&3 0357 D8D0 0000 T2 * DCA:SHR:&8-CODORG:SHR:&3 0358 D8D0 0000 T3 * DCB:SHR:&8-CODORG:SHR:&3 0359 D8D0 0000 T4 * DCC:SHR:&8-CODORG:SHR:&3 0360 D8D0 0000 T5 * SYN:SHR:&8-CODORG:SHR:&3 0361 D8D0 0000 T6 * ETB:SHR:&8-CODORG:SHR:&3 0362 D8D0 0000 T7 * CAN:SHR:&8-CODORG:SHR:&3 0363 D8D0 0000 T8 * EM:SHR:&8-CODORG:SHR:&3 0364 D8D0 0000 T9 * FS:SHR:&8-CODORG:SHR:&3 0365 D8D0 0000 TA * GS:SHR:&8-CODORG:SHR:&3 0366 D8D0 0000 TB * US:SHR:&8-CODORG:SHR:&3 0367 D8D0 [ T1=0 0368 D8D0 | 0370 D8D0 ] 0371 D8D0 [ T2=0 0372 D8D0 | 0374 D8D0 ] 0375 D8D0 [ T3=0 0376 D8D0 | 0378 D8D0 ] 0379 D8D0 [ T4=0 0380 D8D0 | 0382 D8D0 ] 0383 D8D0 [ T5=0 0384 D8D0 | 0386 D8D0 ] 0387 D8D0 [ T6=0 0388 D8D0 | 0390 D8D0 ] 0391 D8D0 [ T7=0 0392 D8D0 | 0394 D8D0 ] 0395 D8D0 [ T8=0 0396 D8D0 | 0398 D8D0 ] 0399 D8D0 [ T9=0 0400 D8D0 | 0402 D8D0 ] 0403 D8D0 [ TA=0 0404 D8D0 | 0406 D8D0 ] 0407 D8D0 [ TB=0 0408 D8D0 | 0410 D8D0 ] 0411 D8D0 0412 D8D0 00C3 TC * HRGTB:SHR: 8 0413 D8D0 00C3 TD * TXTTB:SHR: 8 0414 D8D0 [ TC-TD=0 0415 D8D0 | 0417 D8D0 ] 0418 D8D0 0419 D8D0 00CC TE * CLASCA:SHR: 8 Acorn macro assembler Page 43 VDU File - MOS11 0420 D8D0 00CC TF * CLASCE:SHR: 8 0421 D8D0 0422 D8D0 [ TE-TF=0 0423 D8D0 | 0425 D8D0 ] 0426 D8D0 0427 D8D0 OPT OPPON 0428 D8D0 < 3 0429 D8D0 0430 D8D0 LNK MOS30 0001 D8D0 ; MOS30 0002 D8D0 OPT &01 0003 D8D0 TTL MOS30 Manifests 0004 D8D0 0005 D8D0 ;Change record: 0006 D8D0 0007 D8D0 0008 D8D0 < &0003 0009 D8D0 > &0002 0010 D8D0 0011 D8D0 0012 D8D0 0013 D8D0 0014 D8D0 ; module print selections 0015 D8D0 ; 0016 D8D0 0005 MOS30 * DEFOPT 0017 D8D0 0005 MOS32 * DEFOPT 0018 D8D0 0005 MOS34 * DEFOPT 0019 D8D0 0005 MOS36 * DEFOPT 0020 D8D0 0005 MOS38 * DEFOPT 0021 D8D0 0005 MOS39 * DEFOPT 0022 D8D0 0005 MOS40 * DEFOPT 0023 D8D0 0005 MOS42 * DEFOPT 0024 D8D0 0005 MOS44 * DEFOPT 0025 D8D0 0005 MOS46 * DEFOPT 0026 D8D0 0005 MOS48 * DEFOPT 0027 D8D0 0028 D8D0 0005 MOS52 * DEFOPT 0029 D8D0 0005 MOS54 * DEFOPT 0030 D8D0 0005 MOS56 * DEFOPT 0031 D8D0 0032 D8D0 0005 MOS99 * DEFOPT 0033 D8D0 0034 D8D0 0035 D8D0 OPT MOS30 Acorn macro assembler Page 44 MOS30 Manifests 0036 D8D0 ;(c) 1981 ACORN Computers Limited 0037 D8D0 ;BBC Microcomputer Machine Operating System (MOS) 0038 D8D0 ;Change record: 0039 D8D0 ;Author(s): 0040 D8D0 ;PB Paul Bond 0041 D8D0 ;MP Mike Prees 0042 D8D0 0043 D8D0 0044 D8D0 ; version number 0045 D8D0 ; 0046 D8D0 0001 MCVER * &01 ;OS binary version number 0047 D8D0 0031 VERA * "1" 0048 D8D0 0032 VERB * "2" 0049 D8D0 [ MOS125 = &FF 0051 D8D0 ] 0052 D8D0 [ MOS125 = &7F 0053 D8D0 0036 VERC * "6" 0054 D8D0 ] 0055 D8D0 [ MOS125 = &00 0057 D8D0 ] 0058 D8D0 0059 D8D0 0060 D8D0 ; composition 0061 D8D0 ; 0062 D8D0 0000 TRUE * &00 ;for conditional assembly 0063 D8D0 00FF FALSE * &FF ;for conditional assembly 0064 D8D0 0065 D8D0 0066 D8D0 ; options 0067 D8D0 ; 0068 D8D0 0000 INKYSW * TRUE 0069 D8D0 0070 D8D0 0071 D8D0 ; VDU software interface 0072 D8D0 ; 0073 D8D0 C300 VDUORG * &C300 ;VDU software module origin 0074 D8D0 C300 VDINIT * VDUORG +&00 ;initialise RAM and VDU 0075 D8D0 D8D0 ORIGIN * ENDVDU 0076 D8D0 0077 D8D0 0078 D8D0 ; tube interface 0079 D8D0 ; 0080 D8D0 ^ &0400 0081 D8D0 0400 TBLANG # &03 ;enter language 0082 D8D0 0403 TBESC # &03 ;alter escape condition 0083 D8D0 0406 TBADDR # &03 ;address translation 0084 D8D0 0085 D8D0 0086 D8D0 0087 D8D0 ; error codes 0088 D8D0 0089 D8D0 ; special reports 0090 D8D0 ; 0091 D8D0 0092 D8D0 0093 D8D0 0094 D8D0 ; infamous BASIC error number assignment boob 0095 D8D0 ; 0096 D8D0 0097 D8D0 0098 D8D0 0099 D8D0 ; MOS errors 0100 D8D0 ; 0101 D8D0 0102 D8D0 0103 D8D0 0104 D8D0 ; $FF is reserved for a non-trappable error in future systems 0105 D8D0 ; 0106 D8D0 00FE BADCMD * &FE ;'Bad command' 0107 D8D0 00FD BADST * &FD ;'Bad string' 0108 D8D0 00FC BADADR * &FC ;'Bad address' 0109 D8D0 00FB BADKY * &FB ;'Bad key' 0110 D8D0 00FA KEYUSE * &FA ;'Key in use' 0111 D8D0 00F9 NOLROM * &F9 ;'No language ROM' 0112 D8D0 00F8 NOFSYS * &F8 ;'No filing system' 0113 D8D0 00F7 FX0MSG * &F7 ;operating system version number 0114 D8D0 0115 D8D0 0116 D8D0 ; file system control operations 0117 D8D0 ; 0118 D8D0 0000 FSOPT * &00 ;*OPT x,y value assumed by FX code 0119 D8D0 0001 FSEOF * &01 ;EOF#chan value assumed by FX code 0120 D8D0 0002 FSNOTA * &02 ;*non-alpha 0121 D8D0 0003 FSNAME * &03 ;*name 0122 D8D0 0004 FSRUN * &04 ;*RUN name 0123 D8D0 0005 FSCAT * &05 ;*CAT name 0124 D8D0 0006 FSDIE * &06 ;kill filing system 0125 D8D0 0007 FSHRNG * &07 ;return handle range in X (lo) and Y (hi) 0126 D8D0 0127 D8D0 0008 FSCLI * &08 ;*command encountered 0128 D8D0 0129 D8D0 0130 D8D0 ; user print operations 0131 D8D0 ; 0132 D8D0 0000 UPTIME * &00 ;timer interrupt 0133 D8D0 0001 UPWRCH * &01 ;write character 0134 D8D0 ; return C=0 => printer busy, C=1 => printer free 0135 D8D0 0136 D8D0 0137 D8D0 0138 D8D0 0139 D8D0 ; NET operations 0140 D8D0 ; 0141 D8D0 ; hi-level 0142 D8D0 ; 0143 D8D0 ; VALUES $01-$03,$05 RESERVED FOR PRINTER INTERFACE 0144 D8D0 0004 NTWRCH * &04 ;WRCH 0145 D8D0 0006 NTRDCH * &06 ;RDCH 0146 D8D0 0147 D8D0 0008 NTWORD * &08 ;OSWORD call (c.f. SVWORD) 0148 D8D0 0149 D8D0 0150 D8D0 0151 D8D0 ; service ROM operations 0152 D8D0 ; 0153 D8D0 0010 NROM * &0010 ;number of paged ROMs 0154 D8D0 0155 D8D0 0000 SVNOP * &00 ;no operation 0156 D8D0 0001 SVSTAT * &01 ;offer static allocation 0157 D8D0 0002 SVDYN * &02 ;offer dynamic allocation 0158 D8D0 0003 SVBOOT * &03 ;offer bootstrap Acorn macro assembler Page 45 MOS30 Manifests 0159 D8D0 0004 SVNAME * &04 ;offer command 0160 D8D0 0005 SVINT * &05 ;unknown interrupt 0161 D8D0 0006 SVBRK * &06 ;offer BRK 0162 D8D0 0007 SVBYTE * &07 ;offer bad OSBYTE (N.B. also NTxxxx code) 0163 D8D0 0008 SVWORD * &08 ;offer bad OSWORD (N.B. also NTxxxx code) 0164 D8D0 ; 0165 D8D0 [ FALSE=0 0167 D8D0 | 0168 D8D0 0009 SVHELP * &09 ;*HELP facility 0169 D8D0 ] 0170 D8D0 ; 0171 D8D0 000A SVCSHR * &0A ;claim shared workspace 0172 D8D0 000B SVRNMI * &0B ;release NMI 0173 D8D0 000C SVCNMI * &0C ;claim NMI 0174 D8D0 000D SVISFS * &0D ;initialise speech filing system 0175 D8D0 000E SVRSFS * &0E ;read from speech filing system 0176 D8D0 000F SVFSIC * &0F ;changed filing system indirections 0177 D8D0 0178 D8D0 0010 SVSHES * &10 ;shut EXEC and SPOOL files 0179 D8D0 0011 SVHWMC * &11 ;change of HWM ******** DO NOT CHANGE ******** 0180 D8D0 0012 SVSTFS * &12 ;start filing system N 0181 D8D0 00FE SVTPIN * &FE ;tube post-initialisation **** VALUE ASSUMED BY RESET **** 0182 D8D0 00FF SVTUBE * &FF ;initialise tube software 0183 D8D0 0184 D8D0 0185 D8D0 ; language entry reasons 0186 D8D0 ; 0187 D8D0 0000 LGNONE * &00 ;no language ROM (tube entry reason) 0188 D8D0 0001 LGENTR * &01 ;enter language 0189 D8D0 0190 D8D0 0191 D8D0 ; RS423 transmitter control bits 0192 D8D0 ; 0193 D8D0 0000 RHITXD * &00 ;RTS hi, Tx interrupt disabled 0194 D8D0 0020 RHITXE * &20 ;RTS hi, Tx interrupt enabled 0195 D8D0 0040 RLOTXD * &40 ;RTS lo, Tx interrupt disabled 0196 D8D0 0060 RHITXB * &60 ;RTS hi, Tx break 0197 D8D0 0056 RSCDEF * &16+RLOTXD ;Rx interrupt disabled ... 0198 D8D0 ; ... RTS lo, Tx interrupt disabled, divide by 64, 8 data bits, 1 stop bit 0199 D8D0 0200 D8D0 0201 D8D0 ; speech processor opcodes 0202 D8D0 ; 0203 D8D0 0010 SPOPRB * &10 ;read byte 0204 D8D0 0060 SPOPSE * &60 ;speak external 0205 D8D0 0030 SPOPBR * &30 ;read and branch 0206 D8D0 0040 SPOPLA * &40 ;load address 0207 D8D0 0050 SPOPSP * &50 ;speak 0208 D8D0 00FF SPOPRT * &FF ;reset 0209 D8D0 0210 D8D0 0211 D8D0 ; memory map assignments 0212 D8D0 ; 0213 D8D0 FC00 FRED * &FC00 0214 D8D0 FCFF MEG1P * &FCFF ;1MHz bus page selector 0215 D8D0 FD00 JIM * &FD00 0216 D8D0 FE00 SHEIL * &FE00 0217 D8D0 FE08 ACIA * &FE08 0218 D8D0 FE10 SERPRC * &FE10 ;serial processor 0219 D8D0 0220 D8D0 FE20 VPROC0 * &FE20 ;video processor 0221 D8D0 FE21 VPROC1 * VPROC0 +&01 0222 D8D0 FE20 STNID * &FE20 ;ECONET station identifier 0223 D8D0 FE30 ROM * &FE30 ;ROM select latch 0224 D8D0 FE40 VIAA * &FE40 ;first 6522 0225 D8D0 FE60 VIAB * &FE60 ;second 6522 0226 D8D0 0227 D8D0 0228 D8D0 ; analog to digital converter 0229 D8D0 ; 0230 D8D0 FEC0 ADCONV * &FEC0 0231 D8D0 FEC0 ADCCTL * ADCONV +&00 0232 D8D0 FEC1 ADCHI * ADCONV +&01 0233 D8D0 FEC2 ADCLO * ADCONV +&02 0234 D8D0 0235 D8D0 0236 D8D0 ; tube register(s) 0237 D8D0 ; 0238 D8D0 FEE0 TREG0 * &FEE0 0239 D8D0 FEE5 TREG3 * &FEE5 0240 D8D0 0241 D8D0 0242 D8D0 0243 D8D0 ; test software indirection 0244 D8D0 ; 0245 D8D0 FDFE TSTSFT * &FDFE 0246 D8D0 0247 D8D0 0248 D8D0 ; language ROM address 0249 D8D0 ; 0250 D8D0 8000 LANG * &8000 0251 D8D0 8000 ROMHRD * LANG +&00 ;hard ROM entry point 0252 D8D0 8003 ROMSFT * LANG +&03 ;soft ROM entry point 0253 D8D0 0254 D8D0 8006 ROMTYP * LANG +&06 ;ROM type 0255 D8D0 8007 COPYRP * LANG +&07 ;relative offset (from LANG) to copyright string 0256 D8D0 8008 ROMVER * LANG +&08 ;version byte 0257 D8D0 8009 ROMMSG * LANG +&09 ;name 0258 D8D0 0259 D8D0 0260 D8D0 ; miscellaneous constants 0261 D8D0 ; 0262 D8D0 0000 ZERO * &00 0263 D8D0 0000 NULL * ZERO ;don't care value 0264 D8D0 0020 SPACE * &20 0265 D8D0 0040 AT * &40 0266 D8D0 0041 ALPHAA * "A" 0267 D8D0 0022 DQUOTE * """" 0268 D8D0 002A SPLAT * "*" 0269 D8D0 0060 POUND * &60 0270 D8D0 0271 D8D0 0272 D8D0 0273 D8D0 0007 BEL * &07 0274 D8D0 0275 D8D0 0009 MHT * &09 0276 D8D0 0009 TAB * MHT 0277 D8D0 000A MLF * &0A 0278 D8D0 000D MCR * &0D 0279 D8D0 0015 MNAK * &15 0280 D8D0 Acorn macro assembler Page 46 MOS30 Manifests 0281 D8D0 001B ESC * &1B 0282 D8D0 007F MDEL * &7F 0283 D8D0 0284 D8D0 0285 D8D0 ; real softkeys 0286 D8D0 ; 0287 D8D0 0080 SOFTK0 * &0080 ;f0 (value must NOT be altered) 0288 D8D0 0081 SOFTK1 * SOFTK0 +&01 ;f1 0289 D8D0 0082 SOFTK2 * SOFTK1 +&01 ;f2 0290 D8D0 0083 SOFTK3 * SOFTK2 +&01 ;f3 0291 D8D0 0084 SOFTK4 * SOFTK3 +&01 ;f4 0292 D8D0 0085 SOFTK5 * SOFTK4 +&01 ;f5 0293 D8D0 0086 SOFTK6 * SOFTK5 +&01 ;f6 0294 D8D0 0087 SOFTK7 * SOFTK6 +&01 ;f7 0295 D8D0 0088 SOFTK8 * SOFTK7 +&01 ;f8 0296 D8D0 0089 SOFTK9 * SOFTK8 +&01 ;f9 0297 D8D0 0298 D8D0 0299 D8D0 ; pseudo softkeys, including cursor controls 0300 D8D0 ; 0301 D8D0 008A SOFTKA * SOFTK9 +&01 0302 D8D0 008B SOFTKB * SOFTKA +&01 ;COPY 0303 D8D0 008B MCOPY * SOFTKB 0304 D8D0 008C SOFTKC * SOFTKB +&01 ;cursor left arrow 0305 D8D0 008C CURLFT * SOFTKC 0306 D8D0 008D SOFTKD * SOFTKC +&01 ;cursor right arrow 0307 D8D0 008D CURRHT * SOFTKD 0308 D8D0 008E SOFTKE * SOFTKD +&01 ;cursor down 0309 D8D0 008E CURDWN * SOFTKE 0310 D8D0 008F SOFTKF * SOFTKE +&01 ;cursor up 0311 D8D0 008F CURUP * SOFTKF 0312 D8D0 00BF MAXSK * &BF ;maximum value of SHIFT/CTRL softkey code 0313 D8D0 00CA BREKEY * &CA ;softkey 10 feature 0314 D8D0 0315 D8D0 0316 D8D0 ; default auto-repeat rates 0317 D8D0 ; 0318 D8D0 0032 DAUTOD * 50 ;delay (centiseconds) 0319 D8D0 0008 DAUTOP * 8 ;period (centiseconds) 0320 D8D0 0321 D8D0 0322 D8D0 ; default RS423 baud rates 0323 D8D0 ; 0324 D8D0 0064 B9600 * &64 ;Tx9600 and Rx9600 0325 D8D0 0326 D8D0 0327 D8D0 ; RS423 printer timeout period 0328 D8D0 ; 0329 D8D0 00E7 PTIMUT * &E7 ;(-) 25/50 second 0330 D8D0 0331 D8D0 0332 D8D0 ; OS constants 0333 D8D0 0E00 OSHWM * &0E00 ;default high water mark 0334 D8D0 0D00 NMI * &0D00 0335 D8D0 0336 D8D0 0337 D8D0 ; buffer indices 0338 D8D0 ; 0339 D8D0 0000 BRDCH * &0000 ;RDCH (keyboard) 0340 D8D0 0001 BRSI * &0001 ;RS423 input 0341 D8D0 0001 INPUT * BRSI 0342 D8D0 0002 BRSO * &0002 ;RS423 output 0343 D8D0 0002 OUTPUT * BRSO 0344 D8D0 0003 BPRNT * &0003 ;print 0345 D8D0 0004 BSND1 * &0004 ;sound channel 1 0346 D8D0 0005 BSND2 * BSND1+&1 ;sound channel 2 0347 D8D0 0006 BSND3 * BSND2+&1 ;sound channel 3 0348 D8D0 0007 BSND4 * BSND3+&1 ;sound channel 4 0349 D8D0 0008 BSPCH * BSND4+&1 ;speech 0350 D8D0 0008 BUPB * BSPCH 0351 D8D0 0352 D8D0 0353 D8D0 ; keyboard status bits 0354 D8D0 ; 0355 D8D0 0008 SHFT * &08 ;SHIFT active 0356 D8D0 0010 CAPSL * &10 ;not CAPITALS lock 0357 D8D0 0020 SHFTL * &20 ;not SHIFT lock 0358 D8D0 0040 CTRL * &40 ;CTRL active 0359 D8D0 0080 INVERT * &80 ;SHIFT enable 0360 D8D0 00B7 CTLSHI * &B7 ;inverted (CTRL and SHIFT status bits) 0361 D8D0 0362 D8D0 0363 D8D0 ; keyboard matrix element values 0364 D8D0 ; 0365 D8D0 00C0 CPLKKY * &C0 ;CAPITALS lock key 0366 D8D0 00D0 SHLKKY * &D0 ;SHIFT lock key 0367 D8D0 0368 D8D0 0369 D8D0 ; FX numbers 0370 D8D0 ; 0371 D8D0 0088 FXCODE * &88 0372 D8D0 0089 FXMOTR * &89 0373 D8D0 008B FXOPT * &8B 0374 D8D0 008C FXTAPE * &8C 0375 D8D0 008D FXSROM * &8D 0376 D8D0 0090 FXTV * &90 0377 D8D0 0378 D8D0 0379 D8D0 ; MC6850 addresses 0380 D8D0 ; 0381 D8D0 FE08 RSCTL * ACIA 0382 D8D0 FE08 RSTAT * ACIA 0383 D8D0 FE09 RSDATA * ACIA +&01 0384 D8D0 0385 D8D0 0386 D8D0 ; miscellaneous 0387 D8D0 ; 0388 D8D0 0004 NADC * &04 ;number of ADC channels 0389 D8D0 0390 D8D0 0391 D8D0 ; 6522 addresses 0392 D8D0 ; 0393 D8D0 FE40 PBQ * VIAA 0394 D8D0 FE41 PAQ * VIAA +&01 0395 D8D0 FE42 DDRBQ * VIAA +&02 0396 D8D0 FE43 DDRAQ * VIAA +&03 0397 D8D0 FE44 TQCLQ * VIAA +&04 0398 D8D0 FE45 TQCHQ * VIAA +&05 0399 D8D0 FE46 TQLLQ * VIAA +&06 0400 D8D0 FE47 TQLHQ * VIAA +&07 0401 D8D0 FE48 TRCLQ * VIAA +&08 Acorn macro assembler Page 47 MOS30 Manifests 0402 D8D0 FE49 TRCHQ * VIAA +&09 0403 D8D0 FE4A SRQ * VIAA +&0A 0404 D8D0 FE4B ACRQ * VIAA +&0B 0405 D8D0 FE4C PCRQ * VIAA +&0C 0406 D8D0 000A CAPULS * &0A 0407 D8D0 000C CA2LO * &0C 0408 D8D0 000E CA2HI * &0E 0409 D8D0 00A0 CBPULS * &A0 0410 D8D0 00C0 CB2LO * &C0 0411 D8D0 00E0 CB2HI * &E0 0412 D8D0 FE4D IFRQ * VIAA +&0D 0413 D8D0 FE4E IERQ * VIAA +&0E 0414 D8D0 FE4F PAPQ * VIAA +&0F 0415 D8D0 FE60 PBR * VIAB 0416 D8D0 FE61 PAR * VIAB +&01 0417 D8D0 FE62 DDRBR * VIAB +&02 0418 D8D0 FE63 DDRAR * VIAB +&03 0419 D8D0 FE64 TQCLR * VIAB +&04 0420 D8D0 FE65 TQCHR * VIAB +&05 0421 D8D0 FE66 TQLLR * VIAB +&06 0422 D8D0 FE67 TQLHR * VIAB +&07 0423 D8D0 FE68 TRCLR * VIAB +&08 0424 D8D0 FE69 TRCHR * VIAB +&09 0425 D8D0 FE6A SRR * VIAB +&0A 0426 D8D0 FE6B ACRR * VIAB +&0B 0427 D8D0 FE6C PCRR * VIAB +&0C 0428 D8D0 FE6D IFRR * VIAB +&0D 0429 D8D0 FE6E IERR * VIAB +&0E 0430 D8D0 FE6F PAPR * VIAB +&0F 0431 D8D0 0432 D8D0 0433 D8D0 ; interrupt flags in 6522 IER and IFR 0434 D8D0 ; 0435 D8D0 0002 CA1 * &0002 0436 D8D0 0001 CA2 * &0001 0437 D8D0 0010 CB1 * &0010 0438 D8D0 0008 CB2 * &0008 0439 D8D0 0040 TIMER1 * &0040 0440 D8D0 0020 TIMER2 * &0020 0441 D8D0 0442 D8D0 0443 D8D0 ; VIA pin assignments 0444 D8D0 ; 0445 D8D0 ; VIAA:- 0446 D8D0 ; PA7-PA0 keyboard 0447 D8D0 ; CA1 VSYNC interrupt 0448 D8D0 0002 VSYNC * CA1 0449 D8D0 ; CA2 keyboard interrupt ('any key down') 0450 D8D0 0001 KEYBD * CA2 0451 D8D0 ; PB7 VSP interrupt 0452 D8D0 ; PB6 VSP ready 0453 D8D0 ; PB5,PB4 paddle 0454 D8D0 ; PB3-PB0 addressable latch 0455 D8D0 ; PB3 data value 0456 D8D0 ; PB2-PB0 latch register 0457 D8D0 ; 0 sound enable 0458 D8D0 ; 1 speech RS 0459 D8D0 ; 2 speech WS 0460 D8D0 ; 3 keyboard disable 0461 D8D0 ; 4,5 hardware scroll 0462 D8D0 ; 6,7 ROM select 0463 D8D0 ; CB1 ADC 0464 D8D0 0010 ADC * CB1 0465 D8D0 ; CB2 light pen 0466 D8D0 0467 D8D0 ; VIAB:- 0468 D8D0 ; PA7-PA0 printer output 0469 D8D0 ; CA1 printer acknowledge 0470 D8D0 0002 PRNT * CA1 0471 D8D0 ; CA2 printer strobe 0472 D8D0 ; PB7-PB0 reserved for user 0473 D8D0 ; CB1 reserved for user 0474 D8D0 ; CB2 reserved for user 0475 D8D0 ; TIMER 1 = MAIN CLOCK 0476 D8D0 0040 CLOCK * TIMER1 0477 D8D0 0478 D8D0 0479 D8D0 ; page one is main system stack 0480 D8D0 ; 0481 D8D0 00FF STACK * &FF 0482 D8D0 0483 D8D0 0484 D8D0 0485 D8D0 ; BUFFERS 0486 D8D0 0487 D8D0 0488 D8D0 ; keyboard 0489 D8D0 ; 0490 D8D0 03E0 RDCHBF * &03E0 ;RDCH (keyboard) buffer 0491 D8D0 0020 RDCHSZ * &0020 0492 D8D0 0493 D8D0 0494 D8D0 ; sound 0495 D8D0 ; 0496 D8D0 0800 SNDWRK * &0800 ;sound workspace 0497 D8D0 0804 MACTIV * SNDWRK+&04 ;activation flags 0498 D8D0 0499 D8D0 0840 SNDBF1 * &0840 ;sound buffer channel 1 0500 D8D0 0010 SBSIZE * &0010 ;sound buffer size 0501 D8D0 0850 SNDBF2 * SNDBF1+SBSIZE ;sound buffer channel 2 0502 D8D0 0860 SNDBF3 * SNDBF2+SBSIZE ;sound buffer channel 3 0503 D8D0 0870 SNDBF4 * SNDBF3+SBSIZE ;sound buffer channel 4 0504 D8D0 0505 D8D0 0506 D8D0 ; printer 0507 D8D0 ; 0508 D8D0 0880 PRNBF * &0880 ;print buffer 0509 D8D0 0040 PRNSZ * &0040 0510 D8D0 0511 D8D0 0512 D8D0 ; envelopes 0513 D8D0 ; 0514 D8D0 08C0 ENVEL * &08C0 ;sound envelopes 0515 D8D0 0010 ENVSIZ * &0010 ;size of each envelope 0516 D8D0 0004 NENV * &0004 ;number of envelopes 0517 D8D0 0518 D8D0 0519 D8D0 ; RS423 output 0520 D8D0 ; 0521 D8D0 0900 RSROBF * &0900 ;RS423 output 0522 D8D0 00C0 RSROSZ * &00C0 Acorn macro assembler Page 48 MOS30 Manifests 0523 D8D0 0524 D8D0 0525 D8D0 ; speech 0526 D8D0 ; 0527 D8D0 09C0 SPCHBF * &09C0 ;speech buffer 0528 D8D0 0040 SPCHSZ * &0040 0529 D8D0 0530 D8D0 0531 D8D0 ; RS423 input 0532 D8D0 ; 0533 D8D0 0A00 RSRIBF * &0A00 ;RS423 input 0534 D8D0 0100 RSRISZ * &0100 0535 D8D0 0008 RSOVR * 8 ;handshake overflow allowance 0536 D8D0 0537 D8D0 0538 D8D0 ; soft key buffer 0539 D8D0 ; 0540 D8D0 0B00 SKPTR * &0B00 ;pointers to soft key strings 0541 D8D0 0010 NSOFTK * 16 0542 D8D0 0B01 SKBUF * SKPTR+&01 ;N.B. soft key pointers are relative to this origin 0543 D8D0 0B10 SKEND * SKPTR+NSOFTK ;logical end of string 0544 D8D0 00EF TOTSFT * SKPTR+&0100-SKEND-&01 ;soft key data byte size 0545 D8D0 0546 D8D0 0547 D8D0 LNK MOS32 0001 D8D0 0002 D8D0 ; -> MOS32 0003 D8D0 TTL MOS32 Initialisation and external interfaces 0004 D8D0 OPT MOS32 Acorn macro assembler Page 49 MOS32 Initialisation and external interfaces 0005 D8D0 ;(c) 1981 ACORN Computers Limited 0006 D8D0 ;BBC Microcomputer Machine Operating System (MOS) 0007 D8D0 ;Change record: 0008 D8D0 ;Author(s): 0009 D8D0 ;PB Paul Bond 0010 D8D0 ;MP Mike Prees 0011 D8D0 0012 D8D0 0013 D8D0 ; origin of real code 0014 D8D0 ORG ORIGIN ;MOS starts where VDU ends 0015 D8D0 0016 D8D0 0017 D8D0 IPAGE0 ;page zero values 0018 D8D0 ; externally accessed zero page values 0019 D8D0 ^ &00FF 0020 D8D0 ; 0021 D8D0 00FF ESCFLG # 0 ;Bit 7 of this is the escape flag 0022 D8D0 0023 D8D0 0024 D8D0 ; bit7 escape pending 0025 D8D0 ;= ZERO 0026 D8D0 0027 D8D0 00FF # -2 0028 D8D0 00FD REPTR # &00 ;pointer after BRK 0029 D8D0 ;= NULL /;hi-byte 0030 D8D0 ;= NULL ;lo-byte 0031 D8D0 0032 D8D0 00FD # -1 0033 D8D0 00FC TEMPA # &00 ;user IRQ routine save slot for register A 0034 D8D0 ;= NULL 0035 D8D0 0036 D8D0 00FC # -2 0037 D8D0 00FA SEIWK # &00 ;two work slots used whilst interrupts disabled 0038 D8D0 ; 0039 D8D0 00FA JMILO * SEIWK +&00 ;used by OSBYTE/OSWORD 0040 D8D0 00FB JMIHI * SEIWK +&01 ;used by OSBYTE/OSWORD 0041 D8D0 ; 0042 D8D0 00FA KEYSV * SEIWK +&00 ;work area for ... 0043 D8D0 00FB SKSZWK * SEIWK +&01 ; ... soft key compaction (also SKSIZE) 0044 D8D0 ; 0045 D8D0 00FA KTEMP * SEIWK +&00 ;work area for keyboard 0046 D8D0 ; 0047 D8D0 00FA BUFFLO * SEIWK +&00 ;work slots used by buffer management 0048 D8D0 00FB BUFFHI * SEIWK +&01 0049 D8D0 ; 0050 D8D0 00FA CRLO * SEIWK +&00 ;work slots used during ROM compare 0051 D8D0 00FB CRHI * SEIWK +&01 0052 D8D0 ; 0053 D8D0 00FA MASK * SEIWK +&00 ;work slots used by set Rx/Tx RS423 baud rates 0054 D8D0 00FB BAUD * SEIWK +&01 0055 D8D0 ; 0056 D8D0 00FA RSOP * SEIWK +&00 ;work slot used by RSUCTL 0057 D8D0 ; 0058 D8D0 00FA NOTEWK * SEIWK +&00 ;work slot used by NOTE 0059 D8D0 ; 0060 D8D0 00FA EVENTA * SEIWK +&00 ;work slot used by EVENT (hopefully no clashes) 0061 D8D0 ; 0062 D8D0 00FA PEEKLO * SEIWK +&00 ;work slot used by OSWORD read-byte/write-byte 0063 D8D0 00FB PEEKHI * SEIWK +&01 0064 D8D0 ; 0065 D8D0 00FA SPWK1 * SEIWK +&00 ;used by speech sprocessing 0066 D8D0 00FB SPWK2 * SEIWK +&01 ;used by TIMER2 (speech) interrupt routine 0067 D8D0 0068 D8D0 00FA # -1 0069 D8D0 00F9 SPARE0 # &00 ;**************** 0070 D8D0 ; = NULL 0071 D8D0 0072 D8D0 00F9 # -1 0073 D8D0 00F8 SPARE1 # &00 ;**************** 0074 D8D0 ;= NULL 0075 D8D0 0076 D8D0 00F8 # -2 0077 D8D0 00F6 ROMPTR # &00 ;pointer used by ROM filing system 0078 D8D0 ;= NULL 0079 D8D0 ;= NULL 0080 D8D0 0081 D8D0 00F6 # -1 0082 D8D0 00F5 SEROM # &00 ;serial ROM id 0083 D8D0 ;= NULL 0084 D8D0 0085 D8D0 00F5 # -1 0086 D8D0 00F4 ROMID # &00 ;currently selected ROM 0087 D8D0 0088 D8D0 ;= NULL 0089 D8D0 0090 D8D0 00F4 # -2 0091 D8D0 00F2 WORK # &00 ;miscellaneous pointer 0092 D8D0 ;= NULL 0093 D8D0 ;= NULL 0094 D8D0 0095 D8D0 00F2 # -2 0096 D8D0 ; WORD values may be shared with other sei-routines 0097 D8D0 00F0 WORDX # &00 0098 D8D0 00F0 BYTEX * WORDX 0099 D8D0 00F1 WORDY * WORDX +&01 0100 D8D0 00F1 BYTEY * WORDY 0101 D8D0 0102 D8D0 00F0 # -1 0103 D8D0 00EF WORDA # &00 0104 D8D0 00EF BYTEA * WORDA 0105 D8D0 ;= NULL 0106 D8D0 0107 D8D0 00EF # -1 0108 D8D0 00EE PAGE1M # &00 ;selected page for 1MHz bus 0109 D8D0 ;= ZERO 0110 D8D0 0111 D8D0 00EE # -1 0112 D8D0 00ED OKEY # &00 ;current key value 0113 D8D0 ;= ZERO 0114 D8D0 0115 D8D0 00ED # -1 0116 D8D0 00EC CKEY # &00 ;current key value 0117 D8D0 ;= ZERO 0118 D8D0 0119 D8D0 00EC # -1 0120 D8D0 00EB ESSEMA # &00 ;EXEC/SPOOL semaphore (used by CFS) 0121 D8D0 0122 D8D0 0123 D8D0 00EB # -1 0124 D8D0 00EA RSTUT # &00 ;RS423 printer timeouT 0125 D8D0 ;= ZERO Acorn macro assembler Page 50 MOS32 Initialisation and external interfaces 0126 D8D0 0127 D8D0 00EA # -2 0128 D8D0 00E8 RDLNBF # &00 ;buffer address used by OSWORD readline routine 0129 D8D0 0130 D8D0 00E8 # -1 0131 D8D0 00E7 ARCTR # &00 ;auto-repeat counter 0132 D8D0 ;= ZERO 0133 D8D0 0134 D8D0 00E7 # -1 0135 D8D0 00E6 WRKCLI # &00 ;shared work slot with interrupts enabled 0136 D8D0 ; 0137 D8D0 00E6 RDCTEM * WRKCLI ;used by RDCH 0138 D8D0 00E6 CLIRY * WRKCLI ;used by CLI decoder 0139 D8D0 ; 0140 D8D0 00E6 NUMBER * WRKCLI ;work slot for GETNUM 0141 D8D0 00E6 CSKEY * NUMBER ;current softkey number (must not share with KMASK or KQUOTE) 0142 D8D0 ; 0143 D8D0 00E6 FILEY * WRKCLI ;save area for register Y 0144 D8D0 00E6 EXECY * FILEY ;save area used by EXEC 0145 D8D0 0146 D8D0 00E6 SPOOLY * FILEY ;save area used by SPOOL 0147 D8D0 ;= NULL 0148 D8D0 0149 D8D0 00E6 # -1 0150 D8D0 00E5 FXREGX # &00 ;used by FX CLI command 0151 D8D0 00E5 KMASK # &00 ;used by GSREAD 0152 D8D0 ; must not be shared with CSKEY 0153 D8D0 ;= NULL 0154 D8D0 0155 D8D0 00E5 # -1 0156 D8D0 00E4 FXREGY # &00 ;used by FX CLI command 0157 D8D0 00E4 KQUOTE # &00 ;must not be shared with KMASK 0158 D8D0 ; must not be shared with CSKEY 0159 D8D0 ;= NULL 0160 D8D0 0161 D8D0 00E4 # -1 0162 D8D0 00E3 CFS1 # &00 ;reserved for CFS 0163 D8D0 0164 D8D0 00E3 # -1 0165 D8D0 ; 0166 D8D0 ; CFS workspace 0167 D8D0 ; ============= 0168 D8D0 ; 0169 D8D0 00E2 CFS0 # &00 ;reserved for CFS 0170 D8D0 00E2 CFSTAT * CFS0 0171 D8D0 ;PAGE ZERO 0172 D8D0 0173 D8D0 00B0 PZERO * &00B0 ;Start of p.0 workspace 0174 D8D0 0175 D8D0 00B0 BKADDR * PZERO ;4 BYTE BLOCK PTR. 0176 D8D0 00B4 HIADDR * BKADDR +&04 ;Top of data being saved, 0177 D8D0 ;Must be contiguous with BKADDR 0178 D8D0 0179 D8D0 00B4 BLOKNO * HIADDR 0180 D8D0 00B6 SRCHBK * BLOKNO +&02 ;Block numbers being searched for 0181 D8D0 ;Not used in SAVE, hence can overlap HIADDR 0182 D8D0 0183 D8D0 00B8 FTPTR * HIADDR +&04 ;Used in VSTRIN 0184 D8D0 00BA ERRSW * FTPTR +&02 ;In p.0 to save space 0185 D8D0 00BB USFLGS * ERRSW +&01 0186 D8D0 00BC TEMP * USFLGS +&01 0187 D8D0 00BD IBUF * TEMP +&01 0188 D8D0 00BE CHKSUM * IBUF +&01 0189 D8D0 00C0 IFLAG * CHKSUM +&02 0190 D8D0 00C1 HDRCRC * IFLAG +&01 0191 D8D0 00C2 ITYPE * HDRCRC +&01 0192 D8D0 00C3 CURDRV * ITYPE +&01 ;Currently selected cassette 0193 D8D0 00C4 IADDR * CURDRV +&01 0194 D8D0 00C6 SPEED * IADDR +&02 0195 D8D0 00C7 GAPTIM * SPEED +&01 0196 D8D0 00C8 GENPTR * GAPTIM +&01 ;Used in FILEGO/LOAD only 0197 D8D0 00CA TXFLAG * GENPTR +&02 ;"We are transmitting" flag 0198 D8D0 00CB CRCCNT * TXFLAG +&01 ;Used in CRC check 0199 D8D0 00CC FSIZE * CRCCNT + 1 ;File size to modify control block in LOAD 0200 D8D0 0201 D8D0 00E3 OPTS * CFS1 ;Retained over filing system change 0202 D8D0 ;************************************** 0203 D8D0 0204 D8D0 00E2 BPAGE0 # &00 0205 D8D0 0206 D8D0 0207 D8D0 0208 D8D0 IPAGE2 0209 D8D0 ; page two values 0210 D8D0 ^ &0200 0211 D8D0 0200 APAGE2 # &00 0212 D8D0 0200 USRVEC # &02 ;user vector 0213 D8D0 77 = BADFX 0214 D8D1 E3 = /(BADFX ) 0215 D8D2 0202 BRKVEC # &02 ;BRK handling 0216 D8D2 68 = DEFBRK 0217 D8D3 DB = /(DEFBRK ) 0218 D8D4 0204 IRQALL # &02 ;all IRQs indirect thru here 0219 D8D4 21 = DEFIRQ 0220 D8D5 DE = /(DEFIRQ ) 0221 D8D6 0206 IRQVEC # &02 ;unrecognised IRQ 0222 D8D6 33 = IRQTWO 0223 D8D7 DE = /(IRQTWO ) 0224 D8D8 0208 COMVEC # &02 ;command line intepreter 0225 D8D8 CF = CLINT 0226 D8D9 DF = /(CLINT ) 0227 D8DA 020A BYTVEC # &02 ;MOS routine, 0 1 or 2 arguments 0228 D8DA D5 = BYTE 0229 D8DB E7 = /(BYTE ) 0230 D8DC 020C WORVEC # &02 ;MOS routine, >2 arguments 0231 D8DC 3F = WORD 0232 D8DD E8 = /(WORD ) 0233 D8DE 020E WRCVEC # &02 ;write character 0234 D8DE 03 = WRCH 0235 D8DF E1 = /(WRCH ) 0236 D8E0 0210 RDCVEC # &02 ;read character 0237 D8E0 6F = RDCH 0238 D8E1 DE = /(RDCH ) 0239 D8E2 CFSTAB 0240 D8E2 0212 FILVEC # &02 ;load/save memory image 0241 D8E2 DA = FILEGO 0242 D8E3 F1 = /(FILEGO ) 0243 D8E4 0214 ARGVEC # &02 ;read/set file attributes 0244 D8E4 93 = ARGGO 0245 D8E5 F1 = /(ARGGO ) 0246 D8E6 0216 BGTVEC # &02 ;get byte from random file Acorn macro assembler Page 51 MOS32 Initialisation and external interfaces 0247 D8E6 C7 = GETBYT 0248 D8E7 F4 = /(GETBYT ) 0249 D8E8 0218 BPTVEC # &02 ;put byte to random file 0250 D8E8 2A = PUTBYT 0251 D8E9 F5 = /(PUTBYT ) 0252 D8EA 021A GPBVEC # &02 ;get/put bytes 0253 D8EA B2 = RTS 0254 D8EB FF = /(RTS ) 0255 D8EC 021C FNDVEC # &02 ;open/close random file 0256 D8EC C8 = FIND 0257 D8ED F3 = /(FIND ) 0258 D8EE 021E FSCVEC # &02 ;file system control entry 0259 D8EE A5 = FSFUNC 0260 D8EF F1 = /(FSFUNC ) 0261 D8F0 0220 EVTVEC # &02 ;event interrupt 0262 D8F0 B2 = DEFEVT 0263 D8F1 FF = /(DEFEVT ) 0264 D8F2 0222 UPTVEC # &02 ;user print routine 0265 D8F2 ; default hangs printer 0266 D8F2 B2 = DEFUPT 0267 D8F3 FF = /(DEFUPT ) 0268 D8F4 0224 NETVEC # &02 ;ECONET effects 0269 D8F4 ; default hangs printer 0270 D8F4 B2 = DEFNET 0271 D8F5 FF = /(DEFNET ) 0272 D8F6 0226 VDUVEC # &02 ;VDU command indirection 0273 D8F6 0274 D8F6 B2 = RTS 0275 D8F7 FF = /(RTS ) 0276 D8F8 0228 KEYVEC # &02 ;keyboard control indirection 0277 D8F8 39 = DEFKEY 0278 D8F9 EF = /(DEFKEY ) 0279 D8FA 022A INSVEC # &02 ;buffer insert indirection 0280 D8FA 19 = INS 0281 D8FB E5 = /(INS ) 0282 D8FC 022C REMVEC # &02 ;buffer remove indirection 0283 D8FC CA = REM 0284 D8FD E4 = /(REM ) 0285 D8FE 022E CNPVEC # &02 ;buffer count / purge buffer indirection 0286 D8FE 44 = CNP 0287 D8FF E2 = /(CNP ) 0288 D900 0230 INDONE # &02 0289 D900 B2 = RTS 0290 D901 FF = /(RTS ) 0291 D902 0232 INDTWO # &02 0292 D902 B2 = RTS 0293 D903 FF = /(RTS ) 0294 D904 0234 INDTRH # &02 0295 D904 B2 = RTS 0296 D905 FF = /(RTS ) 0297 D906 0036 VLEN * @-APAGE2 0298 D906 ; 0299 D906 001B NP2IND * VLEN:SHR: 1 ;number of page 2 indirections 0300 D906 0051 ROMIVS * NP2IND* 3 ;page ROM indirection vector size 0301 D906 0D9F ROMVEC * &0DF0-ROMIVS ;paged ROM routine vectors 0302 D906 0303 D906 0304 D906 0236 VARS # &00 0305 D906 ; 0306 D906 0236 # &02 ;variables origin 0307 D906 90 = VBASE ;166 0308 D907 01 = /(VBASE ) 0309 D908 0310 D908 0238 # &02 ;origin of 3-byte ROM indirection vectors 0311 D908 9F = ROMVEC ;168 0312 D909 0D = /(ROMVEC ) 0313 D90A 0314 D90A 023A # &02 ;paged ROM info 0315 D90A A1 = ROMS ;170 0316 D90B 02 = /(ROMS ) 0317 D90C 0318 D90C 023C # &02 ;keyboard matrix info 0319 D90C 58 = KTBL ;172 0320 D90D F0 = /(KTBL ) 0321 D90E 0322 D90E 023E # &02 ;VDU module origin of variables 0323 D90E 00 = VARBLE ;174 0324 D90F 03 = /(VARBLE ) 0325 D910 0326 D910 0240 CYCLE # &01 ;filing system timeout byte 0327 D910 0328 D910 00 = NULL 0329 D911 0330 D911 0241 RDCHSW # &01 ;RDCH source switch (assumed not in page zero, see KTBL) 0331 D911 00 = ZERO ;177 BRDCH (zero) 0332 D912 0333 D912 0242 KSEMA # &01 ;keyboard semaphore 0334 D912 FF = &FF ;178 0335 D913 0336 D913 0243 IHWM # &01 0337 D913 0338 D913 00 = ZERO ;179 0339 D914 0340 D914 0244 HWM # &01 0341 D914 0342 D914 00 = NULL ;180 0343 D915 0344 D915 0245 RS8BIT # &01 0345 D915 01 = &01 ;181 1 => 8 bits, 0 => soft key processing 0346 D916 0347 D916 0348 D916 0246 FONTSW # &01 ;current state of font explosion/implosion 0349 D916 0350 D916 00 = ZERO ;182 0351 D917 ; 0352 D917 0247 SROMSW # &01 ;SEROM/cassette switch 0353 D917 0354 D917 00 = ZERO ;183 cassette by default 0355 D918 0356 D918 0357 D918 0248 VPREGA # &01 ;video ULA control register 0 0358 D918 00 = NULL ;184 0359 D919 ; 0360 D919 0249 VPREGB # &01 ;video ULA control register 1 0361 D919 00 = NULL ;185 0362 D91A 0363 D91A 0364 D91A 024A REPROM # &01 ;ROM id after BRK 0365 D91A 00 = NULL ;186 0366 D91B ; 0367 D91B 024B BROMID # &01 ;BASIC ROM id Acorn macro assembler Page 52 MOS32 Initialisation and external interfaces 0368 D91B FF = &FF ;187 0369 D91C 0370 D91C 0371 D91C 024C ADCHAN # &01 ;ADC channel number 0372 D91C 04 = NADC ;188 0373 D91D ; 0374 D91D 024D MAXADC # &01 ;maximum ADC channel in use 0375 D91D 04 = NADC ;189 0376 D91E ; 0377 D91E 024E ADCCNV # &01 0378 D91E 00 = ZERO ;190 ADC conversion type (12 bits) 0379 D91F 0380 D91F 0381 D91F 024F RSFLAG # &01 ;RS423 use flag 0382 D91F 0383 D91F ; 1xxx xxxx => dormant 0384 D91F ; 0xxx xxxx => busy 0385 D91F FF = &FF ;191 0386 D920 ; 0387 D920 0250 RSCTFL # &01 0388 D920 0389 D920 56 = RSCDEF ;192 0390 D921 0391 D921 0392 D921 ; 0393 D921 0251 FLCNT # &01 ;flash period counter 0394 D921 19 = &19 ;193 1/2 SECOND 0395 D922 ; 0396 D922 0252 FLASHB # &00 ;used by flash FX calls 0397 D922 0252 FLSPC # &01 ;flash space period 0398 D922 19 = &19 ;194 1/2 SECOND 0399 D923 0253 FLMRK # &01 ;flash mark period 0400 D923 19 = &19 ;195 1/2 SECOND 0401 D924 ; 0402 D924 0403 D924 0404 D924 ;**** FOLLOWING MUST BE CONTIGUOUS (c.f. *FX11 and *FX12) **** 0405 D924 0254 FARSET # &01 ;first auto-repeat reset 0406 D924 32 = DAUTOD ;196 0407 D925 0255 ARSET # &01 ;reset for above 0408 D925 08 = DAUTOP ;197 0409 D926 0410 D926 0411 D926 0256 EXECH # &01 ;*EXEC handle 0412 D926 0413 D926 00 = ZERO ;198 0414 D927 ; 0415 D927 0257 SPOOLH # &01 ;*SPOOL handle 0416 D927 0417 D927 00 = ZERO ;199 0418 D928 ; 0419 D928 0258 CRIT # &01 ;critical region indicator 0420 D928 0421 D928 00 = &00 ;200 not within critical region 0422 D929 ; 0423 D929 0259 NETKDS # &01 ;net keyboard disable 0424 D929 00 = ZERO ;201 default: not disabled 0425 D92A ; 0426 D92A 025A KSTAT # &01 ;keyboard status (see MOS56) 0427 D92A 20 = SHFTL ;202 0428 D92B ; 0429 D92B 025B RSHLVL # &01 ;RS423 handshake level 0430 D92B 09 = RSOVR+&01 ;203 0431 D92C ; 0432 D92C 025C RSSHUT # &01 ;suppress RS423 input 0433 D92C 00 = ZERO ;204 default: enable RS423 input 0434 D92D ; 0435 D92D 025D RSCASS # &01 ;cassette/RS423 serial processor select 0436 D92D 00 = ZERO ;205 $00 => select RS423, $40 => select cassette 0437 D92E ; 0438 D92E 025E NETIOC # &01 ;net interception of OS calls 0439 D92E 00 = ZERO ;206 default: not intercepted 0440 D92F ; 0441 D92F 025F NETRDC # &01 ;net interception of RDCH 0442 D92F 00 = ZERO ;207 default: not intercepted 0443 D930 ; 0444 D930 0260 NETWRC # &01 ;net interception of WRCH 0445 D930 00 = ZERO ;208 default: not intercepted 0446 D931 ; 0447 D931 0261 SHUTSP # &01 ;speech suppressor 0448 D931 50 = SPOPSP ;209 0449 D932 ; 0450 D932 0262 SHUTUP # &01 ;sound suppressor 0451 D932 00 = ZERO ;210 allow sound by default 0452 D933 ; 0453 D933 0263 BELLC # &01 ;bell channel 0454 D933 03 = &03 ;211 0455 D934 ; 0456 D934 0264 BELLI # &01 ;bell envelope and chord information 0457 D934 90 = &90 ;212 0458 D935 ; 0459 D935 0265 BELLN # &01 ;bell frequency 0460 D935 64 = &64 ;213 0461 D936 ; 0462 D936 0266 BELLD # &01 ;bell duration 0463 D936 06 = &06 ;214 0464 D937 ; 0465 D937 0267 QUIET # &01 0466 D937 81 = &81 ;215 suppress start-up message / !BOOT option 0467 D938 ; 0468 D938 0268 SOFKL # &01 ;soft key string length 0469 D938 00 = ZERO ;216 0470 D939 ; 0471 D939 0269 LINES # &01 ;used by VDU software 0472 D939 0473 D939 00 = ZERO ;217 used by VDU software in page mode 0474 D93A ; 0475 D93A 026A QPOSN # &01 ;VDU queue count 0476 D93A 0477 D93A 00 = ZERO ;218 0478 D93B ; 0479 D93B 026B TABCOD # &01 ;TAB key code 0480 D93B 09 = TAB ;219 0481 D93C ; 0482 D93C 026C INTCH # &01 0483 D93C 1B = ESC ;220 interrupt character (normally ESC) 0484 D93D ; 0485 D93D 026D SOFTLO # &00 0486 D93D ;221 softkey 10 feature 0487 D93D 026D EXBREK # &01 0488 D93D 01 = &01 ;expand softkey Acorn macro assembler Page 53 MOS32 Initialisation and external interfaces 0489 D93E ;222 reserved 0490 D93E 026E # &01 0491 D93E D0 = &D0 0492 D93F ;223 reserved 0493 D93F 026F # &01 0494 D93F E0 = &E0 0495 D940 ;224 reserved 0496 D940 0270 # &01 0497 D940 F0 = &F0 0498 D941 ;225 0499 D941 ; 0 => enable softkey expansion on fnkey 0500 D941 ; N => return code N+i for fnkey(i), i=0..9 0501 D941 0271 # &01 0502 D941 01 = &01 ;return soft strings by default 0503 D942 ;226 0504 D942 ; 0 => enable softkey expansion on SHIFT/fnkey 0505 D942 ; N => return code N+i for SHIFT/fnkey(i), i=0..9 0506 D942 0272 # &01 0507 D942 80 = &80 ;return codes $80..$89 by default (user definable characters) 0508 D943 ;227 0509 D943 ; 0 => enable softkey expansion on CTRL/fnkey 0510 D943 ; N => return code N+i for CTRL/fnkey(i), i=0..9 0511 D943 0273 # &01 0512 D943 90 = &90 ;return codes $90..$99 by default (user definable characters) 0513 D944 ;228 0514 D944 ; 0 => enable softkey expansion on SHIFT/CTRL/fnkey 0515 D944 ; N => return code N+i for SHIFT/CTRL/fnkey(i), i=0..9 0516 D944 0274 # &01 0517 D944 00 = ZERO ;ingnore key combination by default 0518 D945 0519 D945 0275 ESCHAR # &01 ;make INTERRUPT CHARACTER return normal value 0520 D945 00 = ZERO ;229 <>0 => return normal value 0521 D946 0522 D946 0276 EAOPT # &01 ;suppress normal escape acknowledge actions 0523 D946 00 = ZERO ;230 suppress if <> 0 0524 D947 0525 D947 0277 B6522 # &01 ;$00 => no, $FF => second 6522 present 0526 D947 FFBYT 0527 D947 FF = &FF ;231 assume 6522B present 0528 D948 0529 D948 0278 C6850 # &01 ;$00 => no, $FF => 6850 present 0530 D948 FF = &FF ;232 assume 6850 present 0531 D949 0532 D949 0279 A6522 # &01 ;$00 => no, $FF => primary 6522 present 0533 D949 FF = &FF ;233 assume 6522A present 0534 D94A 0535 D94A 027A TUBEM # &01 ;$FF if tube present 0536 D94A 027A TUBE * TUBEM 0537 D94A 00 = ZERO ;234 assume tube not present 0538 D94B 0539 D94B 027B SPFLAG # &01 ;$FF if speech chip present 0540 D94B 00 = ZERO ;235 0541 D94C 0542 D94C 027C WRCHSW # &01 ;OSWRCH destinations flag 0543 D94C 0001 WRRS * &01 ;WRCH is RS423 0544 D94C 0002 WRVDU * &02 ;WRCH is ***NOT*** VDU 0545 D94C 0004 WRPREN * &04 ;0 => ENABLE PRINT 0546 D94C 0008 WRPRNT * &08 ;WRCH is ***NOT*** print 0547 D94C 0010 WRSPL * &10 ;WRCH is ***NOT*** spool 0548 D94C 0040 WRVDU1 * &40 ;WRCH to printer only by VDU1 0549 D94C 00 = ZERO ;236 WRCH is VDU/print/spool 0550 D94D ; ******** DO NOT ALTER ******** 0551 D94D 0552 D94D 027D CURSED # &01 0553 D94D 00 = ZERO ;237 0554 D94E 0555 D94E 007E MPAGE2 * @-APAGE2 0556 D94E 0557 D94E 027E SPARE8 # &03 0558 D94E 00 = ZERO 0559 D94F 00 = ZERO 0560 D950 00 = ZERO 0561 D951 ; 238, 239, 240 0562 D951 0563 D951 0281 UFX1 # &01 ;FX 1 value 0564 D951 00 = ZERO ;241 0565 D952 ; ******** DO NOT ALTER ******** 0566 D952 0567 D952 0282 SPREGA # &01 ;serial processor register contents 0568 D952 0569 D952 64 = B9600 ;242 0570 D953 0571 D953 0283 TIMESW # &01 ;TIME pointer, either 5 or 10 0572 D953 05 = &05 ;243 0573 D954 0574 D954 0284 USKFLG # &01 ;soft key consistency flag 0575 D954 FF = &FF ;244 =0 => soft keys consistent 0576 D955 0577 D955 0285 PRNTSW # &01 ;PRINT destination flag 0578 D955 0001 PCEN * &01 ;print is (C)ENTRONICS 0579 D955 0002 PRS * &02 ;print is (RS)232 0580 D955 0003 PUSE * &03 ;print is (user) routine 0581 D955 0004 PNET * &04 ;print is ECO(NET) 0582 D955 01 = PCEN ;245 0583 D956 ; ******** DO NOT ALTER ******** 0584 D956 0585 D956 0286 PIGNOR # &01 ;printer ignore character 0586 D956 0A = MLF ;246 support auto-linefeed printers by default 0587 D957 ; ******** DO NOT ALTER ******** 0588 D957 0589 D957 0087 PPAGE2 * @-APAGE2 0590 D957 0591 D957 0287 BREAKI # &03 ;used for interception of BREAK 0592 D957 00 = ZERO ;247 change to $4C to intercept BREAK 0593 D958 00 = ZERO ;248 0594 D959 00 = ZERO ;249 0595 D95A 0596 D95A 028A SPARE9 # &02 ;spare 0597 D95A 00 = ZERO ;250 0598 D95B 00 = ZERO ;251 0599 D95C 0600 D95C 028C LROMID # &01 ;current language ROM id 0601 D95C FF = &FF ;252 0602 D95D 0603 D95D 008D NPAGE2 * @-APAGE2 0604 D95D 0605 D95D 028D TYPE # &01 ;restart type 0606 D95D ;= ZERO ;253 0607 D95D 0608 D95D 028E MODELB # &01 0609 D95D 028E MODEL * MODELB Acorn macro assembler Page 54 MOS32 Initialisation and external interfaces 0610 D95D ;= ZERO ;254 0611 D95D 0612 D95D 028F OPTION # &01 ;start up options 0613 D95D ;= ZERO ;255 0614 D95D 0615 D95D 0190 VBASE * @-&100 0616 D95D 00A6 VORG * VARS-VBASE 0617 D95D [ VARS-VBASE- 166=0 0618 D95D | 0620 D95D ] 0621 D95D ; 0622 D95D 0623 D95D 0290 DPAGE2 # &00 0624 D95D 0625 D95D 0290 VERTIC # &01 ;VDU vertical adjust 0626 D95D 0627 D95D ;= ZERO 0628 D95D 0629 D95D 0291 INTERL # &01 ;interlace invert 0630 D95D 0631 D95D ;= ZERO 0632 D95D 0633 D95D ; time 0634 D95D 0292 TIME1 # &05 ;first absolute time counter 0635 D95D 0292 TIME * TIME1 0636 D95D ;= ZERO 0637 D95D ;= ZERO 0638 D95D ;= ZERO 0639 D95D ;= ZERO 0640 D95D ;= ZERO 0641 D95D 0297 TIME2 # &05 ;second absolute time counter 0642 D95D ;= ZERO 0643 D95D ;= ZERO 0644 D95D ;= ZERO 0645 D95D ;= ZERO 0646 D95D ;= ZERO 0647 D95D ; N.B. soft restart zeroes from here onwards 0648 D95D 029C STPW # &05 ;stopwatch counter 0649 D95D 029C CPAGE2 * STPW 0650 D95D ;= ZERO 0651 D95D ;= ZERO 0652 D95D ;= ZERO 0653 D95D ;= ZERO 0654 D95D ;= ZERO 0655 D95D 0656 D95D 02A1 ROMS # NROM 0657 D95D 0658 D95D ;= ZERO (NROM times) 0659 D95D 0660 D95D ; work slots used by CLI 0661 D95D 02B1 RDCTLO # &01 ;INKEY wait counter 1 0662 D95D ;= ZERO 0663 D95D 02B2 RDCTHI # &01 ;INKEY wait counter 2 0664 D95D ;= ZERO 0665 D95D 0666 D95D ; work slots used by RDLN 0667 D95D ; values must not be altered by any sei-routine 0668 D95D 02B3 RDLNN # &01 0669 D95D ;= NULL 0670 D95D 02B4 RDLNLC # &01 0671 D95D ;= NULL 0672 D95D 02B5 RDLNHC # &01 0673 D95D ;= NULL 0674 D95D 0675 D95D ; ADC control 0676 D95D ; may not be shared 0677 D95D 02B6 ADCLOV # NADC ;ADC lo byte values (0 to 3) 0678 D95D ;= ZERO 0679 D95D ;= ZERO 0680 D95D ;= ZERO 0681 D95D ;= ZERO 0682 D95D 02BA ADCHIV # NADC ;ADC hi byte values (0 to 3) 0683 D95D ;= ZERO 0684 D95D ;= ZERO 0685 D95D ;= ZERO 0686 D95D ;= ZERO 0687 D95D 02BE ADCFLG # &01 0688 D95D ;= ZERO 0689 D95D 0690 D95D ; event interrupt vectors 0691 D95D 000A NEVENT * &000A ;total number of events 0692 D95D 02BF EVENTS # NEVENT ;event flags 0693 D95D 0000 EVMPTY * &00 ;output buffer empty 0694 D95D ;= ZERO 0695 D95D 0001 EVFULL * &01 ;input buffer full 0696 D95D ;= ZERO 0697 D95D 0002 EVKYBD * &02 ;keyboard interrupt 0698 D95D ;= ZERO 0699 D95D 0003 EVADC * &03 ;ADC conversion complete 0700 D95D ;= ZERO 0701 D95D 0004 EVVSYN * &04 ;VSYNC 0702 D95D ;= ZERO 0703 D95D 0005 EVSWCH * &05 ;(timer) stopwatch 0704 D95D ;= ZERO 0705 D95D 0006 EVESC * &06 ;escape detected 0706 D95D ;= ZERO 0707 D95D 0007 EVRS * &07 ;RS423 Rx error 0708 D95D ;= ZERO 0709 D95D 0008 EVUSER * &08 ;user allocated event 0710 D95D ;= ZERO 0711 D95D 0712 D95D ; miscellaneous 0713 D95D 02C9 SOFKP # &01 ;pointer to soft key string 0714 D95D ;= NULL 0715 D95D ; 0716 D95D 02CA FARCTR # &01 ;first auto-repeat count 0717 D95D ;= NULL 0718 D95D 0719 D95D 02CB KSCSTA # &03 ;keyboard scan start address work vector 0720 D95D ;= NULL 0721 D95D 0722 D95D ; values to be initialised to $FF 0723 D95D 02CE FFBYTE # &00 0724 D95D ; 0725 D95D 02CE SSEMA # &01 ;sound semaphore 0726 D95D ; 0727 D95D ; buffer activity flags 0728 D95D 02CF BACTIV # &00 0729 D95D 02CF DUMMY # 3 ;Not used - necessary for padding (see PURGE) 0730 D95D 02D2 PFLAG # &01 ;print flag 0731 D95D ; 1xxx xxxx => dormant Acorn macro assembler Page 55 MOS32 Initialisation and external interfaces 0732 D95D ; 0xxx xxxx => busy 0733 D95D 02D3 SFLUSH # &04 ;sound flush flags 0734 D95D 02D7 SPSTAT # &01 ;speech processor status 0735 D95D ; 0736 D95D ; buffer control 0737 D95D ; buffer start page offsets 0738 D95D 02D8 BFSTRT # BUPB+&01 0739 D95D ; buffer end page offsets 0740 D95D 02E1 BFEND # BUPB+&01 0741 D95D ; 0742 D95D 02EA CFSA # &03 0743 D95D 0744 D95D ; 0745 D95D 02ED CFSD # &01 0746 D95D 0747 D95D 02EE FBLOCK # &12 ;load/save control block 0748 D95D 0000 FSTR * &0000 ;pointer to filename (2 bytes) 0749 D95D 0002 FLOAD * &0002 ;load address (4 bytes) 0750 D95D 0006 FEXEC * &0006 ;execute address (4 bytes) 0751 D95D 000A FFROM * &000A ;from address (4 bytes) 0752 D95D 000E FTO * &000E ;to address (4 bytes) 0753 D95D ;= 18*NULL 0754 D95D 0755 D95D 0300 ZPAGE2 # &00 0756 D95D 0757 D95D LNK MOS34 0001 D95D 0002 D95D ; MOS34 0003 D95D TTL MOS34 Initialisation 0004 D95D OPT MOS34 Acorn macro assembler Page 56 MOS34 Initialisation 0005 D95D 0006 D95D ;(c) 1981 ACORN Computers Limited 0007 D95D ;BBC Microcomputer MOS 0008 D95D 0009 D95D ;Change record: 0010 D95D ;100 15-Apr-82 PB Use PCEN=1 0011 D95D ;039 15-Aug-81 PB Start of change to PROTON interface 0012 D95D ;004 29-Jul-81 MP Prototype version 0013 D95D 0014 D95D ;Author(s): 0015 D95D ;PB Paul Bond 0016 D95D ;MP Mike Prees 0017 D95D TTL Entry point after hardware break/reset 0018 D95D OPT OPNEWP Acorn macro assembler Page 57 Entry point after hardware break/reset 0019 D95D 0020 D95D 0021 D95D MRESET ;entered here after reset 0022 D95D 0023 D95D ; ensure NMIs are ignored as sson as possible 0024 D95D ; 0025 D95D A9 40 LDAIM &40 ;A := RTI opcode 0026 D95F 8D 00 0D STA NMI 0027 D962 0028 D962 ; ensure interrupts disabled (useful for JMP -4 freaks) 0029 D962 ; 0030 D962 78 SEI 0031 D963 0032 D963 ; clear decimal mode 0033 D963 ; 0034 D963 D8 CLD 0035 D964 0036 D964 ; reset stack 0037 D964 ; 0038 D964 A2 FF LDXIM &FF 0039 D966 9A TXS 0040 D967 0041 D967 ; push hard reset status 0042 D967 ; 0043 D967 AD 4E FE LDA IERQ 0044 D96A 0A ASLA 0045 D96B 48 PHA ;A=0 => hard, A<>0 => soft 0046 D96C F0 09 BEQ HRDRST ;[hard reset, A=0] 0047 D96E ; 0048 D96E ; prepare for possible soft reset 0049 D96E ; 0050 D96E ; check for critical region 0051 D96E ; 0052 D96E AD 58 02 LDA CRIT 0053 D971 4A LSRA 0054 D972 C9 01 CMPIM &01 0055 D974 D0 38 BNE SFTRST ;[not within a critical region] 0056 D976 ; A=1 0057 D976 4A LSRA 0058 D977 ; A=0 0059 D977 ; 0060 D977 ; within a critical region - clear store 0061 D977 ; 0062 D977 HRDRST ;hard reset 0063 D977 ; A=0 0064 D977 ; hard reset 0065 D977 ; clear store 0066 D977 [ MOS125 = &FF 0092 D977 ] 0093 D977 0094 D977 [ MOS125 = &7F 0095 D977 A2 04 LDXIM &04 ;start clearing at page 4 0096 D979 A8 TAY ;Y := 0 0097 D97A 85 00 STA &0000 0098 D97C CLRPG 0099 D97C 86 01 STX &0001 0100 D97E C8 INY 0101 D97F 91 00 STAIY &0000 ;saves 163 ms 0102 D981 E4 01 CPX &0001 0103 D983 D0 23 BNE CLEAR0 ;[16K RAM] 0104 D985 E8 INX 0105 D986 E0 0D CPXIM /(NMI ) 0106 D988 85 F2 STA WORK 0107 D98A 86 F3 STX WORK+1 0108 D98C F0 06 BEQ CLEARA ;leave RTI in place 0109 D98E 88 DEY ;otherwise Y=0 0110 D98F 0111 D98F ; clear store to $00 (no blobs on screen) 0112 D98F ; done: 0000 even . 0 . . 0113 D98F ; X WORK odd x . . . 0114 D98F ; Y 0115 D98F CLEAR 0116 D98F 91 F2 STAIY WORK ;saves 4 ms 0117 D991 C8 INY ;1 0118 D992 91 00 STAIY &0000 0119 D994 CLEARA 0120 D994 91 F2 STAIY WORK ;saves 4 ms 0121 D996 C8 INY ;2 0122 D997 91 00 STAIY &0000 ;saves 24 ms 0123 D999 91 F2 STAIY WORK ;saves 4 ms 0124 D99B C8 INY ;3 0125 D99C 91 00 STAIY &0000 ;saves 8 ms 0126 D99E 91 F2 STAIY WORK ;saves 4 ms 0127 D9A0 C8 INY ;0 0128 D9A1 91 00 STAIY &0000 ;saves 4 ms 0129 D9A3 D0 EA BNE CLEAR 0130 D9A5 E8 INX 0131 D9A6 10 D4 BPL CLRPG 0132 D9A8 ; 32K RAM 0133 D9A8 ; 0134 D9A8 CLEAR0 0135 D9A8 ; $0001 = $80 (model B) or $40 (model A) 0136 D9A8 8E 8E 02 STX MODELB 0137 D9AB ; 0138 D9AB ; force soft keys reset 0139 D9AB 8E 84 02 STX USKFLG ;USKFLG := non-zero 0140 D9AE ] 0141 D9AE 0142 D9AE [ MOS125 = &00 0169 D9AE ] 0170 D9AE 0171 D9AE ; 0172 D9AE SFTRST 0173 D9AE ; 0174 D9AE ; initialise addressable latch outputs hi 0175 D9AE ; 0176 D9AE A2 0F LDXIM &0F ;for latch driving 0177 D9B0 8E 42 FE STX DDRBQ ;set PB3-PB0 as outputs to drive addressable latch 0178 D9B3 ; 0179 D9B3 IALTCH 0180 D9B3 CA DEX 0181 D9B4 8E 40 FE STX PBQ ;first store value = $0E, last store value = $08 0182 D9B7 E0 09 CPXIM &09 0183 D9B9 B0 F8 BCS IALTCH 0184 D9BB ; fall thru when X=$08 0185 D9BB 0186 D9BB 0187 D9BB ; check for hard restart 0188 D9BB ; 0189 D9BB ; read start-up options 0190 D9BB ; Acorn macro assembler Page 58 Entry point after hardware break/reset 0191 D9BB E8 INX ;X := $09, scan down from last start-up option 0192 D9BC ; 0193 D9BC RDOPT1 0194 D9BC 8A TXA ;save X in A 0195 D9BD 20 57 F0 JSR KC ;read state of matrix element addressed by X (A maintained) 0196 D9C0 ; 0197 D9C0 ; N.B. does not corrupt A 0198 D9C0 ; 0199 D9C0 E0 80 CPXIM &80 ;C=0 => option open, C=1 => option closed 0200 D9C2 66 FC ROR TEMPA ;rotate state of start-up option into TEMPA byte 0201 D9C4 AA TAX ;restore X 0202 D9C5 CA DEX 0203 D9C6 D0 F4 BNE RDOPT1 ;execute loop 9 times 0204 D9C8 ; 0205 D9C8 ; N.B. exits with X=0, SHIFT key has not been scanned 0206 D9C8 ; state of CTRL key has been rotated into TEMPA 0207 D9C8 ; 0208 D9C8 8E 8D 02 STX TYPE ;restart type := 0 0209 D9CB 26 FC ROL TEMPA ;C = state of CTRL key, TEMPA = start-up options 0210 D9CD 20 22 EF JSR KBDIS ;disable keyboard (and resume hardware scan) 0211 D9D0 ; 0212 D9D0 6A RORA ;C=1 => CTRL pressed (KBDIS does PHP ... PLA) 0213 D9D1 ; 0214 D9D1 A2 9C LDXIM CPAGE2 ;(do not set to reset timer if soft restart) 0215 D9D3 A0 8D LDYIM NPAGE2 ;reset BREAKI if power up 0216 D9D5 68 PLA ;pull hard restart status 0217 D9D6 F0 09 BEQ POWER ;[power up] 0218 D9D8 ; 0219 D9D8 A0 7E LDYIM MPAGE2 ;prepare for BREAK 0220 D9DA 90 11 BCC SOFT ;[CTRL not pressed - force soft reset, b1b0(TYPE) := 0] 0221 D9DC ; 0222 D9DC ; b1b0(TYPE) := 2 0223 D9DC ; 0224 D9DC A0 87 LDYIM PPAGE2 ;CTRL/BREAK 0225 D9DE EE 8D 02 INC TYPE 0226 D9E1 ; 0227 D9E1 POWER ;power up, b1b0(TYPE) := 1 0228 D9E1 ;HARD ;hard restart 0229 D9E1 EE 8D 02 INC TYPE 0230 D9E4 ; 0231 D9E4 ; initialise OPTION 0232 D9E4 ; 0233 D9E4 A5 FC LDA TEMPA 0234 D9E6 49 FF EORIM &FF ;invert VDU mode selection 0235 D9E8 8D 8F 02 STA OPTION 0236 D9EB ; 0237 D9EB A2 90 LDXIM DPAGE2 ;set to reset timer 0238 D9ED 0239 D9ED 0240 D9ED SOFT 0241 D9ED ; initialise other page two locations to zero/$FF 0242 D9ED ; N.B. X has been set to an appropriate value 0243 D9ED A9 00 LDAIM ZERO 0244 D9EF IP0SX 0245 D9EF E0 CE CPXIM FFBYTE 0246 D9F1 [ MOS125 = &FF 0249 D9F1 | 0250 D9F1 D0 07 BNE Z0BYTE 0251 D9F3 A9 FF LDAIM &FF 0252 D9F5 8D CE 02 STA SSEMA 0253 D9F8 A2 D2 LDXIM PFLAG 0254 D9FA ] 0255 D9FA Z0BYTE 0256 D9FA 9D 00 02 STAAX &0200 0257 D9FD E8 INX 0258 D9FE D0 EF BNE IP0SX 0259 DA00 ; N.B. A=$FF, X=0 0260 DA00 8D 63 FE STA DDRAR ;set all outputs on printer data direction register (6522B) 0261 DA03 0262 DA03 0263 DA03 ; initialise page zero locations to zero 0264 DA03 ; 0265 DA03 8A TXA ;A := 0 0266 DA04 A2 E2 LDXIM BPAGE0 0267 DA06 IP0SW 0268 DA06 95 00 STAAX ZERO 0269 DA08 E8 INX 0270 DA09 D0 FB BNE IP0SW 0271 DA0B ; X=0 0272 DA0B 0273 DA0B 0274 DA0B ; initialise page two specific values 0275 DA0B ; 0276 DA0B IP2SV 0277 DA0B B9 CF D8 LDAAY IPAGE2 -&01 0278 DA0E 99 FF 01 STAAY APAGE2 -&01 0279 DA11 88 DEY 0280 DA12 D0 F7 BNE IP2SV 0281 DA14 ; Y=0 0282 DA14 0283 DA14 0284 DA14 ; make old key space in case CFS auto-boot selected 0285 DA14 ; 0286 DA14 A9 62 LDAIM &62 0287 DA16 85 ED STA OKEY 0288 DA18 ; X=0, Y=0 0289 DA18 0290 DA18 0291 DA18 ; setup MC6850 0292 DA18 ; 0293 DA18 20 FF FA JSR MC6850 ;N.B. does not corrupt X or Y 0294 DA1B ; X=0, Y=0 0295 DA1B 0296 DA1B 0297 DA1B ; clear any 6522 interrupt status 0298 DA1B ; 0299 DA1B A9 7F LDAIM &7F 0300 DA1D E8 INX ;X=1 0301 DA1E IFRIER ;X=1 initialises IERQ&IERR, X=0 initialises IFRQ&IFRR 0302 DA1E 9D 4D FE STAAX IFRQ 0303 DA21 9D 6D FE STAAX IFRR 0304 DA24 CA DEX 0305 DA25 10 F7 BPL IFRIER ;[execute loop once more with X=0] 0306 DA27 ; X=$FF 0307 DA27 ; 0308 DA27 [ FALSE=0 0311 DA27 ] 0312 DA27 0313 DA27 ; TEMPA is now 0 0314 DA27 ; if an interrupt occurs it will adopt the value $7F 0315 DA27 ; Acorn macro assembler Page 59 Entry point after hardware break/reset 0316 DA27 ; allow test equipment to interrupt if present 0317 DA27 ; 0318 DA27 58 CLI 0319 DA28 ; ** TEST EQUIPMENT INTERRUPT MAY OCCUR HERE ** 0320 DA28 78 SEI 0321 DA29 ; 0322 DA29 24 FC BIT TEMPA 0323 DA2B 50 03 BVC NOTST1 0324 DA2D ; C=0 0325 DA2D 20 82 F0 JSR JMITST ;enter test routine (first call) 0326 DA30 NOTST1 0327 DA30 0328 DA30 0329 DA30 [ FALSE=0 0348 DA30 ] 0349 DA30 0350 DA30 0351 DA30 ; initialise 6522s 0352 DA30 ; 0353 DA30 A2 F2 LDXIM &F2 ;enable TIMER1(clock,40), TIMER2(speech,20) 0354 DA32 ; CB1(ADC,10), CA1(VSYNC,02) and NOT[CA2(keyboard,01)] 0355 DA32 8E 4E FE STX IERQ 0356 DA35 0357 DA35 0358 DA35 ; initialise peripheral control register 0359 DA35 ; 0360 DA35 A2 04 LDXIM &04 0361 DA37 8E 4C FE STX PCRQ ;select CA2 positive active edge 0362 DA3A 0363 DA3A 0364 DA3A ; setup centisecond timer 0365 DA3A ; 0366 DA3A A9 60 LDAIM &60 ;TIMER1 continuous, TIMER2 count pulses on PB6 0367 DA3C 8D 4B FE STA ACRQ 0368 DA3F 0369 DA3F 0370 DA3F ; N.B. ACRR zeroed by reset 0371 DA3F ; 0372 DA3F ; set timer hi-byte 0373 DA3F ; 0374 DA3F A9 0E LDAIM &0E ;timer 1 period = 998 usec 0375 DA41 8D 46 FE STA TQLLQ 0376 DA44 8D 6C FE STA PCRR ;set CA2 hi (for printer) 0377 DA47 ; 0378 DA47 ; start conversion on analog/digital chip 0379 DA47 ; 0380 DA47 8D C0 FE STA ADCCTL ;12 bits from chip channel 2 0381 DA4A 0382 DA4A 0383 DA4A ; check whether 6522B present 0384 DA4A ; 0385 DA4A CD 6C FE CMP PCRR 0386 DA4D F0 03 BEQ B6522E ;[6522B exists] 0387 DA4F ; 0388 DA4F ; 6522B does not exist 0389 DA4F ; 0390 DA4F EE 77 02 INC B6522 ;B6522 := $00 0391 DA52 B6522E 0392 DA52 ; 0393 DA52 ; set timer lo-byte 0394 DA52 ; 0395 DA52 A9 27 LDAIM &27 0396 DA54 8D 47 FE STA TQLHQ 0397 DA57 8D 45 FE STA TQCHQ 0398 DA5A 0399 DA5A 0400 DA5A ; kill sound 0401 DA5A ; 0402 DA5A 20 A4 EC JSR SNDRST 0403 DA5D 0404 DA5D 0405 DA5D ; ensure motor off 0406 DA5D ; reinitialise serproc 0407 DA5D ; 0408 DA5D AD 82 02 LDA SPREGA 0409 DA60 29 7F ANDIM &7F 0410 DA62 20 0B E7 JSR STASP ;STA SPREGA, STA SERPRC 0411 DA65 ; X, Y corrupted 0412 DA65 0413 DA65 0414 DA65 ; conditionally reset soft keys 0415 DA65 ; soft keys are reset 0416 DA65 ; (a) after a hard reset 0417 DA65 ; (b) if reset occurred during a critical update of the soft keys 0418 DA65 ; 0419 DA65 AE 84 02 LDX USKFLG 0420 DA68 F0 03 BEQ SKOK 0421 DA6A 20 EF E9 JSR RSOFT ;reset soft keys, sets X=0 0422 DA6D SKOK 0423 DA6D ; X=0 0424 DA6D 0425 DA6D 0426 DA6D ; compare ROMs 0427 DA6D ; 0428 DA6D CRX 0429 DA6D 20 D9 DB JSR STXROM ;select ROM 0430 DA70 ; 0431 DA70 ; check for copyright string 0432 DA70 ; 0433 DA70 A2 03 LDXIM &03 0434 DA72 AC 07 80 LDY COPYRP 0435 DA75 CRCPYR 0436 DA75 B9 00 80 LDAAY LANG 0437 DA78 DD 21 F5 CMPAX COPYR 0438 DA7B D0 2E BNE CRBAD 0439 DA7D C8 INY 0440 DA7E CA DEX 0441 DA7F 10 F4 BPL CRCPYR 0442 DA81 ; 0443 DA81 ; ROM has copyright string 0444 DA81 ; 0445 DA81 A6 F4 LDX ROMID 0446 DA83 A4 F4 LDY ROMID 0447 DA85 CRY 0448 DA85 C8 INY 0449 DA86 C0 10 CPYIM NROM 0450 DA88 B0 25 BCS CRNX ;[Y > number of ROMs] 0451 DA8A 98 TYA 0452 DA8B 49 FF EORIM &FF 0453 DA8D 85 FA STA CRLO 0454 DA8F A9 7F LDAIM &7F ;N.B. this is LANG / - 1 Acorn macro assembler Page 60 Entry point after hardware break/reset 0455 DA91 85 FB STA CRHI 0456 DA93 CRLOOP 0457 DA93 8C 30 FE STY ROM ;select second (Y) ROM 0458 DA96 B1 FA LDAIY CRLO 0459 DA98 8E 30 FE STX ROM ;select first (X) ROM 0460 DA9B D1 FA CMPIY CRLO 0461 DA9D D0 E6 BNE CRY ;[ROMs do not match] 0462 DA9F E6 FA INC CRLO 0463 DAA1 D0 F0 BNE CRLOOP 0464 DAA3 E6 FB INC CRHI 0465 DAA5 A5 FB LDA CRHI 0466 DAA7 C9 84 CMPIM &84 ;compare only first 1K of ROMs 0467 DAA9 90 E8 BCC CRLOOP 0468 DAAB ; ROMs match 0469 DAAB CRBAD 0470 DAAB A6 F4 LDX ROMID 0471 DAAD 10 0D BPL CRNX1 ;[ALWAYS jump] 0472 DAAF ; NEVER fall thru 0473 DAAF ; 0474 DAAF CRNX 0475 DAAF AD 06 80 LDA ROMTYP 0476 DAB2 9D A1 02 STAAX ROMS ;store type of recognised ROM 0477 DAB5 ; check for BASIC ROM 0478 DAB5 ;***** N.B. WHITE BASIC MAY NEED 'ANDIM $FE' ***** 0479 DAB5 29 8F ANDIM &8F 0480 DAB7 D0 03 BNE CRNX1 ;[not a BASIC ROM] 0481 DAB9 ; BASIC ROM - remember ROM id for *BASIC command 0482 DAB9 8E 4B 02 STX BROMID 0483 DABC CRNX1 0484 DABC E8 INX 0485 DABD E0 10 CPXIM NROM 0486 DABF 90 AC BCC CRX ;[X a valid ROM number] 0487 DAC1 0488 DAC1 [ NOSP = &00 0490 DAC1 | 0491 DAC1 ; X=NROM 0492 DAC1 ; 0493 DAC1 ; if speech chip ready is still high then the chip has not been fitted 0494 DAC1 ; 0495 DAC1 2C 40 FE BIT PBQ 0496 DAC4 30 11 BMI START1 ;[chip does not exist] 0497 DAC6 ; X=NROM 0498 DAC6 ; speech chip present 0499 DAC6 ; 0500 DAC6 CE 7B 02 DEC SPFLAG ;SPFLAG := $FF 0501 DAC9 ; X=NROM 0502 DAC9 ; reset speech processor 0503 DAC9 ; 0504 DAC9 ; write NROM * $FF (reset) to speech processor 0505 DAC9 SPRST1 0506 DAC9 A0 FF LDYIM SPOPRT 0507 DACB 20 B9 EE JSR WSPECH ;N.B. corrupts A and Y 0508 DACE CA DEX 0509 DACF D0 F8 BNE SPRST1 0510 DAD1 ; X=0 0511 DAD1 ; 0512 DAD1 8E 48 FE STX TRCLQ 0513 DAD4 8E 49 FE STX TRCHQ ;enable interrupt after one negative pulse on PB6 (speech int) 0514 DAD7 ] 0515 DAD7 0516 DAD7 START1 0517 DAD7 0518 DAD7 0519 DAD7 AD 8F 02 LDA OPTION ;initialise graphics mode from start-up options 0520 DADA 20 00 C3 JSR VDINIT ;initialise VDU module 0521 DADD 0522 DADD 0523 DADD ; set up reset soft key (fA) 0524 DADD ; 0525 DADD A0 CA LDYIM BREKEY 0526 DADF 20 56 E5 JSR RDCHS ;set to expand softkeyA immediately 0527 DAE2 ; C=0 cos buffer empty 0528 DAE2 ; 0529 DAE2 ; let user intercept BREAK 0530 DAE2 ; 0531 DAE2 ; C=0 0532 DAE2 20 43 EB JSR BREAK 0533 DAE5 ; 0534 DAE5 ; initialise CFS state 0535 DAE5 ; 0536 DAE5 20 3E F1 JSR INIT 0537 DAE8 ; 0538 DAE8 ; check for tube 0539 DAE8 ; 0540 DAE8 A9 81 LDAIM &81 0541 DAEA 8D E0 FE STA TREG0 0542 DAED AD E0 FE LDA TREG0 0543 DAF0 6A RORA 0544 DAF1 90 0A BCC NOTUBE ;[tube not present] 0545 DAF3 ; 0546 DAF3 ; tube present 0547 DAF3 ; 0548 DAF3 A2 FF LDXIM SVTUBE 0549 DAF5 20 6F F1 JSR SVOP ;initialise tube 0550 DAF8 D0 03 BNE NOTUBE ;[tube software not present] 0551 DAFA CE 7A 02 DEC TUBEM ;TUBEM := $FF 0552 DAFD NOTUBE 0553 DAFD ; 0554 DAFD ; initialise service ROMs before writing to screen 0555 DAFD ; 0556 DAFD A0 0E LDYIM /(OSHWM ) ;Y := default high water mark 0557 DAFF ; 0558 DAFF A2 01 LDXIM SVSTAT ;offer static area 0559 DB01 20 6F F1 JSR SVOP 0560 DB04 ; 0561 DB04 A2 02 LDXIM SVDYN ;offer dynamic area 0562 DB06 20 6F F1 JSR SVOP 0563 DB09 ; 0564 DB09 8C 43 02 STY IHWM ;save adjusted high water mark 0565 DB0C 8C 44 02 STY HWM ;save adjusted high water mark 0566 DB0F ; 0567 DB0F ; allow tube post-initialisation (e.g. exploding font) 0568 DB0F ; 0569 DB0F A2 FE LDXIM SVTPIN ;******** ASSUMED = $FE ******** 0570 DB11 AC 7A 02 LDY TUBEM ;pass tube flag as argument 0571 DB14 20 6F F1 JSR SVOP 0572 DB17 ; A=$00 (tube present) 0573 DB17 ; A=$FF (tube not present) 0574 DB17 ; 0575 DB17 ; conditionally output start-up message 0576 DB17 ; 'BBC Computer' Acorn macro assembler Page 61 Entry point after hardware break/reset 0577 DB17 ; 0578 DB17 2D 67 02 AND QUIET ;may be set by paged ROM 0579 DB1A 10 1B BPL ENTER ;[shshh ... you know who] 0580 DB1C ; 0581 DB1C ; output start up message 0582 DB1C ; 0583 DB1C A0 02 LDYIM MSGBBC-&01 0584 DB1E 20 53 DE JSR WRSTR 0585 DB21 ; 0586 DB21 ; indicate model type 0587 DB21 ; 0588 DB21 AD 8D 02 LDA TYPE 0589 DB24 F0 0C BEQ Z ;[soft restart] 0590 DB26 ; 0591 DB26 ; hard restart 0592 DB26 ; complete message 0593 DB26 ; 0594 DB26 A0 16 LDYIM MSG32K-&01 0595 DB28 2C 8E 02 BIT MODELB 0596 DB2B 30 02 BMI B ;[model B] 0597 DB2D ; 0598 DB2D ; model A 0599 DB2D ; 0600 DB2D A0 11 LDYIM MSG16K-&01 0601 DB2F B 0602 DB2F 20 53 DE JSR WRSTR 0603 DB32 Z 0604 DB32 A0 1B LDYIM MSG2CR-&01 0605 DB34 20 53 DE JSR WRSTR 0606 DB37 ; 0607 DB37 ENTER ;initialise TAPE/DISC 0608 DB37 ; 0609 DB37 ; let user intercept BREAK after filing system initialisation 0610 DB37 ; 0611 DB37 38 SEC 0612 DB38 20 43 EB JSR BREAK 0613 DB3B ; 0614 DB3B ; service ROMs again 0615 DB3B ; test for auto-boot condition (SHIFT and startup option bit3) 0616 DB3B ; 0617 DB3B 20 00 EA JSR MOSTST ;test shift 0618 DB3E [ MOS125 = &FF 0621 DB3E | 0622 DB3E ;Slightly iffy using A directly as no other callers of MOSTST do 0623 DB3E ;however MOSTST always returns SHIFT state in both N and A b7 0624 DB3E ] 0625 DB3E 4A LSRA 0626 DB3F 4A LSRA 0627 DB40 4A LSRA 0628 DB41 4A LSRA 0629 DB42 4D 8F 02 EOR OPTION 0630 DB45 29 08 ANDIM &08 ;use bit3 0631 DB47 A8 TAY ;Y=0 => auto-boot, Y<>0 => do not auto-boot 0632 DB48 A2 03 LDXIM SVBOOT ;offer bootstrap 0633 DB4A 20 6F F1 JSR SVOP 0634 DB4D F0 30 BEQ SLANG ;[file system booted] 0635 DB4F ; 0636 DB4F ; file system not booted - try to auto-boot from SEROM 0637 DB4F ; 0638 DB4F 98 TYA 0639 DB50 D0 27 BNE NOAUTO ;[do not auto boot] 0640 DB52 ; 0641 DB52 ; auto-boot from SEROM 0642 DB52 ; 0643 DB52 A9 8D LDAIM FXSROM 0644 DB54 20 4A F1 JSR CROM ;'*ROM' 0645 DB57 A2 3C LDXIM SLBOOT 0646 DB59 A0 EB LDYIM /(SLBOOT ) 0647 DB5B CE 67 02 DEC QUIET ;flag as loading auto-boot program 0648 DB5E 20 F7 FF JSR OSCLI ;'/!BOOT' 0649 DB61 EE 67 02 INC QUIET ;flag as not loading auto-boot program 0650 DB64 ; if an error occurs whilst running the !BOOT program 0651 DB64 ; then the MOS jumps to EBRK (early BRK) 0652 DB64 D0 19 BNE DNRFS ;[ALWAYS jump, do not reset filing system] 0653 DB66 ; 0654 DB66 [ MOS125 = &FF 0655 DB66 | 0656 DB66 ;Restoring OS 1.20 behaviour: 0657 DB66 ;*FX215,0 by early birds (or *FX215,255 by RFS !BOOT) 0658 DB66 ;forces *TAPE12 on successful completion of RFS !BOOT 0659 DB66 ;with no error message printed 0660 DB66 F0 11 BEQ NOAUTO 0661 DB68 ;NEVER fall through 0662 DB68 0663 DB68 DEFBRK ;default BRK routine outputs error message 0664 DB68 ; assume still decimal mode 0665 DB68 A0 00 LDYIM ZERO 0666 DB6A 20 5B DE JSR WRSTR1 ;output error message 0667 DB6D ; check whether within auto-boot program 0668 DB6D AD 67 02 LDA QUIET 0669 DB70 6A RORA 0670 DB71 STOP 0671 DB71 B0 FE BCS STOP ;hang if not within auto-boot program 0672 DB73 20 E7 FF JSR OSNEWL 0673 DB76 20 E7 FF JSR OSNEWL ;place 2*CR/LF after error message 0674 DB79 ;fall through 0675 DB79 ] 0676 DB79 0677 DB79 NOAUTO 0678 DB79 EBRK ;unexpected (early) BRK (e.g. 'File not found') 0679 DB79 ; 0680 DB79 ; initialise cassette filing system (CFS) 0681 DB79 ; 0682 DB79 A9 00 LDAIM ZERO ;select CFS 0683 DB7B AA TAX ;X:=0, select default baudrate (1200 baud) 0684 DB7C 20 4C F1 JSR TAPE12 ;initialise CFS 0685 DB7F ; 0686 DB7F DNRFS ;do not reset filing system 0687 DB7F ; 0688 DB7F SLANG ;select a language ROM to enter 0689 DB7F AD 8D 02 LDA TYPE 0690 DB82 D0 05 BNE SLANG1 ;[hard restart - use same language as last time] 0691 DB84 ; 0692 DB84 ; soft restart - ensure language exists 0693 DB84 ; A b0=0 used by ILR2 enter ROM with C=0 0694 DB84 ; 0695 DB84 AE 8C 02 LDX LROMID 0696 DB87 10 1E BPL ILR2 ;[language does exist] 0697 DB89 ; 0698 DB89 SLANG1 ;find first language ROM 0699 DB89 ; Acorn macro assembler Page 62 Entry point after hardware break/reset 0700 DB89 A2 0F LDXIM NROM-&1 0701 DB8B ILR1 0702 DB8B BD A1 02 LDAAX ROMS 0703 DB8E [ MOS125 = &FF 0705 DB8E | 0706 DB8E 0A ASLA ;b0=0 used by ILR2 enter ROM with C=0 0707 DB8F ] 0708 DB8F 30 16 BMI ILR2 ;[found language ROM] 0709 DB91 ; 0710 DB91 CA DEX 0711 DB92 10 F7 BPL ILR1 ;[continue search for language ROM] 0712 DB94 ; 0713 DB94 A9 00 LDAIM LGNONE 0714 DB96 2C 7A 02 BIT TUBEM 0715 DB99 30 30 BMI TLANG ;[tube active] 0716 DB9B ; neither language nor tube present 0717 DB9B 00 BRK 0718 DB9C F9 = NOLROM 0719 DB9D 4C 61 6E = "Language?" 0720 DBA6 00 = ZERO 0721 DBA7 ; 0722 DBA7 [ MOS125 = &FF 0725 DBA7 | 0726 DBA7 ILR2 ;*BASIC enters with A b0=1 indicate manual entry 0727 DBA7 4A LSRA ;C=0 indicate to tube that this is a restart 0728 DBA8 ] 0729 DBA8 SELANG ;FX entry point, entered with C=1 (for tube) 0730 DBA8 ; found language ROM 0731 DBA8 ; select language ROM 0732 DBA8 08 PHP ;save entry type (present in C) 0733 DBA9 [ MOS125 = &FF 0735 DBA9 ] 0736 DBA9 20 D9 DB JSR STXROM 0737 DBAC ; output ROM message 0738 DBAC A9 80 LDAIM /(LANG ) 0739 DBAE A0 08 LDYIM ROMMSG-&1 0740 DBB0 20 55 DE JSR WRSTRA 0741 DBB3 ; N.B. Y offset left pointing to copyright message 0742 DBB3 84 FD STY REPTR +&00 0743 DBB5 20 E7 FF JSR OSNEWL 0744 DBB8 20 E7 FF JSR OSNEWL 0745 DBBB ; 0746 DBBB ; enter language 0747 DBBB ; 0748 DBBB 28 PLP ;restore entry type into C 0749 DBBC [ MOS125 = &FF 0750 DBBC | 0751 DBBC ;preserve BRK handler until all printing done 0752 DBBC A5 F4 LDA ROMID 0753 DBBE 8D 8C 02 STA LROMID 0754 DBC1 ] 0755 DBC1 A9 01 LDAIM LGENTR ;entry reason 0756 DBC3 2C 7A 02 BIT TUBEM 0757 DBC6 30 03 BMI TLANG ;[tube active] 0758 DBC8 4C 00 80 JMP ROMHRD ;ROM entry 0759 DBCB TLANG 0760 DBCB 4C 00 04 JMP TBLANG ;tube entry 0761 DBCE 0762 DBCE 0763 DBCE LNK MOS36 0001 DBCE ; > MOS36 0002 DBCE TTL MOS36 Int servicing 0003 DBCE OPT MOS36 Acorn macro assembler Page 63 MOS36 Int servicing 0004 DBCE 0005 DBCE ;(c) 1981 ACORN Computers Limited 0006 DBCE ;BBC MOS 0007 DBCE ;Change record: 0008 DBCE 0009 DBCE ;Author(s): 0010 DBCE ;PB Paul Bond 0011 DBCE 0012 DBCE ; interrupt service mainline 0013 DBCE ; priority sequence:- 0014 DBCE ; [6850] 0015 DBCE ; 1. RS423 0016 DBCE ; [6522a] 0017 DBCE ; 2. VSYNC 0018 DBCE ; 3. centisecond timer 0019 DBCE ; 4. ADC 0020 DBCE ; 5. keyboard 0021 DBCE ; [6522b] 0022 DBCE ; 6. printer (parallel interface) 0023 DBCE 0024 DBCE 0025 DBCE RPROM ;read byte from paged ROM 0026 DBCE ; read byte at ROMPTR in ROM Y into A 0027 DBCE A6 F4 LDX ROMID 0028 DBD0 84 F4 STY ROMID 0029 DBD2 8C 30 FE STY ROM 0030 DBD5 A0 00 LDYIM ZERO 0031 DBD7 B1 F6 LDAIY ROMPTR 0032 DBD9 STXROM 0033 DBD9 86 F4 STX ROMID 0034 DBDB 8E 30 FE STX ROM 0035 DBDE 60 RTS 0036 DBDF 0037 DBDF 0038 DBDF 0039 DBDF IRQ ;entered at IRQ or BRK 0040 DBDF 85 FC STA TEMPA 0041 DBE1 68 PLA 0042 DBE2 48 PHA ;A := processor status 0043 DBE3 29 10 ANDIM &10 0044 DBE5 D0 03 BNE BRK 0045 DBE7 6C 04 02 JMI IRQALL ;indirect thru 'all IRQs' routine 0046 DBEA ; (defaults to DEFIRQ) 0047 DBEA ; 0048 DBEA BRK 0049 DBEA 8A TXA 0050 DBEB 48 PHA ;save X 0051 DBEC BA TSX 0052 DBED BD 03 01 LDAAX &0100+&03 ;get address low 0053 DBF0 D8 CLD 0054 DBF1 38 SEC 0055 DBF2 E9 01 SBCIM &01 0056 DBF4 85 FD STA REPTR +&00 0057 DBF6 BD 04 01 LDAAX &0100+&04 ;get address high 0058 DBF9 E9 00 SBCIM ZERO 0059 DBFB 85 FE STA REPTR +&01 0060 DBFD ; record ROM source of BRK 0061 DBFD A5 F4 LDA ROMID 0062 DBFF 8D 4A 02 STA REPROM 0063 DC02 ; offer BRK to service ROMs 0064 DC02 86 F0 STX BYTEX ;provide clean way for service ROM to access relevant stack area 0065 DC04 A2 06 LDXIM SVBRK 0066 DC06 20 6F F1 JSR SVOP 0067 DC09 ; force language ROM (may be BASIC in pre-interface days) 0068 DC09 AE 8C 02 LDX LROMID 0069 DC0C 20 D9 DB JSR STXROM ;reset to language ROM 0070 DC0F ; 0071 DC0F ; restore X 0072 DC0F ; 0073 DC0F 68 PLA 0074 DC10 AA TAX 0075 DC11 ; 0076 DC11 ; restore A 0077 DC11 ; 0078 DC11 A5 FC LDA TEMPA 0079 DC13 ; 0080 DC13 ; enable interrupts and let user process BRK 0081 DC13 ; 0082 DC13 58 CLI 0083 DC14 6C 02 02 JMI BRKVEC ;process BRK, N.B. default is DEFBRK 0084 DC17 ; 0085 DC17 [ MOS125 = &FF 0098 DC17 ] 0099 DC17 0100 DC17 0101 DC17 TTL IRQ processing 0102 DC17 OPT OPNEWP Acorn macro assembler Page 64 IRQ processing 0103 DC17 0104 DC17 0105 DC17 TXDINT ;disable Tx interrupt 0106 DC17 ; 0107 DC17 ; RS423 printer selected but printer buffer empty 0108 DC17 ; 0109 DC17 38 SEC 0110 DC18 6E 4F 02 ROR RSFLAG ;flag RS423 available 0111 DC1B ; 0112 DC1B ; no more characters to print 0113 DC1B ; 0114 DC1B ; disable RS423 Tx 0115 DC1B ; find whether to set RTS hi or lo 0116 DC1B ; 0117 DC1B ; check whether RS423 Rx enabled 0118 DC1B ; 0119 DC1B 2C 50 02 BIT RSCTFL 0120 DC1E 10 07 BPL RLO ;[Rx disabled] 0121 DC20 ; 0122 DC20 ; Rx enabled 0123 DC20 ; 0124 DC20 ; check bytes in RS423 input buffer 0125 DC20 ; 0126 DC20 20 A5 E7 JSR CNTRS 0127 DC23 ; 0128 DC23 ; C=0 => overflow, C=1 => no overflow 0129 DC23 ; check whether within overflow region 0130 DC23 ; 0131 DC23 A2 00 LDXIM RHITXD 0132 DC25 B0 02 BCS RSOK ;[not overflowing] 0133 DC27 ; 0134 DC27 ; within overflow region 0135 DC27 ; 0136 DC27 RLO ;set RTS lo, Tx interrupt disabled (unfortunately) 0137 DC27 A2 40 LDXIM RLOTXD 0138 DC29 ; 0139 DC29 RSOK ;set RTS hi/lo, Tx interrupt disabled 0140 DC29 4C 11 E2 JMP RSED ;disable Tx interrupts AND return from interrupt 0141 DC2C 0142 DC2C 0143 DC2C RX68 ;RS423 Rx interrupt 0144 DC2C ; 0145 DC2C ; A = 0|0|PE|OVRN|FE|CTS|DCD|TDRE 0146 DC2C ; 0147 DC2C AC 09 FE LDY RSDATA ;read data byte to clear interrupt 0148 DC2F 29 3A ANDIM &3A ;CTS & TDRE are not relevant to Rx 0149 DC31 D0 26 BNE RX68BD ;[bad Rx, PE|OVRN|FE|DCD] 0150 DC33 ; 0151 DC33 ; good reception - move byte into RS423 input buffer 0152 DC33 ; 0153 DC33 AE 5C 02 LDX RSSHUT 0154 DC36 D0 09 BNE NRSI ;[suppress RS423 input] 0155 DC38 ; 0156 DC38 ; X=0 0157 DC38 ; 0158 DC38 E8 INX ;X = BRSI = $01 0159 DC39 20 58 E5 JSR RNSRT ;insert character into RS423 buffer 0160 DC3C ; 0161 DC3C ; check number of characters in buffer 0162 DC3C ; 0163 DC3C 20 A5 E7 JSR CNTRS 0164 DC3F ; 0165 DC3F ; check whether running into overflow area 0166 DC3F ; 0167 DC3F 90 E6 BCC RLO ;[running into overflow area, set RTS lo, Tx interrupt disabled] 0168 DC41 NRSI ;suppress RS423 input 0169 DC41 60 RTS 0170 DC42 0171 DC42 0172 DC42 [ MOS125 = &FF 0188 DC42 | 0189 DC42 VAT 0190 DC42 ] 0191 DC42 ; 0192 DC42 ; indicate in DEFIRQ 0193 DC42 ; 0194 DC42 B8 CLV 0195 DC43 ; 0196 DC43 IRQ68 ;check for interrupt from 6850 0197 DC43 ; 0198 DC43 [ $Tutu 0201 DC43 | 0202 DC43 AD 08 FE LDA RSTAT 0203 DC46 ] 0204 DC46 70 02 BVS RSTIME ;[timer interrupt] 0205 DC48 ; 0206 DC48 10 5D BPL IRQA ;[not a 6850 interrupt, N.B. possibly timer interrupt entry] 0207 DC4A ; 0208 DC4A RSTIME ;timer interrupt 0209 DC4A ; 0210 DC4A ; 6850 interrupt 0211 DC4A ; 0212 DC4A ; use RSTUT to decide where to route the interrupt 0213 DC4A ; 0214 DC4A A6 EA LDX RSTUT 0215 DC4C CA DEX 0216 DC4D 30 30 BMI NOTCFS ;[RS423 not managed by CFS] 0217 DC4F ; 0218 DC4F ; inform CFS of the interrupt 0219 DC4F ; 0220 DC4F 70 2D BVS RTS68 ;[ignore timer interrupt entry] 0221 DC51 4C C0 F5 JMP IRUPT ;let CFS handle interrupt AND return from interrupt 0222 DC54 0223 DC54 0224 DC54 MDCD ;neither Rx not Tx interrupt => DCD interrupt 0225 DC54 ; 0226 DC54 AC 09 FE LDY RSDATA ;clear DCD interrupt 0227 DC57 2A ROLA ;DCD -> lo-bit 0228 DC58 0A ASLA ;restore status byte 0229 DC59 ; 0230 DC59 RX68BD ;bad RS423 Rx 0231 DC59 ; 0232 DC59 ; A = 0|0|PE|OVRN|FE|0|DCD|0 0233 DC59 ; C=1 0234 DC59 ; 0235 DC59 ; signal RS423 error 0236 DC59 ; 0237 DC59 AA TAX ;X := status 0238 DC5A 98 TYA ;A := character 0239 DC5B A0 07 LDYIM EVRS ;RS423 error event 0240 DC5D 4C FA E4 JMP EVENT ;signal event AND return from interrupt Acorn macro assembler Page 65 IRQ processing 0241 DC60 0242 DC60 0243 DC60 TDRE ;Tx interrupt 0244 DC60 ; 0245 DC60 ; RS423 is not claimed by CFS, so we are either 0246 DC60 ; writing or printing to RS423 0247 DC60 ; 0248 DC60 ; extract character from RS423 Tx buffer 0249 DC60 ; 0250 DC60 A2 02 LDXIM BRSO 0251 DC62 20 C6 E4 JSR REMOV 0252 DC65 90 10 BCC TXCH ;[character to transmit] 0253 DC67 ; X=BRSO 0254 DC67 ; 0255 DC67 ; check for print to RS423 0256 DC67 ; 0257 DC67 AD 85 02 LDA PRNTSW 0258 DC6A C9 02 CMPIM PRS 0259 DC6C D0 A9 BNE TXDINT ;[RS423 printer not selected] 0260 DC6E ; X=BRSO 0261 DC6E ; 0262 DC6E ; remove possible character from print buffer 0263 DC6E ; 0264 DC6E E8 INX ;X = BRSO+1 = BPRNT 0265 DC6F 20 C6 E4 JSR REMOV ;remove character from printer buffer 0266 DC72 6E D2 02 ROR PFLAG ;update printer flag 0267 DC75 30 A0 BMI TXDINT ;[no character to print] 0268 DC77 ; 0269 DC77 TXCH ;transmit character in A 0270 DC77 ; 0271 DC77 8D 09 FE STA RSDATA ;transmit character 0272 DC7A ; 0273 DC7A ; set RS423 printer timeout active 0274 DC7A ; 0275 DC7A A9 E7 LDAIM PTIMUT 0276 DC7C 85 EA STA RSTUT 0277 DC7E ; 0278 DC7E 0279 DC7E RTS68 0280 DC7E UNK0 0281 DC7E 60 RTS ;return from interrupt 0282 DC7F 0283 DC7F 0284 DC7F NOTCFS ;RS423 not managed by CFS 0285 DC7F ; 0286 DC7F 2D 78 02 AND C6850 ;suppress bits according to user tastes 0287 DC82 4A LSRA ;C=Rx 0288 DC83 90 07 BCC NOTRX ;[not Rx int] 0289 DC85 70 05 BVS NOTRX ;[do not allow Rx by polling] 0290 DC87 ; 0291 DC87 AC 50 02 LDY RSCTFL 0292 DC8A 30 A0 BMI RX68 ;[recieve interrupts enabled] 0293 DC8C ; 0294 DC8C NOTRX 0295 DC8C 4A LSRA ;C=Tx, N=Rx 0296 DC8D 6A RORA ;C=DCD, N=Tx 0297 DC8E B0 C4 BCS MDCD ;[DCD interrupt] 0298 DC90 ; 0299 DC90 30 CE BMI TDRE ;[TDRE] 0300 DC92 ; 0301 DC92 70 EA BVS RTS68 ;[timer interrupt entry] 0302 DC94 ; 0303 DC94 ; not timer interrupt entry 0304 DC94 ; 0305 DC94 UNKIRQ ;unknown interrupt 0306 DC94 ; 0307 DC94 A2 05 LDXIM SVINT 0308 DC96 20 6F F1 JSR SVOP ;allow FS ROMs to process interrupt 0309 DC99 F0 E3 BEQ UNK0 ;[service ROM dealt with interrupt] 0310 DC9B ; 0311 DC9B ; pull return address 0312 DC9B ; 0313 DC9B 68 PLA 0314 DC9C 68 PLA 0315 DC9D ; 0316 DC9D ; restore X and Y for user interrupt routine 0317 DC9D ; 0318 DC9D 68 PLA 0319 DC9E A8 TAY 0320 DC9F 68 PLA 0321 DCA0 AA TAX 0322 DCA1 68 PLA 0323 DCA2 85 FC STA TEMPA 0324 DCA4 6C 06 02 JMI IRQVEC ;assume that user will clear the interrupt 0325 DCA7 ; (defaults to IRQTWO) 0326 DCA7 0327 DCA7 0328 DCA7 0329 DCA7 IRQA ;check for interrupt from primary 6522 0330 DCA7 ; 0331 DCA7 AD 4D FE LDA IFRQ ;A = IFR [IRQ,TIMER1,TIMER2,CB1,CB2,SHIFTREG,CA1,CA2] 0332 DCAA 10 3A BPL IRQB ;[not a VIAA interrupt] 0333 DCAC ; 0334 DCAC ; 0335 DCAC 2D 79 02 AND A6522 ;suppress bits according to user tastes 0336 DCAF 2D 4E FE AND IERQ ;N.B. only look at enabled interrupts 0337 DCB2 ; 0338 DCB2 ; 0339 DCB2 6A RORA ;A = IFR >> 1 0340 DCB3 6A RORA ;A = IFR >> 2, C = CA1, N = CA2 0341 DCB4 90 52 BCC ITIME2 ;[not VSYNC interrupt] 0342 DCB6 ; 0343 DCB6 ; VSYNC interrupt 0344 DCB6 ; N.B. C=1 0345 DCB6 ; 0346 DCB6 CE 40 02 DEC CYCLE ;update CFS timeout byte 0347 DCB9 A5 EA LDA RSTUT ;decrement RS423 printer timeout 0348 DCBB 10 02 BPL NPRST 0349 DCBD E6 EA INC RSTUT 0350 DCBF ; 0351 DCBF NPRST ;no RS423 printer timeout 0352 DCBF ; 0353 DCBF AD 51 02 LDA FLCNT 0354 DCC2 F0 18 BEQ IVS1 ;[flash disabled] 0355 DCC4 CE 51 02 DEC FLCNT 0356 DCC7 D0 13 BNE IVS1 ;[flash count not exhausted] 0357 DCC9 ; 0358 DCC9 ; flash count exhausted 0359 DCC9 ; reset FLCNT 0360 DCC9 ; 0361 DCC9 [ MOS125 = &FF Acorn macro assembler Page 66 IRQ processing 0372 DCC9 | 0373 DCC9 ; A=1 0374 DCC9 AE 52 02 LDX FLSPC 0375 DCCC 4D 48 02 EOR VPREGA ;invert flash bit 0376 DCCF 4A LSRA ;C = new flash bit 0377 DCD0 B0 03 BCS FLASH1 ;[old flash bit = 0] 0378 DCD2 ; old flash bit = 1 0379 DCD2 AE 53 02 LDX FLMRK 0380 DCD5 FLASH1 0381 DCD5 ; 0382 DCD5 2A ROLA ;A = VPREGA 0383 DCD6 ] 0384 DCD6 20 27 EA JSR MVPRC0 ;update video processor and register image 0385 DCD9 8E 51 02 STX FLCNT ;update flash count 0386 DCDC ; 0387 DCDC IVS1 0388 DCDC A0 04 LDYIM EVVSYN 0389 DCDE 20 FA E4 JSR EVENT 0390 DCE1 ; 0391 DCE1 A9 02 LDAIM VSYNC 0392 DCE3 4C 0D DE JMP IVIAA0 ;clear interrupt and return 0393 DCE6 0394 DCE6 0395 DCE6 0396 DCE6 IRQB ;check for interrupt from secondary 6522 0397 DCE6 ; 0398 DCE6 AD 6D FE LDA IFRR ;A = IFR, C = ?, N = IRQ 0399 DCE9 10 A9 BPL UNKIRQ ;[not a VIAB interrupt] 0400 DCEB ; 0401 DCEB ; 0402 DCEB 2D 77 02 AND B6522 ;suppress bits if secondary 6522 not present 0403 DCEE 2D 6E FE AND IERR ;only look at enabled interrupts 0404 DCF1 6A RORA ;A = IFR >> 1 0405 DCF2 6A RORA ;A = IFR >> 2, C = CA1 0406 DCF3 90 9F BCC UNKIRQ ;[not a printer interrupt] 0407 DCF5 ; 0408 DCF5 IPRNT ;printer interrupt 0409 DCF5 ; 0410 DCF5 ; acknowledge interrupt 0411 DCF5 ; N.B. clear before sending next character since printer 0412 DCF5 ; may acknowledge quickly and we could miss the interrupt 0413 DCF5 AC 85 02 LDY PRNTSW 0414 DCF8 88 DEY ;******** ASSUMES PCEN = 1 ******** 0415 DCF9 D0 99 BNE UNKIRQ ;[ignore printer interrupt cos centronics not selected] 0416 DCFB ; 0417 DCFB A9 02 LDAIM PRNT 0418 DCFD 8D 6D FE STA IFRR ;acknowledge interrupt 0419 DD00 8D 6E FE STA IERR ;disable printer interrupt 0420 DD03 ; (will be enabled again by STROBE if another character is sent 0421 DD03 ; using the parallel port) 0422 DD03 ; 0423 DD03 A2 03 LDXIM BPRNT ;X := print bufferid 0424 DD05 4C D3 E1 JMP STROBE ;if character read then print it AND return from interrupt 0425 DD08 0426 DD08 0427 DD08 ITIME2 ;check for TIMER2 interrupt 0428 DD08 ; 0429 DD08 2A ROLA ;A = IFR >> 1 0430 DD09 2A ROLA ;A = IFR 0431 DD0A 2A ROLA ;:A = IFR << 1, N = TIMER1 0432 DD0B 2A ROLA ;A = IFR << 2, N = TIMER2, C = TIMER1 0433 DD0C 10 5B BPL ITIME1 ;[not TIMER2, check for TIMER1 interrupt] 0434 DD0E [ NOSP = &00 0437 DD0E | 0438 DD0E ; 0439 DD0E ; timer 2 interrupt 0440 DD0E ; acknowledge interrupt 0441 DD0E ; 0442 DD0E ; and 0443 DD0E ; 0444 DD0E ; set speech RDY to interrupt again 0445 DD0E ; 0446 DD0E A9 20 LDAIM TIMER2 0447 DD10 A2 00 LDXIM ZERO 0448 DD12 ; N.B. minimise time between next two instructions 0449 DD12 8D 4D FE STA IFRQ ;clear interrupt 0450 DD15 8E 49 FE STX TRCHQ ;set to interrupt on speech chip INT 0451 DD18 ; 0452 DD18 ; process speech request 0453 DD18 ; 0454 DD18 PRSPRQ ;process speech request 0455 DD18 ; 0456 DD18 ; set speak external repeat counter to 4 0457 DD18 ; 0458 DD18 A2 08 LDXIM BSPCH 0459 DD1A 86 FB STX SPWK2 ;**** ASSUMES BSPCH=8 **** 0460 DD1C ; 0461 DD1C SPEREP ;repeat poke of speak external data 0462 DD1C ; 0463 DD1C ; inspect speech buffer 0464 DD1C ; 0465 DD1C 20 C1 E4 JSR EXAM 0466 DD1F ; 0467 DD1F ; record buffer status - MI => dormant, PL => busy 0468 DD1F ; 0469 DD1F 6E D7 02 ROR SPSTAT 0470 DD22 30 44 BMI NSPECH ;[buffer empty] 0471 DD24 ; 0472 DD24 A8 TAY 0473 DD25 F0 05 BEQ SPOK ;[speak external data] 0474 DD27 ; 0475 DD27 ; new command - ensure not talking 0476 DD27 ; 0477 DD27 20 A7 EE JSR RSPECH 0478 DD2A 30 3C BMI NSPECH ;[talking active] 0479 DD2C ; 0480 DD2C ; new command and not talking 0481 DD2C ; 0482 DD2C SPOK ;speak external data 0483 DD2C ; 0484 DD2C ; get command byte from speech buffer 0485 DD2C ; 0486 DD2C 20 C6 E4 JSR REMOV 0487 DD2F ; 0488 DD2F ; codeword in A 0489 DD2F ; 0490 DD2F 85 F5 STA SEROM 0491 DD31 ; 0492 DD31 ; pull data 0493 DD31 ; 0494 DD31 20 C6 E4 JSR REMOV Acorn macro assembler Page 67 IRQ processing 0495 DD34 85 F7 STA ROMPTR+&01 ;hi-address / hi-data 0496 DD36 20 C6 E4 JSR REMOV 0497 DD39 85 F6 STA ROMPTR+&00 ;lo-address / lo-data 0498 DD3B ; 0499 DD3B ; switch on codeword 0500 DD3B ; 0501 DD3B A4 F5 LDY SEROM 0502 DD3D F0 1B BEQ ISP2 ;[command=0, do not treat codeword as a command] 0503 DD3F 10 16 BPL ISP3 ;[command>0, speech command without address] 0504 DD41 ; 0505 DD41 ; command with address 0506 DD41 ; command either speak(address) OR read-and-branch(address) 0507 DD41 ; 0508 DD41 ; check for read and branch request 0509 DD41 ; 0510 DD41 24 F5 BIT SEROM 0511 DD43 [ MOS125 = &FF 0531 DD43 | 0532 DD43 50 09 BVC LADDR ;[speak(address)] 0533 DD45 ;read and branch (speak indirect) 0534 DD45 ; 0535 DD45 ; multiply offset by two 0536 DD45 ; 0537 DD45 06 F6 ASL ROMPTR+&00 0538 DD47 26 F7 ROL ROMPTR+&01 0539 DD49 ; 0540 DD49 ; reselect address 0541 DD49 ; 0542 DD49 20 76 EE JSR SPLIND ;load address indirect (returns C=0) 0543 DD4C 90 03 BCC ISPX ;always branch 0544 DD4E 0545 DD4E LADDR 0546 DD4E ; 0547 DD4E ; speak(address) 0548 DD4E ; load address into speech processor 0549 DD4E ; 0550 DD4E ; V=0 0551 DD4E 20 F5 EE JSR SPLOAD ;N.B. does PHP...PLP 0552 DD51 ] 0553 DD51 ; 0554 DD51 ISPX 0555 DD51 AC 61 02 LDY SHUTSP ;command defaults to speech 0556 DD54 4C B9 EE JMP WSPECH ;send command AND return 0557 DD57 ; 0558 DD57 ; 0559 DD57 ISP3 ;treat codeword as a command 0560 DD57 ; 0561 DD57 20 B9 EE JSR WSPECH ;issue codeword command 0562 DD5A ; 0563 DD5A ISP2 ;write argument data bytes 0564 DD5A ; 0565 DD5A A4 F6 LDY ROMPTR+&00 0566 DD5C 20 B9 EE JSR WSPECH 0567 DD5F A4 F7 LDY ROMPTR+&01 0568 DD61 20 B9 EE JSR WSPECH 0569 DD64 ; 0570 DD64 ; repeat poke of speak external data up to 4 times (8 bytes) 0571 DD64 ; 0572 DD64 46 FB LSR SPWK2 0573 DD66 D0 B4 BNE SPEREP ;[try poking more speak external data] 0574 DD68 ; 0575 DD68 NSPECH 0576 DD68 60 RTS 0577 DD69 ] 0578 DD69 0579 DD69 0580 DD69 0581 DD69 ITIME1 ;check for TIMER1 interrupt 0582 DD69 ; 0583 DD69 90 7B BCC IADC ;[not TIMER1, check for ADC interrupt] 0584 DD6B ; C=1 0585 DD6B ; 0586 DD6B ; main clock interrupt 0587 DD6B ; 0588 DD6B ; clear interrupt 0589 DD6B ; 0590 DD6B A9 40 LDAIM CLOCK 0591 DD6D 8D 4D FE STA IFRQ ;acknowledge clock interrupt 0592 DD70 ; C=1 0593 DD70 ; 0594 DD70 ; increment absolute time 0595 DD70 ; 0596 DD70 AD 83 02 LDA TIMESW 0597 DD73 AA TAX ;X -> current timer 0598 DD74 49 0F EORIM &0F 0599 DD76 48 PHA 0600 DD77 A8 TAY ;Y -> other timer 0601 DD78 ; C=1 0602 DD78 ;****SEC ;N.B. add 1 to timer 0603 DD78 ; 0604 DD78 IT1 0605 DD78 BD 91 02 LDAAX TIME -&01 0606 DD7B 69 00 ADCIM ZERO 0607 DD7D 99 91 02 STAAY TIME -&01 0608 DD80 CA DEX 0609 DD81 F0 03 BEQ IT2 0610 DD83 88 DEY 0611 DD84 D0 F2 BNE IT1 0612 DD86 IT2 0613 DD86 ; 0614 DD86 68 PLA 0615 DD87 8D 83 02 STA TIMESW ;switch timers 0616 DD8A ; 0617 DD8A ; 0618 DD8A A2 05 LDXIM &05 0619 DD8C IVIAA5 0620 DD8C FE 9B 02 INCAX STPW -&01 0621 DD8F D0 08 BNE IINKEY 0622 DD91 CA DEX 0623 DD92 D0 F8 BNE IVIAA5 0624 DD94 ; 0625 DD94 ; stopwatch timeout 0626 DD94 ; 0627 DD94 A0 05 LDYIM EVSWCH 0628 DD96 20 FA E4 JSR EVENT 0629 DD99 ; 0630 DD99 IINKEY ;decrement INKEY counter 0631 DD99 ; 0632 DD99 AD B1 02 LDA RDCTLO 0633 DD9C D0 08 BNE IIN1 ;[just decrement lo] 0634 DD9E ; lo zero Acorn macro assembler Page 68 IRQ processing 0635 DD9E AD B2 02 LDA RDCTHI 0636 DDA1 F0 06 BEQ IIN0 ;[counter zero] 0637 DDA3 ; decrement lo and hi 0638 DDA3 CE B2 02 DEC RDCTHI 0639 DDA6 IIN1 ;just decrement lo 0640 DDA6 CE B1 02 DEC RDCTLO 0641 DDA9 IIN0 ;counter zero 0642 DDA9 0643 DDA9 [ $Tutu ; no sound, no speech shit wanted - nothing from this point on 0647 DDA9 | 0648 DDA9 ; 0649 DDA9 ; 0650 DDA9 ; check sound sema to ensure exclusive access to sound code 0651 DDA9 ; 0652 DDA9 2C CE 02 BIT SSEMA 0653 DDAC ] 0654 DDAC 10 0B BPL SINUSE ;[sound software in use] 0655 DDAE ; 0656 DDAE ; sound software available 0657 DDAE ; 0658 DDAE EE CE 02 INC SSEMA ;claim sound sema 0659 DDB1 58 CLI ;enable interrupts during sound processing 0660 DDB2 20 9F EB JSR SNDIRQ 0661 DDB5 78 SEI ;disable interrupts after sound processing 0662 DDB6 CE CE 02 DEC SSEMA ;release sound sema 0663 DDB9 SINUSE 0664 DDB9 [ NOSP = &00 0666 DDB9 | 0667 DDB9 ; 0668 DDB9 ; give speech a chance 0669 DDB9 ; 0670 DDB9 ; check buffer 0671 DDB9 ; 0672 DDB9 2C D7 02 BIT SPSTAT 0673 DDBC 30 0C BMI SPBUSY ;[speech buffer empty] 0674 DDBE ; 0675 DDBE ; read speech chip status 0676 DDBE ; 0677 DDBE 20 A7 EE JSR RSPECH ;N.B. does not alter A if speech chip not present 0678 DDC1 ; 0679 DDC1 ; A>=$80 => busy 0680 DDC1 ; 0681 DDC1 ; N.B. if speech chip does not exist then 25% chance that PRSPRQ will 0682 DDC1 ; be called, this will just result in a no-operation effect 0683 DDC1 ; 0684 DDC1 49 A0 EORIM &A0 0685 DDC3 C9 60 CMPIM &60 0686 DDC5 90 03 BCC SPBUSY ;[100, 101 or 111] 0687 DDC7 ; 0688 DDC7 20 18 DD JSR PRSPRQ ;process speech request 0689 DDCA ] 0690 DDCA ; 0691 DDCA SPBUSY ;speech chip busy 0692 DDCA ; 0693 DDCA ; check RS423 for possible Tx 0694 DDCA ; 0695 DDCA 2C 47 D9 BIT FFBYT ;indicate timer interrupt call 0696 DDCD 20 43 DC JSR IRQ68 0697 DDD0 ; 0698 DDD0 ; check keyboard if keys active 0699 DDD0 ; 0700 DDD0 A5 EC LDA CKEY 0701 DDD2 05 ED ORA OKEY 0702 DDD4 2D 42 02 AND KSEMA ;check for keyboard critical region 0703 DDD7 F0 04 BEQ ICLK0 ;[no keys active, clear timer interrupt] 0704 DDD9 38 SEC 0705 DDDA 20 92 F0 JSR JMIKYV ;key(s) active, process timer interrupt 0706 DDDD ; ******** MAY ENABLE INTERRUPTS (EXITS DISABLED) ******** 0707 DDDD ; 0708 DDDD ICLK0 0709 DDDD ; give user print routine a chance 0710 DDDD 20 32 E2 JSR UPTINT 0711 DDE0 ; 0712 DDE0 ; the ADC is connected on CB1 0713 DDE0 ; when port B is read (by keyboard routines) any 0714 DDE0 ; interrupt is lost, and the ADC must be restarted 0715 DDE0 ; 0716 DDE0 2C C0 FE BIT ADCCTL 0717 DDE3 70 04 BVS IADCB ;[ADC not busy] 0718 DDE5 60 RTS ;return from interrupt 0719 DDE6 0720 DDE6 0721 DDE6 IADC ;check for ADC interrupt 0722 DDE6 ; 0723 DDE6 2A ROLA ;A = IFR << 3, N = CB1 0724 DDE7 10 28 BPL IKEYBD ;[not an ADC intterupt] 0725 DDE9 ; 0726 DDE9 ; ADC interrupt 0727 DDE9 ; check ADC enabled 0728 DDE9 ; 0729 DDE9 IADCB 0730 DDE9 AE 4C 02 LDX ADCHAN 0731 DDEC F0 1D BEQ IADC0 ;[ADC disabled] 0732 DDEE ; 0733 DDEE ; read conversion lo byte 0734 DDEE ; 0735 DDEE AD C2 FE LDA ADCLO 0736 DDF1 9D B5 02 STAAX ADCLOV -&01 0737 DDF4 ; 0738 DDF4 ; read conversion hi byte 0739 DDF4 ; 0740 DDF4 AD C1 FE LDA ADCHI 0741 DDF7 9D B9 02 STAAX ADCHIV -&01 0742 DDFA ; 0743 DDFA ; set latest conversion number 0744 DDFA ; 0745 DDFA 8E BE 02 STX ADCFLG 0746 DDFD ; 0747 DDFD ; signal ADC conversion event, X = channel number 0748 DDFD ; 0749 DDFD A0 03 LDYIM EVADC 0750 DDFF 20 FA E4 JSR EVENT 0751 DE02 ; 0752 DE02 ; step to next channel 0753 DE02 ; 0754 DE02 CA DEX 0755 DE03 D0 03 BNE IADC2 ;[channel >= 1] 0756 DE05 ; 0757 DE05 ; channel counter underflow 0758 DE05 ; reload channel counter 0759 DE05 ; Acorn macro assembler Page 69 IRQ processing 0760 DE05 AE 4D 02 LDX MAXADC 0761 DE08 IADC2 0762 DE08 ; 0763 DE08 ; initiate next conversion 0764 DE08 ; X = channel number 0765 DE08 ; 0766 DE08 20 39 DE JSR ADCBGX ;begin conversion, sets ADCHAN=X 0767 DE0B IADC0 0768 DE0B A9 10 LDAIM ADC 0769 DE0D IVIAA0 ;return from VIAA interrupt 0770 DE0D 8D 4D FE STA IFRQ ;clear interrupt state 0771 DE10 60 RTS ;return from interrupt 0772 DE11 0773 DE11 0774 DE11 IKEYBD ;keyboard interrupt check 0775 DE11 ; 0776 DE11 2A ROLA ;A = IFR << 4 0777 DE12 2A ROLA ;A = IFR << 5 0778 DE13 2A ROLA ;A = IFR << 6 0779 DE14 2A ROLA ;A = IFR << 7, N = CA2 0780 DE15 10 07 BPL JUNKIRQ ;[not keyboard interrupt] 0781 DE17 ; 0782 DE17 ; C=0 because no VSYNC 0783 DE17 ; 0784 DE17 20 92 F0 JSR JMIKYV ;find and set up new current key (enter with C=0) 0785 DE1A ; ******** MAY ENABLE INTERRUPTS (EXITS DISABLED) ******** 0786 DE1A A9 01 LDAIM KEYBD 0787 DE1C D0 EF BNE IVIAA0 ;[ALWAYS jump] 0788 DE1E ; 0789 DE1E 4C 94 DC JUNKIRQ JMP UNKIRQ ;IRQ not identified 0790 DE21 0791 DE21 0792 DE21 0793 DE21 [ MOS125 = &FF 0794 DE21 | 0795 DE21 DEFIRQ ;default IRQ routine 0796 DE21 D8 CLD 0797 DE22 A5 FC LDA TEMPA 0798 DE24 48 PHA 0799 DE25 8A TXA 0800 DE26 48 PHA 0801 DE27 98 TYA 0802 DE28 48 PHA 0803 DE29 ; 0804 DE29 ; schedule return from interrupt 0805 DE29 ; 0806 DE29 20 42 DC JSR VAT 0807 DE2C ] 0808 DE2C IRQ0 ;return from interrupt restoring registers 0809 DE2C 68 PLA 0810 DE2D A8 TAY 0811 DE2E 68 PLA 0812 DE2F AA TAX 0813 DE30 68 PLA 0814 DE31 85 FC STA TEMPA 0815 DE33 ; 0816 DE33 IRQTWO 0817 DE33 A5 FC LDA TEMPA 0818 DE35 40 RTI 0819 DE36 0820 DE36 0821 DE36 ADCBEG ;begin forced ADC conversion 0822 DE36 ; 0823 DE36 ; X = external channel number 0824 DE36 ; Y = 0 0825 DE36 ; 0826 DE36 8C BE 02 STY ADCFLG ;clear conversion number 0827 DE39 ; 0828 DE39 ADCBGX ;begin ADC conversion 0829 DE39 ; 0830 DE39 ; X = external channel number 0831 DE39 ; Y corrupted 0832 DE39 ; 0833 DE39 E0 05 CPXIM NADC +&01 0834 DE3B 90 02 BCC ADCBG1 ;[valid channel number] 0835 DE3D A2 04 LDXIM NADC ;force valid channel number 0836 DE3F ADCBG1 ;channel number now valid (but possibly 0) 0837 DE3F ; 0838 DE3F 8E 4C 02 STX ADCHAN 0839 DE42 AC 4E 02 LDY ADCCNV ;normally 0, 8 or 12 (0 has same effect as 12) 0840 DE45 88 DEY 0841 DE46 98 TYA 0842 DE47 29 08 ANDIM &08 ;extract conversion type 0843 DE49 18 CLC 0844 DE4A 6D 4C 02 ADC ADCHAN 0845 DE4D ; C=0 0846 DE4D E9 00 SBCIM ZERO ;subtract 1, add in INTERNAL channel number (1->0 ... 4->3) 0847 DE4F 8D C0 FE STA ADCCTL ;start conversion 0848 DE52 ; 0849 DE52 ; if X was 0 on entry then a conversion is initiated on channel 3 0850 DE52 ; of the opposite conversion type to that expected, but the result 0851 DE52 ; of this conversion will be ignored 0852 DE52 ; 0853 DE52 60 RTS 0854 DE53 0855 DE53 0856 DE53 WRSTR ;write string 0857 DE53 ; 0858 DE53 A9 C3 LDAIM /MSG 0859 DE55 WRSTRA 0860 DE55 85 FE STA REPTR +&01 0861 DE57 A9 00 LDAIM ZERO 0862 DE59 85 FD STA REPTR +&00 0863 DE5B WRSTR1 0864 DE5B C8 INY 0865 DE5C B1 FD LDAIY REPTR 0866 DE5E 20 E3 FF JSR OSASCI ;write message character 0867 DE61 AA TAX 0868 DE62 D0 F7 BNE WRSTR1 ;[ALWAYS jump, step to next message character] 0869 DE64 ; terminator found 0870 DE64 60 RTS 0871 DE65 0872 DE65 0873 DE65 LNK MOS38 0001 DE65 ; > MOS38 0002 DE65 TTL MOS38 CLI 0003 DE65 OPT MOS38 Acorn macro assembler Page 70 MOS38 CLI 0004 DE65 ;(c) 1981 ACORN 0005 DE65 ;BBC MOS 0006 DE65 ;Change record: 0007 DE65 ;004 29-Jul-81 MP Prototype version 0008 DE65 ;Author(s): 0009 DE65 ;PB Paul Bond 0010 DE65 ;MP Mike Prees 0011 DE65 0012 DE65 0013 DE65 ; RDCH 0014 DE65 INKEY 0015 DE65 8E B1 02 STX RDCTLO ;set INKEY counter 0016 DE68 8C B2 02 STY RDCTHI 0017 DE6B A9 FF LDAIM &FF ;indicate INKEY operational 0018 DE6D D0 02 BNE RDCH5 ;[ALWAYS JUMP] 0019 DE6F RDCH ;default OSRDCH 0020 DE6F A9 00 LDAIM ZERO ;indicate not INKEY 0021 DE71 RDCH5 0022 DE71 85 E6 STA RDCTEM 0023 DE73 ; save X and Y 0024 DE73 8A TXA 0025 DE74 48 PHA 0026 DE75 98 TYA 0027 DE76 48 PHA 0028 DE77 ; check for exec file 0029 DE77 AC 56 02 LDY EXECH 0030 DE7A F0 14 BEQ RDCHQ ;[no exec file] 0031 DE7C ; 0032 DE7C 38 SEC 0033 DE7D 66 EB ROR ESSEMA ;enter critical region 0034 DE7F 20 D7 FF JSR OSBGET ;get a byte from exec file 0035 DE82 08 PHP 0036 DE83 46 EB LSR ESSEMA ;exit critical region 0037 DE85 28 PLP 0038 DE86 90 25 BCC RDCH3 ;[return character] 0039 DE88 ; 0040 DE88 ; end of exec file: close exec file 0041 DE88 ; Y = handle 0042 DE88 A9 00 LDAIM ZERO 0043 DE8A 8D 56 02 STA EXECH ;cancel exec file handle 0044 DE8D 20 CE FF JSR OSFIND ;close exec file 0045 DE90 RDCHQ ;read character 0046 DE90 24 FF BIT ESCFLG 0047 DE92 30 16 BMI RDCH1 ;[ESCAPE detected] 0048 DE94 ; 0049 DE94 AE 41 02 LDX RDCHSW ;set to read ch from selected buffer 0050 DE97 20 DC E5 JSR RDCHG ;get ch from kybd input buffer 0051 DE9A 90 11 BCC RDCHN ;[character available] 0052 DE9C ; 0053 DE9C ; C=1 0054 DE9C ; 0055 DE9C 24 E6 BIT RDCTEM 0056 DE9E 50 F0 BVC RDCHQ ;[INKEY not operational] 0057 DEA0 ; 0058 DEA0 AD B1 02 LDA RDCTLO 0059 DEA3 0D B2 02 ORA RDCTHI 0060 DEA6 D0 E8 BNE RDCHQ ;[INKEY counter <> 0] 0061 DEA8 ; 0062 DEA8 ;INKEY count exhausted 0063 DEA8 ; 0064 DEA8 B0 05 BCS RDCH2 ;[ALWAYS jump, return A=$FF, C=1] 0065 DEAA ; 0066 DEAA RDCH1 ;ESCAPE detected 0067 DEAA 38 SEC ;indicate escape detected 0068 DEAB A9 1B LDAIM ESC 0069 DEAD RDCHN ;C=0 => 'real' character 0070 DEAD RDCH3 ;C=1 => escape detected OR INKEY count expired 0071 DEAD 85 E6 STA RDCTEM ;save character read 0072 DEAF RDCH2 ;entry point used when INKEY count exhausted (N.B. RDCTEM=$FF) 0073 DEAF 68 PLA ;restore X and Y 0074 DEB0 A8 TAY 0075 DEB1 68 PLA 0076 DEB2 AA TAX 0077 DEB3 A5 E6 LDA RDCTEM ;A := character 0078 DEB5 60 RTS 0079 DEB6 [ MOS125 = &FF 0355 DEB6 ] 0356 DEB6 0357 DEB6 [ MOS125 = &FF 0358 DEB6 | 0359 DEB6 ;START OF MOS 1.25 0360 DEB6 ; COPYR had been anchored here for fear that CLISKP 0361 DEB6 ; would be entered with X<2; this is now ruled out 0362 DEB6 ; but instead end-of-table marker must be within 0363 DEB6 ; 253 bytes of COMTAB 0364 DEB6 ; command level interpreter 0365 DEB6 COMTAB ;table of MOS commands 0366 DEB6 ; this table uses the fact that all routine address hi-bytes 0367 DEB6 ; will have the top bit set 0368 DEB6 ; N.B. addresses are stored hi-byte followed by lo-byte 0369 DEB6 ; hi-byte is assumed to be >=$80 0370 DEB6 ; code following address is A reg on entry to address 0371 DEB6 ; A+ => enter with XY -> line 0372 DEB6 ; A- => enter with Y = offset 0373 DEB6 0374 DEB6 ; CAT 0375 DEB6 ;must come first to trap *. 0376 DEB6 43 41 54 = "CAT" 0377 DEB9 E0 9C & /JMIFSC 0378 DEBB 05 = FSCAT ;enter with XY -> line 0379 DEBC 0380 DEBC ; FX 0381 DEBC ;second entry in OS 1.20. 0382 DEBC ;some naughty code might rely on the same quick response 0383 DEBC ;but we also want to give fast access to USERV (*FX136) 0384 DEBC ;and match early due to the sheer volume of calls 0385 DEBC 46 58 = "FX" 0386 DEBE E3 8E & /FX 0387 DEC0 FF = &FF ;enter with Y = offset 0388 DEC1 0389 DEC1 ; CODE 0390 DEC1 ;match after FX to take less time than *FX136 0391 DEC1 43 4F 44 = "CODE" 0392 DEC5 E3 94 & /FXN 0393 DEC7 88 = FXCODE ;enter with Y = offset 0394 DEC8 0395 DEC8 ; LOAD 0396 DEC8 ;must come before LINE to trap *L. 0397 DEC8 4C 4F 41 = "LOAD" 0398 DECC E2 BA & /LOAD 0399 DECE Acorn macro assembler Page 71 MOS38 CLI 0400 DECE 00 = &00 ;enter with XY -> line 0401 DECF 0402 DECF ; LINE 0403 DECF ;needs fast service the most as user code may be time critical 0404 DECF ;the only (trivial) way to pass a string from parasite to USERV 0405 DECF 4C 49 4E = "LINE" 0406 DED3 E6 BE & /JMIUSR 0407 DED5 01 = &01 ;enter with A=$01, XY -> line, C=0 0408 DED6 0409 DED6 ; default if first character is not alpha, |, . or / 0410 DED6 ;filter the wordless *commands off early 0411 DED6 ;a substitute for testing the first char in code 0412 DED6 [ MOS125 = &7F 0413 DED6 [ STARGO = &00 0414 DED6 E0 95 & /JMICMD 0415 DED8 | 0417 DED8 ] 0418 DED8 | 0420 DED8 ] 0421 DED8 03 = FSNAME ;enter with XY -> line 0422 DED9 0423 DED9 ; RUN 0424 DED9 ;must come before ROM to trap *R. 0425 DED9 ;should be as fast as *wordless to have equal advantage 0426 DED9 52 55 4E = "RUN" 0427 DEDC [ MOS125 = &7F 0428 DEDC [ STARGO = &00 0429 DEDC E0 95 & /JMICMD 0430 DEDE | 0432 DEDE ] 0433 DEDE | 0435 DEDE ] 0436 DEDE 0437 DEDE 04 = FSRUN ;enter with XY -> line 0438 DEDF 0439 DEDF ; OPT 0440 DEDF ;part of a program's operation, has high priority 0441 DEDF 4F 50 54 = "OPT" 0442 DEE2 E3 94 & /FXN 0443 DEE4 0444 DEE4 8B = FXOPT ;enter with Y = offset 0445 DEE5 0446 DEE5 ; EXEC 0447 DEE5 ;slow but provides the computer with work, should not hold it up 0448 DEE5 45 58 45 = "EXEC" 0449 DEE9 F6 C5 & /EXEC 0450 DEEB 0451 DEEB 00 = ZERO ;enter with XY -> line 0452 DEEC 0453 DEEC ; MOTOR 0454 DEEC ;a quick command but not urgent coming through OSCLI 0455 DEEC 4D 4F 54 = "MOTOR" 0456 DEF1 E3 94 & /FXN 0457 DEF3 0458 DEF3 89 = FXMOTR ;enter with Y = offset 0459 DEF4 0460 DEF4 ; SAVE 0461 DEF4 ;must come before SPOOL to trap *S. 0462 DEF4 ;a slow command and rarer than loading 0463 DEF4 53 41 56 = "SAVE" 0464 DEF8 E2 BC & /SAVE 0465 DEFA 0466 DEFA 00 = ZERO ;enter with XY -> line 0467 DEFB 0468 DEFB ; SPOOL 0469 DEFB ;also slow and rarer than saving 0470 DEFB 53 50 4F = "SPOOL" 0471 DF00 E2 FF & /SPOOL 0472 DF02 0473 DF02 00 = ZERO ;enter with XY -> line 0474 DF03 0475 DF03 ; KEY 0476 DF03 ;low volume, called by programs at setup 0477 DF03 4B 45 59 = "KEY" 0478 DF06 E3 C3 & /KEY 0479 DF08 0480 DF08 FF = &FF ;enter with Y = offset 0481 DF09 0482 DF09 ; TAPE 0483 DF09 ;must come before TV to trap *T. 0484 DF09 ;slightly more complex, called by programs at setup 0485 DF09 54 41 50 = "TAPE" 0486 DF0D E3 94 & /FXN 0487 DF0F 0488 DF0F 8C = FXTAPE ;enter with Y = offset 0489 DF10 0490 DF10 ; TV 0491 DF10 ;cosmetic, called by programs at setup 0492 DF10 54 56 = "TV" 0493 DF12 E3 94 & /FXN 0494 DF14 0495 DF14 90 = FXTV ;enter with Y = offset 0496 DF15 0497 DF15 ; HELP 0498 DF15 ;user command 0499 DF15 48 45 4C = "HELP" 0500 DF19 F5 4C & /HELP 0501 DF1B 0502 DF1B FF = &FF ;enter with Y = offset 0503 DF1C 0504 DF1C ; ROM 0505 DF1C ;rarely used. as RFS installations are site-specific 0506 DF1C ;this is essentially a user command 0507 DF1C 52 4F 4D = "ROM" 0508 DF1F E3 94 & /FXN 0509 DF21 0510 DF21 8D = FXSROM ;don't care 0511 DF22 0512 DF22 ; BASIC 0513 DF22 ;invokes the language (i.e. non-transient) 0514 DF22 ;called either by the user or in a slow *EXEC file 0515 DF22 42 41 53 = "BASIC" 0516 DF27 E0 7A & /BASIC 0517 DF29 01 = &01 ;bit 0 set for ILR2 to enter ROM with C=1 0518 DF2A ] 0519 DF2A 0520 DF2A [ MOS125 = &7F 0521 DF2A [ STARGO = &00 0522 DF2A ; GOIO 0523 DF2A ;comes before GO to trap *G. 0524 DF2A 47 4F 49 = "GOIO" Acorn macro assembler Page 72 MOS38 CLI 0525 DF2E DF 7A & /GOIO 0526 DF30 0527 DF30 80 = /LANG ;assumed -ve; stored as default jump address 0528 DF31 0529 DF31 ; GO 0530 DF31 47 4F = "GO" 0531 DF33 DF 7B & /GO 0532 DF35 0533 DF35 80 = /LANG ;assumed -ve; stored as default jump address 0534 DF36 0535 DF36 = "" 0536 DF36 80 = &80 ;end of table 0537 DF37 0538 DF37 00 00 00 % 67 ;padding 0539 DF7A 0540 DF7A [ NOSP = &00 0542 DF7A ] 0543 DF7A 0544 DF7A GOIO 0545 DF7A 38 SEC 0546 DF7B GO 0547 DF7B 08 PHP 0548 DF7C A2 D4 LDXIM INFO +BKEXEC -FBLOCK ;stretch! 0549 DF7E 20 81 E2 JSR CLRFB 0550 DF81 8D C3 03 STA INFO +BKEXEC +&01 ;default address = &00008000 0551 DF84 20 92 E2 JSR LSA ;replace with user address if present 0552 DF87 28 PLP 0553 DF88 90 08 BCC GETENV ;if *GO then use whole address 0554 DF8A A9 FF LDAIM &FF 0555 DF8C 8D C4 03 STA INFO +BKEXEC +&02 0556 DF8F 8D C5 03 STA INFO +BKEXEC +&03 ;else force an I/O processor address 0557 DF92 GETENV 0558 DF92 20 A0 E0 JSR SKIPSP ;get next argument 0559 DF95 F0 07 BEQ GOTO ;if CR then point tail at it 0560 DF97 C9 3B CMPIM ";" 0561 DF99 D0 03 BNE GOTO ;if not semicolon then point tail at it 0562 DF9B 20 9F E0 JSR SKIPSN ;else absorb semicolon once 0563 DF9E GOTO 0564 DF9E 4C 02 F3 JMP RUNGO ;set up tail from Y and enter user code 0565 DFA1 0566 DFA1 RETAIL ;return command line tail to OSARGS control block 0567 DFA1 ;Y=high byte 0568 DFA1 94 01 STYZX &01 ;store in 3MSB 0569 DFA3 AC D0 02 LDY TAILLO 0570 DFA6 94 00 STYZX &00 ;store low byte in MSB 0571 DFA8 A0 FF LDYIM &FF ;command line tail is always in I/O processor 0572 DFAA 94 02 STYZX &02 ;set high word to &FFFF 0573 DFAC 94 03 STYZX &03 0574 DFAE C8 INY ;Y=0 for return 0575 DFAF [ TRUE = &00 0576 DFAF A9 DC LDAIM SEAL ;set conventional return value (conflicting documentation) 0577 DFB1 ] 0578 DFB1 60 RTS 0579 DFB2 0580 DFB2 COLHEX 0581 DFB2 [ FALSE = &00 0584 DFB2 ] 0585 DFB2 AE C2 03 LDX INFO +BKEXEC ;get selected slot to X 0586 DFB5 E0 10 CPXIM NROM ;does the slot have a table entry? 0587 DFB7 [ TRUE = &00 0588 DFB7 B0 70 BCS FRIEZE ;[not in table] 0589 DFB9 | 0591 DFB9 ] 0592 DFB9 BD A1 02 LDAAX ROMS 0593 DFBC 10 6B BPL FRIEZE ;[not a service ROM] 0594 DFBE ABACUS 0595 DFBE A5 F4 LDA ROMID ;save current ROM 0596 DFC0 48 PHA 0597 DFC1 20 D9 DB JSR STXROM 0598 DFC4 A9 04 LDAIM SVNAME 0599 DFC6 20 03 80 JSR ROMSFT ;call service ROM 0600 DFC9 AA TAX ;if ROM did not claim the call 0601 DFCA D0 5D BNE FRIEZE ;then raise "Bad command" 0602 DFCC 4C 8B F1 JMP SVOP3 ;[service claimed, do not offer to other ROMs] 0603 DFCF | 0612 DFCF ] 0613 DFCF ] 0614 DFCF 0615 DFCF [ MOS125 = &00 0624 DFCF ] 0625 DFCF 0626 DFCF [ MOS125 = &FF 0627 DFCF | 0628 DFCF CLINT 0629 DFCF 86 F2 STX WORK +&00 0630 DFD1 84 F3 STY WORK +&01 0631 DFD3 ; report *command to filing system 0632 DFD3 A9 08 LDAIM FSCLI 0633 DFD5 20 9C E0 JSR JMIFSC 0634 DFD8 ; check line is terminated by CR 0635 DFD8 A0 00 LDYIM ZERO 0636 DFDA A9 0D LDAIM MCR 0637 DFDC D1 F2 CLICHK CMPIY WORK 0638 DFDE F0 04 BEQ CLILOK ;[terminator present] 0639 DFE0 C8 INY 0640 DFE1 D0 F9 BNE CLICHK 0641 DFE3 ; no terminator within 256 bytes so ignore line 0642 DFE3 CLIRTS 0643 DFE3 60 RTS 0644 DFE4 ; 0645 DFE4 A0 FF CLILOK LDYIM &FF ;start scan from beginning of input buffer 0646 DFE6 ; N.B. Y will now be incremented to ZERO by SKIPSN 0647 DFE6 CLIR ;skip leading spaces and asterisks 0648 DFE6 20 9F E0 JSR SKIPSN ;skip spaces/asterisk and spaces 0649 DFE9 F0 F8 BEQ CLIRTS ;[reached end-of-line, ignore line] 0650 DFEB C9 2A CMPIM SPLAT 0651 DFED F0 F7 BEQ CLIR ;[asterisk, ignore] 0652 DFEF [ FALSE=0 0656 DFEF ] 0657 DFEF ; ignore comment line 0658 DFEF C9 7C CMPIM "|" 0659 DFF1 F0 F0 BEQ CLIRTS ;[*| command] 0660 DFF3 ; check for override 0661 DFF3 C9 2F CMPIM "/" 0662 DFF5 D0 09 BNE NOTSL ;[not /] 0663 DFF7 ; */name 0664 DFF7 C8 INY ;skip past / 0665 DFF8 20 6B E0 JSR CLIXY ;make XY -> after / 0666 DFFB A9 02 LDAIM FSNOTA 0667 DFFD [ MOS125 = &7F 0668 DFFD [ STARGO = &00 Acorn macro assembler Page 73 MOS38 CLI 0669 DFFD 4C 95 E0 JMP JMICMD ;[ALWAYS JUMP] 0670 E000 NOTSL 0671 E000 ; save pointer to rest of line 0672 E000 84 E6 STY CLIRY 0673 E002 C9 3A CMPIM ":" 0674 E004 D0 26 BNE NOTCO 0675 E006 C8 INY ;skip past colon 0676 E007 [ TRUE = &00 0677 E007 D1 F2 CMPIY WORK ;is there a second colon? 0678 E009 D0 21 BNE NOTCO ;reject if not 0679 E00B C8 INY ;skip past colon 0680 E00C ] 0681 E00C D1 F2 CMPIY WORK ;three colons? 0682 E00E D0 06 BNE COLON ;if not then get hex 0683 E010 20 9F E0 JSR SKIPSN ;else skip colon and spaces 0684 E013 98 TYA ;command line offset to A 0685 E014 D0 7A BNE CLIFS ;pass rest of line via FSC 3 (always) 0686 E016 COLON 0687 E016 A2 D4 LDXIM INFO +BKEXEC -FBLOCK ;hopefully out of the way 0688 E018 20 92 E2 JSR LSA ;hex to scratch space 0689 E01B 08 PHP ;save result 0690 E01C 20 A0 E0 JSR SKIPSP 0691 E01F 28 PLP 0692 E020 B0 90 BCS COLHEX ;if hex present, call specific ROM 0693 E022 A2 04 LDXIM SVNAME ;else pass to service ROMs only 0694 E024 20 6F F1 JSR SVOP 0695 E027 F0 50 BEQ SVACK 0696 E029 FRIEZE 0697 E029 4C 77 E3 JMP MBDCMD 0698 E02C NOTCO 0699 E02C | 0704 E02C ] 0705 E02C | 0710 E02C ] 0711 E02C ; X=&FF going to 0, point to start of table 0712 E02C A2 FF LDXIM &FF 0713 E02E CLIRST ; restart search at next keyword 0714 E02E A4 E6 LDY CLIRY ; reset pointer to start of user word 0715 E030 88 DEY ;cancel first INY 0716 E031 CLIADV ; compare characters 0717 E031 C8 INY ; advance user word pointer 0718 E032 B1 F2 LDAIY WORK ; fetch user character 0719 E034 29 DF ANDIM &DF ;equate cases 0720 E036 C9 5B CMPIM "Z"+&01 0721 E038 90 02 BCC CLIALF ;if above "Z" 0722 E03A A9 00 LDAIM &00 ;then ensure A<&30, C=0 0723 E03C C9 41 CLIALF CMPIM "A" ;C=1, "A"<=A<="Z" iff alpha 0724 E03E E8 INX ; advance table pointer or skip aux byte 0725 E03F 5D B6 DE EORAX COMTAB ; set b7 from table and compare b6..0 0726 E042 F0 ED BEQ CLIADV ;keywords must be all capital letters 0727 E044 B0 09 BCS CLISKP ;C=1, mismatch or end of keyword, reject 0728 E046 30 07 BMI CLISKP ;C=0, end of both words, accept 0729 E048 B1 F2 LDAIY WORK ;else end of user word, test for abbreviation 0730 E04A C8 INY ;move past the dot 0731 E04B 49 2E EORIM "." 0732 E04D C9 01 CMPIM &01 ;C=1 iff not dot, reject 0733 E04F CLISKP 0734 E04F E8 INX ; skip high byte of action address 0735 E050 CLIALI ; align to keyword terminator 0736 E050 E8 INX ; advance table pointer or skip low byte of action address 0737 E051 BD B4 DE LDAAX COMTAB -&02 ; test table byte at original offset 0738 E054 10 FA BPL CLIALI ;[not reached address hi-byte] 0739 E056 B0 2A BCS CLITMN ;if C=1, compare with next keyword 0740 E058 ;CLIMFN ;full name match 0741 E058 ; found CLI command match 0742 E058 ; construct JMI hi-byte value to command processing code 0743 E058 48 PHA 0744 E059 ; construct JMI lo-byte value to command processing code 0745 E059 BD B5 DE LDAAX COMTAB -&01 0746 E05C 48 PHA 0747 E05D ; skip spaces after command name 0748 E05D 20 A0 E0 JSR SKIPSP 0749 E060 18 CLC ;C=0 used by FXN entry 0750 E061 08 PHP ;status used by EXEC and SPOOL 0751 E062 ; (optionally) make XY -> rest of line 0752 E062 20 66 E0 JSR CLIXYA 0753 E065 40 RTI ;enter command processing routine 0754 E066 0755 E066 0756 E066 CLIXYA ;conditionally make XY -> rest of line 0757 E066 BD B6 DE LDAAX COMTAB 0758 E069 30 0E BMI CLIXY0 ;[keep Y = offset of rest of line from WORK] 0759 E06B CLIXY ;make XY -> rest of command line 0760 E06B 98 TYA ;A = offset of rest of line 0761 E06C BC B6 DE LDYAX COMTAB ;Y := function code 0762 E06F CLIXY2 0763 E06F 18 CLC 0764 E070 65 F2 ADC WORK ;N.B. C=1 => carry 0765 E072 AA TAX ;X = lo-byte of pointer to rest of line 0766 E073 98 TYA ;A = function code 0767 E074 A4 F3 LDY WORK +&01 0768 E076 90 01 BCC CLIXY1 ;[no carry] 0769 E078 ; carry 0770 E078 C8 INY 0771 E079 CLIXY1 ;N.B. Y = hi-byte of pointer to rest of line 0772 E079 CLIXY0 0773 E079 SVACK ;command accepted by service ROM 0774 E079 60 RTS 0775 E07A 0776 E07A 0777 E07A BASIC ;select BASIC language ROM 0778 E07A AE 4B 02 LDX BROMID 0779 E07D 30 06 BMI NBASIC ;[no BASIC ROM] 0780 E07F 4C A7 DB JMP ILR2 ;enter BASIC ROM (N.B. A b0=1, enter with C=1) 0781 E082 0782 E082 CLITMN 0783 E082 0A ASLA 0784 E083 D0 A9 BNE CLIRST 0785 E085 ;else fall through to CLIEND 0786 E085 0787 E085 0788 E085 ;END OF MOS 1.25 0789 E085 ] 0790 E085 0791 E085 LNK MOS39 0001 E085 ; > MOS39 0002 E085 TTL MOS39 CLI 0003 E085 OPT MOS39 Acorn macro assembler Page 74 MOS39 CLI 0004 E085 ;(c) 1981 ACORN 0005 E085 ;BBC MOS 0006 E085 ;Change record: 0007 E085 ;004 29-Jul-81 MP Prototype version 0008 E085 ;Author(s): 0009 E085 ;PB Paul Bond 0010 E085 ;MP Mike Prees 0011 E085 0012 E085 0013 E085 NBASIC ;BASIC ROM not present so offer to service ROMs 0014 E085 CLIEND ;entered here if command not recognised or does not exist 0015 E085 ; offer command to service ROMs 0016 E085 A4 E6 LDY CLIRY ;restore Y offset to point to command name 0017 E087 A2 04 LDXIM SVNAME 0018 E089 20 6F F1 JSR SVOP 0019 E08C F0 EB BEQ SVACK ;[accepted by service ROM] 0020 E08E ; command not accepted by a service ROM 0021 E08E ; so pass command to filing system 0022 E08E A5 E6 LDA CLIRY ;A = offset to command name 0023 E090 [ MOS125 = &7F 0024 E090 [ STARGO = &00 0025 E090 CLIFS 0026 E090 ] 0027 E090 ] 0028 E090 20 6F E0 JSR CLIXY2 ;make XY -> rest of line 0029 E093 A9 03 LDAIM FSNAME 0030 E095 [ MOS125 = &7F 0031 E095 [ STARGO = &00 0032 E095 JMICMD 0033 E095 ;entry for FSC calls 2,3,4,(11) 0034 E095 ;cancel OSARGS 1 intercept, FS provides the tail pointer itself 0035 E095 48 PHA 0036 E096 A9 00 LDAIM &00 0037 E098 8D D1 02 STA TAILHI 0038 E09B 68 PLA 0039 E09C ] 0040 E09C ] 0041 E09C 0042 E09C JMIFSC 0043 E09C 0044 E09C 6C 1E 02 JMI FSCVEC 0045 E09F [ MOS125 = &FF 0054 E09F ] 0055 E09F 0056 E09F 0057 E09F ; ignore space characters 0058 E09F C8 SKIPSN INY ;skip current character 0059 E0A0 B1 F2 SKIPSP LDAIY WORK 0060 E0A2 C9 20 CMPIM SPACE 0061 E0A4 F0 F9 BEQ SKIPSN ;[character is space, ignore] 0062 E0A6 C9 0D SKPSP1 CMPIM MCR 0063 E0A8 ; Z=1 next character is CR 0064 E0A8 ; Z=0 next character is not CR 0065 E0A8 60 RTS 0066 E0A9 SKPCM ;C=0 => check for line end 0067 E0A9 ;C=1 => skip optional comma and check for line end 0068 E0A9 90 F5 BCC SKIPSP 0069 E0AB SKPCOM 0070 E0AB ; skip spaces and an optional comma 0071 E0AB 20 A0 E0 JSR SKIPSP 0072 E0AE C9 2C CMPIM "," 0073 E0B0 D0 F4 BNE SKPSP1 0074 E0B2 C8 INY ;N.B. force Z=0 (i.e. non-zero result) 0075 E0B3 60 RTS 0076 E0B4 ; get decimal number 0077 E0B4 [ MOS125 = &FF 0110 E0B4 | 0111 E0B4 GETNUM 0112 E0B4 20 A0 E0 JSR SKIPSP ;skip leading spaces, A := delimiter 0113 E0B7 20 DC E0 JSR TSTNUM 0114 E0BA B0 13 BCS GN0 0115 E0BC 60 RTS ;C=0 [not a digit] 0116 E0BD 0117 E0BD GNT 0118 E0BD E0 1A CPXIM &1A ;if 26 or more 0119 E0BF B0 2B BCS TSTNR ;then overflow 0120 E0C1 AA TAX ;save last digit read 0121 E0C2 A5 E6 LDA NUMBER 0122 E0C4 0A ASLA ;times 2 0123 E0C5 0A ASLA ;times 4 0124 E0C6 65 E6 ADC NUMBER ;times 5; C=0 0125 E0C8 0A ASLA ;times 10; C=0 0126 E0C9 86 E6 STX NUMBER ;NUMBER := most recently read digit 0127 E0CB ; N.B. C=0 0128 E0CB 65 E6 ADC NUMBER ;A := accumulated value 0129 E0CD B0 1D BCS TSTNR ;[overflow] 0130 E0CF GN0 0131 E0CF 85 E6 STA NUMBER ;NUMBER := accumulated number so far (must save for KEY) 0132 E0D1 AA TAX 0133 E0D2 20 DB E0 JSR TSTNUX ;read digit skipping current character 0134 E0D5 B0 E6 BCS GNT ;process digit [non-digit serves as terminator] 0135 E0D7 C9 0D CMPIM MCR 0136 E0D9 38 SEC 0137 E0DA ; return with: 0138 E0DA ; C=1 => valid number, Z=1/0 => delimiter is/is_not CR, number in X 0139 E0DA 60 RTS 0140 E0DB ] 0141 E0DB 0142 E0DB ; check character is a digit 0143 E0DB TSTNUX 0144 E0DB C8 INY ;skip current character 0145 E0DC TSTNUM 0146 E0DC B1 F2 LDAIY WORK ;get next character 0147 E0DE C9 3A CMPIM &3A ;N.B. $3A = '9' + 1 0148 E0E0 B0 0A BCS TSTNR ;[bad digit, > '9'] 0149 E0E2 C9 30 CMPIM "0" 0150 E0E4 90 06 BCC TSTNR ;[bad digit, < '0'] 0151 E0E6 29 0F ANDIM &0F ;convert to number (do not corrupt V) 0152 E0E8 ; N.B. C=1 0153 E0E8 60 RTS 0154 E0E9 0155 E0E9 TSTNRX 0156 E0E9 20 AB E0 JSR SKPCOM 0157 E0EC TSTNR 0158 E0EC 18 CLC 0159 E0ED ; C=0 bad number, A = delimiting character 0160 E0ED 60 RTS 0161 E0EE 0162 E0EE TSTHEX ;test for, and convert, hex digit 0163 E0EE 20 DC E0 JSR TSTNUM 0164 E0F1 B0 0E BCS TSTH0 ;[is a number, therefore a valid hex digit] Acorn macro assembler Page 75 MOS39 CLI 0165 E0F3 29 DF ANDIM &DF ;force upper case 0166 E0F5 C9 47 CMPIM "G" 0167 E0F7 B0 F0 BCS TSTNRX ;[>'F' so fail] 0168 E0F9 C9 41 CMPIM "A" 0169 E0FB 90 EC BCC TSTNRX ;[<'A' so fail] 0170 E0FD 08 PHP ;save V 0171 E0FE E9 37 SBCIM ALPHAA -&0A ;convert to hex 0172 E100 28 PLP ;restore V 0173 E101 ; C=1 0174 E101 TSTH0 ;C=1 0175 E101 C8 INY 0176 E102 60 RTS 0177 E103 0178 E103 0179 E103 WRCH ;system write character 0180 E103 48 PHA ;save character on stack 0181 E104 8A TXA ;save registers 0182 E105 48 PHA 0183 E106 98 TYA 0184 E107 48 PHA 0185 E108 BA TSX 0186 E109 BD 03 01 LDAAX &0103 ;restore character 0187 E10C 48 PHA 0188 E10D ; A = character 0189 E10D 0190 E10D ; examine WRCH selection(s) 0191 E10D ; 0192 E10D 2C 60 02 BIT NETWRC 0193 E110 10 08 BPL WRCNTN ;[WRCH not to net] 0194 E112 ; WRCH to net 0195 E112 ; A = character 0196 E112 A8 TAY ;send character in Y 0197 E113 A9 04 LDAIM NTWRCH 0198 E115 20 E3 E5 JSR JMINET ;WRCH thru net 0199 E118 B0 52 BCS WRCHNN ;[immediate return to caller] 0200 E11A ; 0201 E11A ; continue within WRCH 0202 E11A ; 0203 E11A WRCNTN 0204 E11A 0205 E11A 18 CLC ;in case VDU not selected 0206 E11B A9 02 LDAIM WRVDU 0207 E11D 2C 7C 02 BIT WRCHSW 0208 E120 D0 05 BNE WRCHNV ;[WRCH not to VDU] 0209 E122 ; WRCH to VDU 0210 E122 68 PLA 0211 E123 48 PHA ;A := character 0212 E124 20 C0 C4 JSR VDU 0213 E127 ; C=0 => VDU says do not print character 0214 E127 WRCHNV ;WRCH not to VDU 0215 E127 0216 E127 ; C=0 => VDU (if selected) says do not print character 0217 E127 ; check who controls printing 0218 E127 A9 08 LDAIM WRPRNT 0219 E129 2C 7C 02 BIT WRCHSW 0220 E12C D0 02 BNE WRCHNC ;[printing not controlled by VDU] 0221 E12E ; printing controlled by VDU 0222 E12E 90 05 BCC WRCHNP ;[VDU says do not print character] 0223 E130 WRCHNC ;conditionally print character 0224 E130 68 PLA 0225 E131 48 PHA ;A := character 0226 E132 20 73 E1 JSR MPRINT ;conditionally print character 0227 E135 WRCHNP ;do not print character 0228 E135 0229 E135 ; check for output to RS423 0230 E135 ; 0231 E135 [ FALSE=0 0235 E135 | 0236 E135 AD 7C 02 LDA WRCHSW 0237 E138 6A RORA ;**************** ASSUME WRRS = 1 **************** 0238 E139 90 1B BCC WRCHNR ;[RS423 disabled] 0239 E13B ] 0240 E13B 0241 E13B ; WRCH via RS423 0242 E13B A4 EA LDY RSTUT 0243 E13D 88 DEY 0244 E13E 10 16 BPL WRCHNR ;[RS423 managed by CFS, ignore WRCH request] 0245 E140 68 PLA 0246 E141 48 PHA ;A := character 0247 E142 ; 0248 E142 08 PHP 0249 E143 78 SEI 0250 E144 A2 02 LDXIM BRSO 0251 E146 48 PHA 0252 E147 20 C1 E4 JSR EXAM 0253 E14A 90 03 BCC WRCNP1 ;[buffer not empty] 0254 E14C ; RS423 output buffer empty 0255 E14C 20 07 E2 JSR RSBUSY ;enable RS423 Tx interrupts 0256 E14F WRCNP1 0257 E14F 68 PLA 0258 E150 A2 02 LDXIM BRSO 0259 E152 20 6B E2 JSR WRITE ;insert character into RS423 output buffer, waiting if necessary 0260 E155 ; N.B. WRITE disables interrupts 0261 E155 ; character not inserted if ESCAPE detected 0262 E155 28 PLP 0263 E156 ; 0264 E156 WRCHNR ;not via RS423 0265 E156 0266 E156 ; check for spooling enabled 0267 E156 ; check whether spooling active 0268 E156 A9 10 LDAIM WRSPL 0269 E158 2C 7C 02 BIT WRCHSW 0270 E15B D0 0F BNE WRCHNS ;[spooling disabled] 0271 E15D ; spool character 0272 E15D AC 57 02 LDY SPOOLH 0273 E160 F0 0A BEQ WRCHNS ;[spooling not active] 0274 E162 ; spooling active 0275 E162 ; write byte to spool file 0276 E162 68 PLA 0277 E163 48 PHA ;A := character 0278 E164 ; 0279 E164 38 SEC 0280 E165 66 EB ROR ESSEMA ;enter critical region 0281 E167 20 D4 FF JSR OSBPUT 0282 E16A 46 EB LSR ESSEMA ;exit critical region 0283 E16C WRCHNS ;no spooling 0284 E16C 0285 E16C WRCHNN 0286 E16C ; exit restoring registers 0287 E16C 68 PLA ;pull redundant byte 0288 E16D [ MOS125 = &FF Acorn macro assembler Page 76 MOS39 CLI 0289 E16D | 0290 E16D PLYXAR 0291 E16D ] 0292 E16D 68 PLA 0293 E16E A8 TAY 0294 E16F 68 PLA 0295 E170 AA TAX 0296 E171 68 PLA ;restore character 0297 E172 60 RTS 0298 E173 0299 E173 MPRINT ;conditionally print character in A 0300 E173 ; N.B. character should never be NUL 0301 E173 ; decide whether to ignore character 0302 E173 2C 7C 02 BIT WRCHSW 0303 E176 70 20 BVS PRINT0 ;[only print thru VDU1] 0304 E178 CD 86 02 CMP PIGNOR 0305 E17B F0 1B BEQ PRINT0 ;[match on printer ignore character] 0306 E17D ; 0307 E17D ; 0308 E17D ; ====== 0309 E17D ; PRINT 0310 E17D ; ====== 0311 E17D ; 0312 E17D ; Print a character via VDU 1 0313 E17D ; 0314 E17D ; ENTRY:- A = Character 0315 E17D ; 0316 E17D ; EXIT:- A,X,Y corrupt 0317 E17D ; Flags preserved 0318 E17D ; 0319 E17D PRINT ;used by VDU (SOH), uses fact of exit with C=0 0320 E17D 08 PHP 0321 E17E 78 SEI 0322 E17F ; N.B. if print sink is 0 then character will 0323 E17F ; eventually be ignored by STROBE 0324 E17F ; 0325 E17F AA TAX ;save print character 0326 E180 ; 0327 E180 ; test whether printer enabled 0328 E180 ; 0329 E180 A9 04 LDAIM WRPREN 0330 E182 2C 7C 02 BIT WRCHSW 0331 E185 D0 10 BNE PRINT4 ;[printer disabled] 0332 E187 ; 0333 E187 8A TXA ;restore print character 0334 E188 A2 03 LDXIM BPRNT ;X := print bufferid 0335 E18A 20 6B E2 JSR WRITE ;write character to buffer, waiting if necessary 0336 E18D B0 08 BCS PRINT3 ;[ESCAPE detected] 0337 E18F ; 0338 E18F ; test printer status; interrupts disabled 0339 E18F ; 0340 E18F 2C D2 02 BIT PFLAG 0341 E192 10 03 BPL PRINT3 ;[printer busy] 0342 E194 ; 0343 E194 ; printer dormant 0344 E194 ; send the first character 0345 E194 ; 0346 E194 20 D3 E1 JSR STROBE ;send character to selected printer 0347 E197 ; 0348 E197 PRINT3 ;printer busy 0349 E197 PRINT4 ;return enabling interrupts 0350 E197 28 PLP ;restore interrupt state, set C=0 (fact used by VDU) 0351 E198 ; 0352 E198 PRINT0 0353 E198 60 RTS 0354 E199 0355 E199 0356 E199 [ MOS125 = &FF 0357 E199 | 0358 E199 FLUSHC ;flush buffer 0359 E199 D0 0F BNE JFLUSH ;[flush currently selected input buffer] 0360 E19B ; X=0 => flush all buffers 0361 E19B FLSHAL ;flush all buffers 0362 E19B A2 08 LDXIM BUPB 0363 E19D FLUSH3 0364 E19D ; allow interrupts 0365 E19D 58 CLI 0366 E19E 78 SEI 0367 E19F 20 A5 E1 JSR FLUSHS ;flush buffer given by X 0368 E1A2 CA DEX 0369 E1A3 10 F8 BPL FLUSH3 0370 E1A5 ; 0371 E1A5 ; N.B. X<0, so is an invalid bufferid (and will be ignored by FLUSHS) 0372 E1A5 ; 0373 E1A5 FLUSHS ;flush specific buffer 0374 E1A5 E0 09 CPXIM BUPB +&01 0375 E1A7 90 04 BCC FLUSH2 ;[valid bufferid] 0376 E1A9 ; invalid bufferid 0377 E1A9 60 RTS 0378 E1AA 0379 E1AA JFLUSH ;flush input buffer and clear soft key expansion 0380 E1AA AE 41 02 LDX RDCHSW ;X := input bufferid 0381 E1AD FLUSH2 0382 E1AD STROB4 ;not user print 0383 E1AD STCRS ;RS423 managed by cassette 0384 E1AD ; ignore print request by purging buffer AND return 0385 E1AD PURGE 0386 E1AD ; purge buffer given by index in X 0387 E1AD ; this routine does not corrupt A or X 0388 E1AD 18 CLC 0389 E1AE ; 0390 E1AE PURGEX ;entered by OSWORD sound routine with C=1 0391 E1AE 48 PHA ;save A 0392 E1AF 08 PHP ;save interrupt state 0393 E1B0 78 SEI 0394 E1B1 ; 0395 E1B1 ; kill sound channel if sound buffer 0396 E1B1 B0 08 BCS PURNSB ;[OSWORD call so do not kill sound] 0397 E1B3 BD D4 E9 LDAAX BUFTYP 0398 E1B6 10 03 BPL PURNSB ;[not a sound buffer] 0399 E1B8 ; kill sound on channel X 0400 E1B8 20 E3 EC JSR SCRST 0401 E1BB PURNSB 0402 E1BB ; 0403 E1BB ; check for input buffer 0404 E1BB E0 02 CPXIM OUTPUT 0405 E1BD B0 08 BCS VAULT ;[output buffer] 0406 E1BF ; 0407 E1BF ; input buffer, kill soft key expansion and VDU queueing 0408 E1BF ; 0409 E1BF A9 00 LDAIM ZERO Acorn macro assembler Page 77 MOS39 CLI 0410 E1C1 8D 68 02 STA SOFKL ;kill soft key expansion 0411 E1C4 8D 6A 02 STA QPOSN ;kill VDU queueing 0412 E1C7 ; 0413 E1C7 ;if input buffer OR first output buffer i.e. RS423 0414 E1C7 ;then Z=1; buffer flag unused, preserve 0415 E1C7 F0 04 VAULT BEQ PURGE3 0416 E1C9 ;otherwise C=1 0417 E1C9 ; flag buffer dormant 0418 E1C9 7E CF 02 RORAX BACTIV 0419 E1CC 38 SEC ;pass C=1; N=1, V=1, Z=* from BIT FFBYT 0420 E1CD ; 0421 E1CD PURGE3 0422 E1CD ; 0423 E1CD 20 9F E7 JSR JMIPUR ;use indirection with V=1 (defaults to CNP) 0424 E1D0 ; 0425 E1D0 28 PLP ;restore interrupt state 0426 E1D1 68 PLA ;restore A 0427 E1D2 60 RTS 0428 E1D3 ] 0429 E1D3 0430 E1D3 STROBE ;send character to selected printer 0431 E1D3 ; **************************************** 0432 E1D3 ; MUST BE ENTERED WITH INTERRUPTS DISABLED 0433 E1D3 ; ********************************** 0434 E1D3 ; determine print sink 0435 E1D3 AD 85 02 LDA PRNTSW 0436 E1D6 F0 D5 BEQ PURGE ;[ignore print request] 0437 E1D8 ; print sink determined by PRNTSW 0438 E1D8 ; 0: infinite print sink 0439 E1D8 ; 1: centronics 0440 E1D8 ; 2: RS423 output 0441 E1D8 ; 3: user print routine 0442 E1D8 ; 4: net printer server 0443 E1D8 [ MOS125 = &FF 0446 E1D8 | 0447 E1D8 C9 02 CMPIM PRS 0448 E1DA B0 21 BCS STROB1 ;[not centronics] 0449 E1DC ] 0450 E1DC ; centronics interface 0451 E1DC ; this code must be executed with interrupts disabled 0452 E1DC ; otherwise a CA1 interrupt coinciding with the STA PAR 0453 E1DC ; would result in a spurious interrupt which would not 0454 E1DC ; be recognised, resulting in a 'Bad IRQ' state 0455 E1DC 20 C6 E4 JSR REMOV ;remove character from print buffer 0456 E1DF 6E D2 02 ROR PFLAG 0457 E1E2 30 43 BMI STROB0 ;[no more characters to print] 0458 E1E4 A0 82 LDYIM &82 0459 E1E6 8C 6E FE STY IERR ;enable parallel port printer interrupt 0460 E1E9 ; write character 0461 E1E9 8D 61 FE STA PAR 0462 E1EC ; pulse strobe line 0463 E1EC AD 6C FE LDA PCRR 0464 E1EF 29 F1 ANDIM &F1 ;********** DO NOT CHANGE 0465 E1F1 09 0C ORAIM CA2LO ;********** DO NOT CHANGE 0466 E1F3 8D 6C FE STA PCRR ;CA2 strobe lo (signal inverted by h/w) 0467 E1F6 09 0E ORAIM CA2HI ;********** DO NOT CHANGE 0468 E1F8 8D 6C FE STA PCRR ;CA2 strobe hi (signal inverted by h/w) 0469 E1FB ; N.B. leave signal hi 0470 E1FB D0 2A BNE STROB0 ;[ALWAYS jump, exit] 0471 E1FD 0472 E1FD STROB1 ;not centronics 0473 E1FD ; X = bufferid 0474 E1FD [ MOS125 = &FF 0476 E1FD ] 0477 E1FD D0 29 BNE STROB3 ;[not RS423] 0478 E1FF ; printer is RS423 0479 E1FF A4 EA LDY RSTUT 0480 E201 88 DEY 0481 E202 10 A9 BPL STCRS ;[RS423 printer managed by CFS, ignore print request] 0482 E204 ; print to RS423 0483 E204 4E D2 02 LSR PFLAG ;flag printer busy 0484 E207 ; 0485 E207 RSBUSY 0486 E207 4E 4F 02 LSR RSFLAG ;flag RS423 busy 0487 E20A ; 0488 E20A RSETX ;enable RS423 Tx interrupts 0489 E20A 20 A5 E7 JSR CNTRS 0490 E20D 90 18 BCC RSOVF ;[RS423 input buffer overflow] 0491 E20F ; 0492 E20F A2 20 LDXIM RHITXE ;set RTS hi, Tx interrupt enabled 0493 E211 ; 0494 E211 RSED ;alter Tx control register to X 0495 E211 A0 9F LDYIM &9F ;field is b6-b5 0496 E213 ; 0497 E213 RS423 0498 E213 08 PHP 0499 E214 78 SEI 0500 E215 98 TYA ;A := mask 0501 E216 ; ***************************************** 0502 E216 ; MUST BE EXECUTED WITH INTERRUPTS DISABLED 0503 E216 ; ***************************************** 0504 E216 ; A = mask (altered) 0505 E216 ; X = new value 0506 E216 86 FA STX RSOP ;save new value of field 0507 E218 2D 50 02 AND RSCTFL ;copy status and clear field for new status 0508 E21B 45 FA EOR RSOP ;add in new status 0509 E21D AE 50 02 LDX RSCTFL ;X := old value 0510 E220 STARSC ;used by MC6850 N.B. does PLP RTS 0511 E220 0512 E220 8D 50 02 STA RSCTFL ;update record of status 0513 E223 8D 08 FE STA RSCTL ;update 6850 0514 E226 28 PLP 0515 E227 RSOVF ;RS423 input buffer overflow 0516 E227 STROB0 0517 E227 60 RTS 0518 E228 0519 E228 STROB3 ;not RS423 0520 E228 0521 E228 18 CLC 0522 E229 0523 E229 ; C=0 0524 E229 ; user or net print 0525 E229 ; X=print_bufferid 0526 E229 ; character in printer buffer 0527 E229 A9 01 LDAIM UPWRCH 0528 E22B 20 39 E2 JSR mUPT ;call print routine (returns with carry meaningful) 0529 E22E PFREE ;indicate printer dormant (OSBYTE call used by UPT routine) 0530 E22E 6E D2 02 ROR PFLAG ;set printer status according to user print routine 0531 E231 ; C=0 => printer busy 0532 E231 ; C=1 => printer free 0533 E231 ; (default user print routine is DEFUPT) Acorn macro assembler Page 78 MOS39 CLI 0534 E231 UPTRTS 0535 E231 60 RTS 0536 E232 0537 E232 0538 E232 UPTINT ;timer interrupt 0539 E232 2C D2 02 BIT PFLAG 0540 E235 30 FA BMI UPTRTS ;[printer dormant] 0541 E237 ; 0542 E237 ; give a hand to polled printers 0543 E237 A9 00 LDAIM UPTIME 0544 E239 ; 0545 E239 MUPT ;call user print routine (also used by VDU software) 0546 E239 ; A = reason code ($02/$03) 0547 E239 A2 03 LDXIM BPRNT ;X := print buffer id 0548 E23B ; 0549 E23B UPTX ;entered by *FX5 0550 E23B AC 85 02 LDY PRNTSW ;Y := current print selection 0551 E23E 20 E3 E5 JSR JMINET ;call net print routine 0552 E241 6C 22 02 JMI UPTVEC ;call user print routine AND return 0553 E244 0554 E244 0555 E244 [ MOS125 = &FF 0598 E244 ] 0599 E244 ; 0600 E244 ; 0601 E244 CNP ;count buffer entries / purge buffer 0602 E244 [ $Tutu 0605 E244 | 0606 E244 50 07 BVC COUNT ;[count buffer entries] 0607 E246 ] 0608 E246 ; 0609 E246 ; purge buffer 0610 E246 ; 0611 E246 ; reset buffer pointers 0612 E246 ; set buffer start = buffer end 0613 E246 BD D8 02 LDAAX BFSTRT 0614 E249 9D E1 02 STAAX BFEND 0615 E24C 60 RTS 0616 E24D ; 0617 E24D ; 0618 E24D COUNT 0619 E24D 08 PHP 0620 E24E 78 SEI 0621 E24F ; 0622 E24F 08 PHP ;save count type 0623 E250 ; 0624 E250 38 SEC 0625 E251 BD E1 02 LDAAX BFEND 0626 E254 FD D8 02 SBCAX BFSTRT 0627 E257 B0 04 BCS BUFNX1 0628 E259 ; adjust for overflow 0629 E259 38 SEC 0630 E25A FD AD E4 SBCAX BFORG 0631 E25D BUFNX1 0632 E25D ; 0633 E25D 28 PLP ;restore count type 0634 E25E ; 0635 E25E 90 06 BCC BFCNT0 ;[input buffer] 0636 E260 ; 0637 E260 ; output buffer 0638 E260 ; adjust to give remaining entries 0639 E260 18 CLC 0640 E261 7D AD E4 ADCAX BFORG 0641 E264 49 FF EORIM &FF 0642 E266 ; 0643 E266 BFCNT0 0644 E266 A0 00 LDYIM ZERO 0645 E268 AA TAX 0646 E269 ; 0647 E269 28 PLP 0648 E26A 60 RTS 0649 E26B 0650 E26B 0651 E26B LNK MOS40 0001 E26B 0002 E26B ; MOS40 0003 E26B TTL MOS40 Machine operating system internal commands 0004 E26B OPT MOS40 Acorn macro assembler Page 79 MOS40 Machine operating system internal commands 0005 E26B ;(c) 1981 ACORN Computers Limited 0006 E26B ;BBC Microcomputer Machine Operating System (MOS) 0007 E26B ;Change record: 0008 E26B ;033 12-Aug-81 PB Reset SKNEND code, check KEY line termination 0009 E26B ;032 12-Aug-81 PB Extracted from CLI code 0010 E26B ;Author(s): 0011 E26B ;PB Paul Bond 0012 E26B ;MP Mike Prees 0013 E26B 0014 E26B 0015 E26B WRITE 0016 E26B WRITE1 0017 E26B 78 SEI ;another critical region 0018 E26C 20 16 E5 JSR INSRT ;attempt to add character to print queue 0019 E26F 90 0F BCC WRITE0 ;[character inserted into printer buffer] 0020 E271 ; printer buffer full 0021 E271 ; C=1 0022 E271 20 11 EA JSR LEDSON ;conditionally set LEDs and test escape condition 0023 E274 ; N.B. does not corrupt C or X 0024 E274 ; C=1 0025 E274 ; reset LEDs 0026 E274 08 PHP 0027 E275 48 PHA 0028 E276 20 22 EF JSR KBDIS 0029 E279 68 PLA 0030 E27A 28 PLP 0031 E27B ; 0032 E27B 30 03 BMI WRITE0 ;[escape detected] 0033 E27D 58 CLI ;enable interrupts to allow printer buffer to purge. 0034 E27E ; Interrupts are enabled at this part of the loop, 0035 E27E ; rather than at the begining (which would save 2 bytes of code) 0036 E27E ; in order to ensure that if the print routine is called with 0037 E27E ; interrupts disabled, then interrupts are not enabled if there is 0038 E27E ; room in the print buffer. 0039 E27E B0 EB BCS WRITE1 ;[ALWAYS jump, wait for room in printer buffer, C=1] 0040 E280 WRITE0 0041 E280 60 RTS 0042 E281 0043 E281 0044 E281 CLRFB ;clear file control block 0045 E281 48 PHA 0046 E282 A9 00 LDAIM ZERO 0047 E284 9D EE 02 STAAX FBLOCK 0048 E287 9D EF 02 STAAX FBLOCK +&01 0049 E28A 9D F0 02 STAAX FBLOCK +&02 0050 E28D 9D F1 02 STAAX FBLOCK +&03 0051 E290 68 PLA 0052 E291 60 RTS 0053 E292 [ MOS125 = &FF 0076 E292 | 0077 E292 20 A0 E0 LSA JSR SKIPSP 0078 E295 20 EE E0 JSR TSTHEX 0079 E298 90 1F BCC LSA0 ;[hex not present, return V=1] 0080 E29A ; 0081 E29A ; clear field 0082 E29A ; 0083 E29A 20 81 E2 JSR CLRFB 0084 E29D ; 0085 E29D ; read address 0086 E29D ; 0087 E29D LSA1 ;rotate hex digit into 4-byte address 0088 E29D ; move nibble into high nibble 0089 E29D ;set b3, clear b2..0 0090 E29D ;SEC ;C=1 from BCC LSA0 (CLRFB preserves) or BCS LSA1 0091 E29D 2A ROLA 0092 E29E 0A ASLA 0093 E29F 0A ASLA 0094 E2A0 0A ASLA 0095 E2A1 ;shift once more. C=hex b3, A b4=1, b3..0=0 0096 E2A1 0A ASLA 0097 E2A2 ROL4A ;rotate bit into address 0098 E2A2 3E EE 02 ROLAX FBLOCK 0099 E2A5 3E EF 02 ROLAX FBLOCK +&01 0100 E2A8 3E F0 02 ROLAX FBLOCK +&02 0101 E2AB 3E F1 02 ROLAX FBLOCK +&03 0102 E2AE B0 35 BCS MBADHX ;[overflow] 0103 E2B0 ; C=0 0104 E2B0 0A ASLA 0105 E2B1 D0 EF BNE ROL4A ;execute loop four times 0106 E2B3 ; C=1 which TSTHEX ignores 0107 E2B3 20 EE E0 JSR TSTHEX 0108 E2B6 B0 E5 BCS LSA1 0109 E2B8 38 SEC ;return C=1 0110 E2B9 LSA0 ;Z=1 => CR terminator 0111 E2B9 60 RTS 0112 E2BA ] 0113 E2BA 0114 E2BA 0115 E2BA LOAD ;LOAD [load address] 0116 E2BA A9 FF LDAIM &FF 0117 E2BC SAVE ;(A=$00) SAVE [exechex] [loadhex] 0118 E2BC 86 F2 STX WORK 0119 E2BE 84 F3 STY WORK +&01 0120 E2C0 8E EE 02 STX FBLOCK+FSTR+&0 0121 E2C3 8C EF 02 STY FBLOCK+FSTR+&1 0122 E2C6 48 PHA 0123 E2C7 ; clear load address 0124 E2C7 A2 02 LDXIM FLOAD 0125 E2C9 20 81 E2 JSR CLRFB 0126 E2CC ; set lsb exec address = $FF (preparing for possible LOAD) 0127 E2CC A0 FF LDYIM &FF 0128 E2CE 8C F4 02 STY FBLOCK+FEXEC ;'use file load address' 0129 E2D1 ; set to read characters from WORK buffer 0130 E2D1 C8 INY ;Y:=0 0131 E2D2 ; skip filename 0132 E2D2 20 82 EA JSR GSINTC 0133 E2D5 20 94 EA LS2 JSR GSREAD 0134 E2D8 90 FB BCC LS2 ;[string character] 0135 E2DA ; determine command type 0136 E2DA 68 PLA 0137 E2DB 48 PHA 0138 E2DC F0 4D BEQ SAVEX ;[SAVE command] 0139 E2DE ; LOAD command 0140 E2DE ; 0141 E2DE ; read load address 0142 E2DE ; N.B. X=FLOAD 0143 E2DE 20 92 E2 JSR LSA 0144 E2E1 B0 3B BCS LOADX1 ;hex present 0145 E2E3 F0 3E BEQ LS0 ;[just CR terminator] 0146 E2E5 MBADHX ;report error 'Bad address' 0147 E2E5 00 BRK Acorn macro assembler Page 80 MOS40 Machine operating system internal commands 0148 E2E6 FC = BADADR 0149 E2E7 42 61 64 = "Bad address" 0150 E2F2 00 = ZERO ;message terminator 0151 E2F3 0152 E2F3 0153 E2F3 SHUTES ;shut EXEC and SPOOL files 0154 E2F3 0155 E2F3 ; 0156 E2F3 ; inform paged ROMs of intentions 0157 E2F3 ; 0158 E2F3 A2 10 LDXIM SVSHES 0159 E2F5 20 6F F1 JSR SVOP 0160 E2F8 F0 23 BEQ SPOOL0 ;[claimed, do not close files] 0161 E2FA ; 0162 E2FA ; deal with EXEC file 0163 E2FA ; 0164 E2FA 20 C3 F6 JSR ECLOSE ;Close EXEC file 0165 E2FD ; 0166 E2FD ; close SPOOL file AND return 0167 E2FD ; 0168 E2FD A9 00 LDAIM ZERO ;Z=1, A=$00 0169 E2FF ; 0170 E2FF SPOOL ;SPOOL 0171 E2FF ; XY -> filename 0172 E2FF ; A = $00 0173 E2FF ; EQ -> spool off 0174 E2FF ;remember whether to just turn spooling off 0175 E2FF 08 PHP 0176 E300 ; close old spool file 0177 E300 84 E6 STY SPOOLY ;save Y 0178 E302 AC 57 02 LDY SPOOLH 0179 E305 8D 57 02 STA SPOOLH ;clear spooling 0180 E308 F0 03 BEQ SPOOL2 ;[not currently spooling] 0181 E30A ; A=0 0182 E30A 20 CE FF JSR OSFIND ;close spool file 0183 E30D SPOOL2 0184 E30D A4 E6 LDY SPOOLY ;restore Y 0185 E30F 28 PLP 0186 E310 F0 0B BEQ SPOOL0 ;[just close spool file] 0187 E312 ; open given spool file 0188 E312 A9 80 LDAIM &80 ;open file for output 0189 E314 20 CE FF JSR OSFIND 0190 E317 A8 TAY 0191 E318 F0 5D BEQ BADFX ;[open failure] 0192 E31A 8D 57 02 STA SPOOLH 0193 E31D SPOOL0 ;Z=1 0194 E31D 60 RTS 0195 E31E 0196 E31E 0197 E31E LOADX1 ;explicit load address given 0198 E31E D0 57 BNE BADFX ;[no CR terminator] 0199 E320 EE F4 02 INC FBLOCK+FEXEC ;use explicit load address 0200 E323 LS0 ;load file 0201 E323 A2 EE LDXIM FBLOCK 0202 E325 A0 02 LDYIM /(FBLOCK ) 0203 E327 68 PLA 0204 E328 4C DD FF JMP OSFILE 0205 E32B ; 0206 E32B [ MOS125 = &FF 0223 E32B ] 0224 E32B ; 0225 E32B ; 0226 E32B SAVEX ;SAVE command 0227 E32B ; 0228 E32B ; read FROM address 0229 E32B ; 0230 E32B A2 0A LDXIM FFROM 0231 E32D 20 92 E2 JSR LSA 0232 E330 90 45 BCC BADFX 0233 E332 ; 0234 E332 ; read TO address 0235 E332 ; check if preceeded by '+' 0236 E332 ; 0237 E332 [ MOS125 = &FF 0243 E332 | 0244 E332 B1 F2 LDAIY WORK 0245 E334 49 AB EORIM "+":EOR:&80 0246 E336 69 FE ADCIM &FE ;c=1, set V iff symbol='+' 0247 E338 50 01 BVC SAVEX3 ;['+' not present] 0248 E33A ] 0249 E33A C8 INY ;skip '+' symbol 0250 E33B SAVEX3 0251 E33B A2 0E LDXIM FTO 0252 E33D 20 92 E2 JSR LSA ;N.B. does not corrupt V 0253 E340 90 35 BCC BADFX ;[to address not given] 0254 E342 ; C=1 0255 E342 08 PHP ;Z => no exec address 0256 E343 ; if '+' was specified then the TO address was really 0257 E343 ; a length specification 0258 E343 50 0F BVC SAVEX4 ;['+' not specified] 0259 E345 ; convert length to end address 0260 E345 ; N.B. C=1 0261 E345 00FC MINUS4 * &00FC 0262 E345 A2 FC LDXIM MINUS4 0263 E347 18 CLC 0264 E348 SAVEX5 0265 E348 BD FC 01 LDAAX FBLOCK+FFROM-MINUS4 0266 E34B 7D 00 02 ADCAX FBLOCK+FTO-MINUS4 0267 E34E 9D 00 02 STAAX FBLOCK+FTO-MINUS4 0268 E351 E8 INX 0269 E352 D0 F4 BNE SAVEX5 ;[execute loop four times] 0270 E354 SAVEX4 ;copy 'from' address to execute and load fields 0271 E354 A2 03 LDXIM &03 0272 E356 SAVEX1 0273 E356 BD F8 02 LDAAX FBLOCK+FFROM 0274 E359 9D F4 02 STAAX FBLOCK+FEXEC 0275 E35C 9D F0 02 STAAX FBLOCK+FLOAD 0276 E35F CA DEX 0277 E360 10 F4 BPL SAVEX1 0278 E362 ; check if exec address present 0279 E362 28 PLP 0280 E363 F0 BE BEQ LS0 ;[no exec address] 0281 E365 ; read exec address 0282 E365 A2 06 LDXIM FEXEC 0283 E367 20 92 E2 JSR LSA 0284 E36A 90 0B BCC BADFX ;[expected exec address not found] 0285 E36C F0 B5 BEQ LS0 ;[no following load address] 0286 E36E ; read load address 0287 E36E A2 02 LDXIM FLOAD 0288 E370 20 92 E2 JSR LSA 0289 E373 90 02 BCC BADFX ;[expected load address not found] Acorn macro assembler Page 81 MOS40 Machine operating system internal commands 0290 E375 F0 AC BEQ LS0 ;[good line termination] 0291 E377 BADFX 0292 E377 MBDCMD 0293 E377 00 BRK ;report error 'Bad command' 0294 E378 FE = BADCMD 0295 E379 42 61 64 = "Bad command" 0296 E384 00 BADKEY BRK ;report error 'Bad KEY' / end of preceeding error message 0297 E385 FB = BADKY 0298 E386 42 61 64 = "Bad key" 0299 E38D 00 = ZERO ;message terminator 0300 E38E 0301 E38E [ MOS125 = &FF 0333 E38E ] 0334 E38E 0335 E38E 0336 E38E 0337 E38E FX ;*FX x,y 0338 E38E 20 B4 E0 JSR GETNUM ;read FX function code 0339 E391 90 E4 BCC BADFX ;[bad FX number] 0340 E393 ; 0341 E393 ; N.B. C=1 0342 E393 ; push function code 0343 E393 ; 0344 E393 8A TXA 0345 E394 FXN ;entry point used by CLI, C=0 0346 E394 48 PHA 0347 E395 A9 00 LDAIM ZERO ;set default argument values 0348 E397 85 E5 STA FXREGX 0349 E399 85 E4 STA FXREGY 0350 E39B ; 0351 E39B ; check for line end 0352 E39B ; 0353 E39B 20 A9 E0 JSR SKPCM ;N.B. C=0 => just check for line end 0354 E39E ; 0355 E39E ; C=1 => skip an optional comma and check for line end 0356 E39E ; 0357 E39E F0 18 BEQ FX1 ;[line end, just a function code] 0358 E3A0 ; 0359 E3A0 ; try reading another argument 0360 E3A0 ; 0361 E3A0 20 B4 E0 JSR GETNUM 0362 E3A3 90 D2 BCC BADFX ;[bad FX number] 0363 E3A5 ; 0364 E3A5 ; N.B. C=1 0365 E3A5 ; 0366 E3A5 86 E5 STX FXREGX 0367 E3A7 ; 0368 E3A7 ; check for line end 0369 E3A7 ; 0370 E3A7 20 AB E0 JSR SKPCOM 0371 E3AA F0 0C BEQ FX1 0372 E3AC ; 0373 E3AC ; try reading another argument 0374 E3AC ; 0375 E3AC 20 B4 E0 JSR GETNUM 0376 E3AF 90 C6 BCC BADFX ;[bad FX number] 0377 E3B1 86 E4 STX FXREGY 0378 E3B3 ; 0379 E3B3 ; ensure line end 0380 E3B3 ; 0381 E3B3 20 A0 E0 JSR SKIPSP 0382 E3B6 D0 BF BNE BADFX ;[bad command termination] 0383 E3B8 ; 0384 E3B8 FX1 0385 E3B8 A4 E4 LDY FXREGY ;load OSBYTE arguments 0386 E3BA A6 E5 LDX FXREGX 0387 E3BC 68 PLA 0388 E3BD 20 F4 FF JSR OSBYTE 0389 E3C0 70 B5 BVS BADFX ;[unrecognised FX code] 0390 E3C2 [ MOS125 = &FF 0391 E3C2 | 0392 E3C2 KEYZAP 0393 E3C2 ] 0394 E3C2 60 RTS 0395 E3C3 0396 E3C3 0397 E3C3 [ MOS125 = &FF 0398 E3C3 | 0399 E3C3 KEY ;KEY 0400 E3C3 20 B4 E0 JSR GETNUM 0401 E3C6 90 BC BCC BADKEY ;[bad soft key number (>255)] 0402 E3C8 ; A = character delimiting number 0403 E3C8 ; X = NUMBER = CSKEY = key number 0404 E3C8 ; Y = soft key number argument 0405 E3C8 ; check soft key number range 0406 E3C8 E0 10 CPXIM NSOFTK 0407 E3CA B0 B8 BCS BADKEY ;[soft_key_number > number of soft keys - 1] 0408 E3CC ; key number in range 0 to NSOFTK-1 0409 E3CC ; 0410 E3CC [ FALSE=0 0413 E3CC ] 0414 E3CC ; 0415 E3CC 20 AB E0 JSR SKPCOM ;skip optional spaces and an optional comma 0416 E3CF 08 PHP ;save line end status 0417 E3D0 AE 10 0B LDX SKEND ;Y points to unused portion of soft key buffer area 0418 E3D3 ; (set to reset SKNEND as it might have been set as a result 0419 E3D3 ; of a 'KEY in use' error) 0420 E3D3 98 TYA 0421 E3D4 48 PHA 0422 E3D5 20 37 E4 JSR SKGCR ;delete soft key (uses value in X) 0423 E3D8 ; on exit X = SKEND 0424 E3D8 68 PLA 0425 E3D9 A8 TAY 0426 E3DA 28 PLP ;restore line end status 0427 E3DB F0 E5 BEQ KEYZAP ; end of line - specified soft key value value has been deleted so return 0428 E3DD ] 0429 E3DD CLI1 0430 E3DD 38 SEC 0431 E3DE 20 83 EA JSR GSINTS ;initialise for reading quoted string 0432 E3E1 CLIWP 0433 E3E1 20 94 EA JSR GSREAD ;read string character 0434 E3E4 B0 08 BCS CLIY ;end of string 0435 E3E6 E8 INX 0436 E3E7 F0 9B BEQ BADKEY ;[buffer full, (N.B. buffer assumed to be 256 bytes long)] 0437 E3E9 ; buffer not full 0438 E3E9 9D 00 0B STAAX SKBUF -&01 ;store character in soft key buffer 0439 E3EC ;(N.B. note offset of -1) 0440 E3EC 90 F3 BCC CLIWP ;[ALWAYS jump, go process next character] 0441 E3EE ; SOFT KEY FINAL CHECK TO SEE IF ANY OTHER KEY SHARES SAME 0442 E3EE ; VALUE POINTER - IF IT DOES THEN SET IT EQUAL TO SKEND 0443 E3EE CLIY Acorn macro assembler Page 82 MOS40 Machine operating system internal commands 0444 E3EE D0 94 BNE BADKEY ;[string not terminated by CR] 0445 E3F0 ; N.B. new buffer end in X 0446 E3F0 08 PHP 0447 E3F1 78 SEI ;** DISABLE INTERRUPTS ** 0448 E3F2 20 37 E4 JSR SKGCR ;delete old soft key and replace with new value (uses value in X) 0449 E3F5 ;N.B. sets Y to specified soft key number 0450 E3F5 A2 10 LDXIM NSOFTK ;X to be roving soft key number 0451 E3F7 CLIYP 0452 E3F7 E4 E6 CPX CSKEY 0453 E3F9 F0 0E BEQ CLIYQ ;[do not process specified soft key] 0454 E3FB BD 00 0B LDAAX SKPTR 0455 E3FE D9 00 0B CMPAY SKPTR ;compare soft key buffer pointers 0456 E401 D0 06 BNE CLIYQ ;[pointers differ] 0457 E403 AD 10 0B LDA SKEND 0458 E406 9D 00 0B STAAX SKPTR ;update soft key buffer pointer 0459 E409 CLIYQ 0460 E409 CA DEX 0461 E40A 10 EB BPL CLIYP ;[go process next soft key] 0462 E40C 28 PLP ;** ENABLE INTERRUPTS ** 0463 E40D 60 RTS 0464 E40E 0465 E40E 0466 E40E SKSIZE ;A := size of soft key given by Y 0467 E40E ; ** THIS MODULE DISABLES INTERRUPTS ** 0468 E40E ; this routine is called by soft key set (via *KEY command) 0469 E40E ; and soft key read (via RDCH processing). 0470 E40E ; the choice is to duplicate the code, using a distinct work slot, 0471 E40E ; or share the code within a critical region in order that SKSZWK 0472 E40E ; may be shared 0473 E40E 08 PHP ;save interrupt state 0474 E40F 78 SEI ;** DISABLE INTERRUPTS ** 0475 E410 AD 10 0B LDA SKEND 0476 E413 38 SEC 0477 E414 F9 00 0B SBCAY SKPTR 0478 E417 85 FB STA SKSZWK ;SKSZWK := number of bytes to end of buffer 0479 E419 8A TXA 0480 E41A 48 PHA ;push X 0481 E41B A2 10 LDXIM NSOFTK ;X is roving soft key number 0482 E41D SKS1 0483 E41D BD 00 0B LDAAX SKPTR 0484 E420 38 SEC 0485 E421 F9 00 0B SBCAY SKPTR ;A := length of soft key w.r.t. specified soft key 0486 E424 90 08 BCC SKS2 ;[ignore negative length] 0487 E426 F0 06 BEQ SKS2 ;[ignore zero length] 0488 E428 C5 FB CMP SKSZWK 0489 E42A B0 02 BCS SKS2 ;[this length >= past lengths] 0490 E42C 85 FB STA SKSZWK ;remember new minimum length 0491 E42E CA SKS2 DEX 0492 E42F 10 EC BPL SKS1 ;[go process next soft key] 0493 E431 68 PLA 0494 E432 AA TAX ;restore X 0495 E433 A5 FB LDA SKSZWK 0496 E435 28 PLP ;** RESTORE INTERRUPT STATE ** 0497 E436 ; A := length of soft key string 0498 E436 ; Y := soft key number given on entry 0499 E436 60 RTS 0500 E437 0501 E437 0502 E437 ; SOFT KEY BUFFER GARBAGE COLLECTION ROUTINE.STRING 0503 E437 ; FOR KEY NUMBER GIVEN IN 'CSKEY' IS DELETED & ALL 0504 E437 ; POINTERS ADJUSTED ACC 0505 E437 SKGCR ;delete (and insert) key value(s) 0506 E437 ;** THIS MODULE DISABLES INTERRUPTS ** 0507 E437 08 PHP ;** SAVE INTERRUPT STATE OF CALLER ** 0508 E438 78 SEI ;** DISABLE INTERRUPTS ** 0509 E439 ; save new end address 0510 E439 8A TXA 0511 E43A 48 PHA 0512 E43B A4 E6 LDY CSKEY ;Y is specified soft key number 0513 E43D 20 0E E4 JSR SKSIZE ;A := length of soft key string 0514 E440 ; NOW SKSZWK = LENGTH OF CURRENT SK STRING 0515 E440 ; SO SETUP FOR DELETING THIS STRING. 0516 E440 B9 00 0B LDAAY SKPTR 0517 E443 A8 TAY ;Y points to specified soft key string 0518 E444 18 CLC 0519 E445 65 FB ADC SKSZWK 0520 E447 AA TAX ;X points to start of byte area to be moved down 0521 E448 85 FA STA KEYSV 0522 E44A ; TO AVOID MASHING POINTER STRUCTURE IF 0523 E44A ; MACHINE CRASHES ELSEWHERE,IT IS ESSENTIAL 0524 E44A ; THAT INTERRUPTS ARE *OFF* FOR THIS NEXT BIT 0525 E44A ; before altering the data structure, check that a soft key 0526 E44A ; is not being used by RDCH 0527 E44A AD 68 02 LDA SOFKL ;A := length of soft key in use by RDCH 0528 E44D F0 0D BEQ SK3 ;[no soft key in use] 0529 E44F ; soft key being 'unwound' by RDCH 0530 E44F ; N.B. altering the data structure would confuse RDCH 0531 E44F 00 BRK ;report error 'KEY in use' 0532 E450 FA = KEYUSE 0533 E451 4B 65 79 = "Key in use" 0534 E45B 00 = ZERO ;end of error message 0535 E45C 0536 E45C SK3 0537 E45C CE 84 02 DEC USKFLG ;indicate update of soft keys in progress (USKFLG<>0) 0538 E45F 68 PLA ;A := new end of buffer 0539 E460 38 SEC 0540 E461 E5 FA SBC KEYSV 0541 E463 85 FA STA KEYSV ;KEYSV := number of bytes to copy 0542 E465 F0 0C BEQ SKGCV ;[zero bytes to copy] 0543 E467 SKGCS 0544 E467 BD 01 0B LDAAX SKBUF ;*MOVE 0545 E46A 99 01 0B STAAY SKBUF ;*CHARACTERS 0546 E46D C8 INY 0547 E46E E8 INX 0548 E46F C6 FA DEC KEYSV 0549 E471 D0 F4 BNE SKGCS ;[more bytes to copy] 0550 E473 ; NOW ADJUST ALL POINTERS WHICH ARE GREATER 0551 E473 ; THAN THE ONE AT CSKEY. 0552 E473 SKGCV 0553 E473 ; save new end address 0554 E473 98 TYA 0555 E474 48 PHA 0556 E475 A4 E6 LDY CSKEY ;Y is specified soft key number 0557 E477 A2 10 LDXIM NSOFTK ;X is roving soft key number, including end pointer 0558 E479 SKGCT 0559 E479 BD 00 0B LDAAX SKPTR 0560 E47C D9 00 0B CMPAY SKPTR 0561 E47F 90 07 BCC SKGCU ;[current pointer precedes specified pointer] 0562 E481 [ TRUE=0 0563 E481 F0 05 BEQ SKGCU ;[current pointer equals specified pointer] 0564 E483 ] Acorn macro assembler Page 83 MOS40 Machine operating system internal commands 0565 E483 ; current pointer is beyond specified pointer 0566 E483 ; if pointers are equal then specified soft key was null ... 0567 E483 ; ... therefore its size was zero and a drop thru is a no-operation 0568 E483 ; C=1 0569 E483 E5 FB SBC SKSZWK ;C already 1 0570 E485 9D 00 0B STAAX SKPTR ;adjust current buffer pointer 0571 E488 SKGCU 0572 E488 CA DEX 0573 E489 10 EE BPL SKGCT ;[go process next soft key] 0574 E48B ; NOW UPDATE CURRENT KEY POINTER 0575 E48B AD 10 0B LDA SKEND 0576 E48E 99 00 0B STAAY SKPTR ;adjust specified soft key pointer to point to end of buffer 0577 E491 68 PLA ;A := new end address 0578 E492 8D 10 0B STA SKEND ;make end buffer pointers equal 0579 E495 AA TAX ;X := new end of buffer pointer 0580 E496 EE 84 02 INC USKFLG ;indicate update of soft keys over (USKFLG=0) 0581 E499 28 PLP ;** RESTORE INTERRUPT STATE OF CALLER ** 0582 E49A ; X = SKEND 0583 E49A ; Y = specified soft key number 0584 E49A 60 RTS 0585 E49B LNK MOS42 0001 E49B 0002 E49B ; > MOS42 0003 E49B TTL MOS42 Buffer management 0004 E49B OPT MOS42 Acorn macro assembler Page 84 MOS42 Buffer management 0005 E49B ;(c) 1981 ACORN Computers Limited 0006 E49B ;BBC Microcomputer Machine Operating System (MOS) 0007 E49B ;Change record: 0008 E49B ;201 01-May-82 PB EVENT restores A 0009 E49B ;004 29-Jul-81 MP Prototype version 0010 E49B ;Author(s): 0011 E49B ;PB Paul Bond 0012 E49B ;MP Mike Prees 0013 E49B ; buffer address table (hi byte) 0014 E49B BFADHI 0015 E49B 03 = /(RDCHBF+RDCHSZ-&0100 ) 0016 E49C 0A = /(RSRIBF+RSRISZ-&0100 ) 0017 E49D 08 = /(RSROBF+RSROSZ-&0100 ) 0018 E49E 07 = /(PRNBF+PRNSZ-&0100 ) 0019 E49F 07 = /(SNDBF1+SBSIZE-&0100 ) 0020 E4A0 07 = /(SNDBF2+SBSIZE-&0100 ) 0021 E4A1 07 = /(SNDBF3+SBSIZE-&0100 ) 0022 E4A2 07 = /(SNDBF4+SBSIZE-&0100 ) 0023 E4A3 09 = /(SPCHBF+SPCHSZ-&0100 ) 0024 E4A4 ; buffer address table (lo byte) 0025 E4A4 BFADLO 0026 E4A4 00 = RDCHBF+RDCHSZ-&0100 ;RDCH (keyboard) buffer 0027 E4A5 00 = RSRIBF+RSRISZ-&0100 ;RS423 input 0028 E4A6 C0 = RSROBF+RSROSZ-&0100 ;RS423 output 0029 E4A7 C0 = PRNBF+PRNSZ-&0100 ;print 0030 E4A8 50 = SNDBF1+SBSIZE-&0100 ;sound channel 1 0031 E4A9 60 = SNDBF2+SBSIZE-&0100 ;sound channel 2 0032 E4AA 70 = SNDBF3+SBSIZE-&0100 ;sound channel 3 0033 E4AB 80 = SNDBF4+SBSIZE-&0100 ;sound channel 4 0034 E4AC 00 = SPCHBF+SPCHSZ-&0100 ;speech 0035 E4AD ; buffer origin offsets within page 0036 E4AD BFORG 0037 E4AD E0 = &0100-RDCHSZ 0038 E4AE 00 = &0100-RSRISZ 0039 E4AF 40 = &0100-RSROSZ 0040 E4B0 C0 = &0100-PRNSZ 0041 E4B1 F0 = &0100-SBSIZE 0042 E4B2 F0 = &0100-SBSIZE 0043 E4B3 F0 = &0100-SBSIZE 0044 E4B4 F0 = &0100-SBSIZE 0045 E4B5 C0 = &0100-SPCHSZ 0046 E4B6 ; general buffer manipulation routines 0047 E4B6 SETBUF 0048 E4B6 ; set buffer pointer 0049 E4B6 BD A4 E4 LDAAX BFADLO 0050 E4B9 85 FA STA BUFFLO 0051 E4BB BD 9B E4 LDAAX BFADHI 0052 E4BE 85 FB STA BUFFHI 0053 E4C0 60 RTS 0054 E4C1 0055 E4C1 0056 E4C1 EXAM ;examine character in buffer 0057 E4C1 2C 47 D9 BIT FFBYT ;V=1 => examine option 0058 E4C4 70 01 BVS EXAM1 ;[ALWAYS jump] 0059 E4C6 ; NEVER fall thru 0060 E4C6 REMOV ;remove character from buffer 0061 E4C6 B8 CLV ;V=0 => indicate remove option 0062 E4C7 ; X = buffer index 0063 E4C7 ; V=0 => remove, V=1 => examine 0064 E4C7 EXAM1 ;entered with V=1 0065 E4C7 ; 0066 E4C7 6C 2C 02 JMI REMVEC ;use indirection (defaults to REM) 0067 E4CA ; 0068 E4CA REM 0069 E4CA [ $Tutu 0072 E4CA | 0073 E4CA ; disable interrupts 0074 E4CA 08 PHP 0075 E4CB 78 SEI 0076 E4CC ] 0077 E4CC ; get buffer start pointer 0078 E4CC BD D8 02 LDAAX BFSTRT 0079 E4CF DD E1 02 CMPAX BFEND 0080 E4D2 F0 72 BEQ REMOV1 0081 E4D4 A8 TAY ;Y := buffer start pointer 0082 E4D5 ; set buffer pointer 0083 E4D5 20 B6 E4 JSR SETBUF 0084 E4D8 ; remove character from buffer 0085 E4D8 B1 FA LDAIY BUFFLO 0086 E4DA 70 1B BVS REMOV3 ;[examine option, exit with character] 0087 E4DC 48 PHA ;push character 0088 E4DD ; update buffer start pointer 0089 E4DD C8 INY 0090 E4DE 98 TYA 0091 E4DF D0 03 BNE REMOV2 0092 E4E1 ; wraparound 0093 E4E1 BD AD E4 LDAAX BFORG 0094 E4E4 REMOV2 0095 E4E4 9D D8 02 STAAX BFSTRT 0096 E4E7 ; check for removal of last character in buffer 0097 E4E7 ; N.B. this code is only executed for the remove option 0098 E4E7 E0 02 CPXIM OUTPUT 0099 E4E9 90 0A BCC REMOV4 ;[input buffer, buffer empty event not applicable] 0100 E4EB DD E1 02 CMPAX BFEND 0101 E4EE D0 05 BNE REMOV4 ;[not last character] 0102 E4F0 ; signal buffer empty event 0103 E4F0 A0 00 LDYIM EVMPTY 0104 E4F2 20 FA E4 JSR EVENT 0105 E4F5 REMOV4 0106 E4F5 68 PLA ;restore character read 0107 E4F6 A8 TAY ;Y := character 0108 E4F7 REMOV3 ;return with C=0 indicating removal successful 0109 E4F7 28 PLP ;restore interrupt state 0110 E4F8 18 CLC 0111 E4F9 60 RTS 0112 E4FA 0113 E4FA 0114 E4FA EVENT ;signal event given by Y, optional arguments given in A & X 0115 E4FA ; this routine must not corrupt A 0116 E4FA 08 PHP 0117 E4FB 78 SEI 0118 E4FC 48 PHA ;save A 0119 E4FD 85 FA STA EVENTA ;save A 0120 E4FF B9 BF 02 LDAAY EVENTS 0121 E502 F0 41 BEQ EVENT0 ;[event disabled] 0122 E504 ; event enabled, call event routine 0123 E504 98 TYA ;A = event code 0124 E505 A4 FA LDY EVENTA ;Y := argument passed originally in A 0125 E507 20 D2 F0 JSR JMIEVT ;A = event code, must not corrupt X 0126 E50A 68 PLA ;restore A 0127 E50B 28 PLP Acorn macro assembler Page 85 MOS42 Buffer management 0128 E50C 18 CLC ;indicate event was enabled 0129 E50D 60 RTS 0130 E50E 0131 E50E CKESCY ;insert character in Y into buffer 0132 E50E ; 0133 E50E ; signal input event 0134 E50E ; 0135 E50E 98 TYA ;A := character 0136 E50F A0 02 LDYIM EVKYBD 0137 E511 20 FA E4 JSR EVENT ;assumes A and X not corrupted 0138 E514 A8 TAY 0139 E515 INSERT ;FX call to insert character into buffer 0140 E515 98 TYA 0141 E516 INSRT ;insert character into buffer 0142 E516 ; 0143 E516 6C 2A 02 JMI INSVEC ;use indirection (defaults to INS) 0144 E519 ; 0145 E519 INS 0146 E519 ; A = character 0147 E519 ; X = buffer index 0148 E519 [ $Tutu 0151 E519 | 0152 E519 ; disable interrupts 0153 E519 08 PHP 0154 E51A 78 SEI 0155 E51B ] 0156 E51B ; save character 0157 E51B 48 PHA 0158 E51C ; construct buffer end offset in Y 0159 E51C BC E1 02 LDYAX BFEND 0160 E51F C8 INY 0161 E520 D0 03 BNE INSRT2 0162 E522 ; buffer wraparound 0163 E522 BC AD E4 LDYAX BFORG 0164 E525 INSRT2 0165 E525 98 TYA 0166 E526 DD D8 02 CMPAX BFSTRT 0167 E529 F0 0F BEQ INSRT1 ;[buffer full] 0168 E52B ; update buffer end pointer 0169 E52B BC E1 02 LDYAX BFEND 0170 E52E 9D E1 02 STAAX BFEND 0171 E531 ; construct buffer pointer 0172 E531 20 B6 E4 JSR SETBUF 0173 E534 ; store character in buffer 0174 E534 68 PLA ;A := character 0175 E535 91 FA STAIY BUFFLO 0176 E537 ; return with C=0 => insert successful 0177 E537 28 PLP ;restore interrupt state 0178 E538 18 CLC 0179 E539 60 RTS 0180 E53A 0181 E53A INSRT1 ;signal buffer full event 0182 E53A 68 PLA ;restore character 0183 E53B E0 02 CPXIM OUTPUT 0184 E53D B0 07 BCS INOBUF ;[output buffer, buffer full event not applicable] 0185 E53F ; signal input buffer full event 0186 E53F A0 01 LDYIM EVFULL 0187 E541 20 FA E4 JSR EVENT ;A=character, X=bufferid 0188 E544 ; (N.B. does not corrupt A, should not corrupt X) 0189 E544 48 PHA ;compensate for following PLA 0190 E545 EVENT0 ;indicate event was disabled 0191 E545 68 PLA 0192 E546 INOBUF ;output buffer, buffer full event not applicable 0193 E546 REMOV1 ;return with C=1 => insert/remove failed due to buffer full/empty 0194 E546 28 PLP ;restore interrupt state 0195 E547 38 SEC 0196 E548 60 RTS 0197 E549 0198 E549 0199 E549 CAPS ;test for an uppercase letter 0200 E549 0201 E549 [ MOS125 = &FF 0214 E549 | 0215 E549 48 PHA 0216 E54A ;Must preserve V during LOADGO->SRCH0->LOOK->CMPFT->CAPS 0217 E54A ;ANDIM &DF;CMPIM "A";EORIM &FF;RORA;ADCIM "Z":SHR:1 0218 E54A ;ORAIM &20;CMPIM "z"+&01;EORIM &FF;RORA;ADCIM ("a":SHR:1):OR:&80 0219 E54A 29 DF ANDIM &DF 0220 E54C C9 5B CMPIM "Z"+&01 0221 E54E B0 04 BCS CAPSX 0222 E550 49 FF EORIM &FF 0223 E552 C9 BF CMPIM "A"-&01:EOR:&FF 0224 E554 CAPSX 0225 E554 68 PLA 0226 E555 ; C=0 => Pass, C=1 => Fail 0227 E555 60 RTS 0228 E556 ] 0229 E556 0230 E556 0231 E556 RDCHS ;insert character into RDCH (keyboard) buffer 0232 E556 A2 00 LDXIM BRDCH 0233 E558 RNSRT 0234 E558 ; insert character Y into buffer whose index is X, 0235 E558 ; checking for the interrupt character (default ASCII escape) 0236 E558 ; 0237 E558 ; RS423 8 bit does not detect interrupt character 0238 E558 8A TXA 0239 E559 2D 45 02 AND RS8BIT 0240 E55C D0 B7 BNE INSERT ;[RSI & RS423-8-bit, no input event] 0241 E55E ; 0242 E55E 98 TYA 0243 E55F 4D 6C 02 EOR INTCH ;default INTCH is ESC 0244 E562 0D 75 02 ORA ESCHAR ;treat as character? 0245 E565 D0 A7 BNE CKESCY ;[not escape character or let escape thru, take no action] 0246 E567 ; 0247 E567 ; ESC detected - ignore ? 0248 E567 AD 58 02 LDA CRIT 0249 E56A 6A RORA 0250 E56B 98 TYA ;A := character 0251 E56C B0 0A BCS CLCRTS ;[ignore escape] 0252 E56E ; 0253 E56E A0 06 LDYIM EVESC 0254 E570 20 FA E4 JSR EVENT ;N.B. does not corrupt A 0255 E573 90 03 BCC CKESC1 ;[event was enabled, no need to take default action] 0256 E575 ; 0257 E575 ; event was disabled, so take default action 0258 E575 ; default escape routine 0259 E575 ; C=1 0260 E575 20 D9 E6 JSR CESCPS ;set escape flag **** MUST USE ROUTINE CESCPS **** 0261 E578 CKESC1 ;character 'inserted' successfully 0262 E578 CLCRTS Acorn macro assembler Page 86 MOS42 Buffer management 0263 E578 18 CLC 0264 E579 ; C=0 => character inserted OK, C=1 => character not inserted 0265 E579 60 RTS ;RETURN - do not insert ESC into buffer 0266 E57A 0267 E57A RDCHGX ;check for cursor option 1 0268 E57A 6A RORA 0269 E57B 68 PLA 0270 E57C B0 79 BCS RDCHGCLC ;[option 1 active, return &87..&8B] 0271 E57E ; treat as cursor option 2 0272 E57E RDCHGS ;process character as real softkey 0273 E57E 98 TYA ;A := character 0274 E57F ; 0275 E57F 48 PHA 0276 E580 4A LSRA 0277 E581 4A LSRA 0278 E582 4A LSRA 0279 E583 4A LSRA 0280 E584 ; 0281 E584 49 04 EORIM &04 ;fudge to tie in with frozen documentation 0282 E586 A8 TAY 0283 E587 ; character on stack 0284 E587 ; 0285 E587 B9 65 02 LDAAY SOFTLO-&08 0286 E58A C9 01 CMPIM &01 ;test softkey range option 0287 E58C F0 6B BEQ GKEY ;[expand softkey] 0288 E58E 68 PLA ;restore character 0289 E58F 90 0D BCC RDCHG1 ;[ignore key] 0290 E591 ; return byte code 0291 E591 ; C=1 0292 E591 29 0F ANDIM &0F ;A := offset of soft key 0293 E593 18 CLC 0294 E594 79 65 02 ADCAY SOFTLO-&08 0295 E597 0296 E597 18 CLC 0297 E598 60 RTS ;read successful, character in A 0298 E599 0299 E599 0300 E599 RDCHGB 0301 E599 ; invalid character at cursor position 0302 E599 ; complain by transmitting BEL 0303 E599 20 99 E8 JSR BELL ;**** N.B. NOT THRU OSWRCH **** must restore X 0304 E59C 68 PLA 0305 E59D AA TAX ;restore X 0306 E59E ; get next character 0307 E59E ; 0308 E59E RDCHG1 ;process character from currently selected input buffer 0309 E59E 20 C6 E4 JSR REMOV ;get character from buffer 0310 E5A1 B0 55 BCS RDCHG0 ;[buffer empty, C=1] 0311 E5A3 ; 0312 E5A3 ; C=0 0313 E5A3 ; 0314 E5A3 ; character is in A 0315 E5A3 ; 0316 E5A3 ; check whether to set RTS hi for RS423 input 0317 E5A3 ; save A 0318 E5A3 48 PHA 0319 E5A4 ; 0320 E5A4 ; check for RS423 input buffer 0321 E5A4 E0 01 CPXIM BRSI 0322 E5A6 D0 06 BNE RDCHL ;[keyboard buffer, C=0] 0323 E5A8 ; 0324 E5A8 20 0A E2 JSR RSETX ;set RHITXE if applicable 0325 E5AB ; 0326 E5AB A2 01 LDXIM BRSI ;restore bufferid 0327 E5AD 38 SEC 0328 E5AE ; 0329 E5AE RDCHL ;do not alter RTS 0330 E5AE ; C=0 => keyboard, C=1 => RS423 0331 E5AE ; 0332 E5AE ; restore A 0333 E5AE 68 PLA 0334 E5AF ; 0335 E5AF 90 05 BCC RDCHK ;[keyboard] 0336 E5B1 ; 0337 E5B1 ; RS423 0338 E5B1 ; 0339 E5B1 AC 45 02 LDY RS8BIT 0340 E5B4 D0 41 BNE RDCHGCLC ;[let RS423 deliver 8 bit codes] 0341 E5B6 RDCHK 0342 E5B6 ; 0343 E5B6 ; test to see if it is a softkey (real or pseudo) 0344 E5B6 A8 TAY ;Y := character 0345 E5B7 10 3E BPL RDCHGCLC ;[not a soft key (top bit zero), C=0] 0346 E5B9 0347 E5B9 [ FALSE=0 0350 E5B9 ] 0351 E5B9 0352 E5B9 ; character is a softkey 0353 E5B9 ; check for cursor control key 0354 E5B9 29 0F ANDIM &0F 0355 E5BB C9 0B CMPIM MCOPY-SOFTK0 0356 E5BD 90 BF BCC RDCHGS ;[not a cursor control, therefore a real softkey] 0357 E5BF ; cursor control key 0358 E5BF ; C=1 0359 E5BF ; convert character to codes &87..&8B 0360 E5BF 69 7B ADCIM &87-MCOPY+SOFTK0-&1 0361 E5C1 48 PHA ;save converted code, real character still in Y 0362 E5C2 ; there are 3 cursor options (selected by *FX4) 0363 E5C2 ; 0 cursor edit VDU 0364 E5C2 ; 1 return codes &87..&8B 0365 E5C2 ; 2 treat as softkey 0366 E5C2 AD 7D 02 LDA CURSED 0367 E5C5 D0 B3 BNE RDCHGX ;[not option 0] 0368 E5C7 ; option 0 0369 E5C7 ; check if output to VDU 0370 E5C7 AD 7C 02 LDA WRCHSW 0371 E5CA 6A RORA 0372 E5CB 6A RORA 0373 E5CC 68 PLA ;restore converted code 0374 E5CD B0 CF BCS RDCHG1 ;[ignore character, output not to VDU] 0375 E5CF ; let VDU process code 0376 E5CF C9 87 CMPIM &87 0377 E5D1 F0 38 BEQ RDCHGY ;[COPY key] 0378 E5D3 ; cursor direction key 0379 E5D3 A8 TAY ;save X 0380 E5D4 8A TXA 0381 E5D5 48 PHA 0382 E5D6 98 TYA 0383 E5D7 20 5E D8 JSR VDUB ;N.B. cursor control entry point 0384 E5DA 68 PLA 0385 E5DB AA TAX ;restore X Acorn macro assembler Page 87 MOS42 Buffer management 0386 E5DC ; falling thru will transfer control to RDCHG1 0387 E5DC RDCHG 0388 E5DC ; FETCH CHAR FROM RDCH BUFFER 0389 E5DC ; EXPAND SOFT KEYS AS NECESSARY 0390 E5DC ; PASS CURSOR CONTROL KEYS 0391 E5DC ; STRAIGHT TO VDU DRIVER 0392 E5DC ; RETURN CARRY SET IF CHARACTER 0393 E5DC ; AVAILABLE 0394 E5DC ; 0395 E5DC ; check for ECONET interception 0396 E5DC ; 0397 E5DC 2C 5F 02 BIT NETRDC 0398 E5DF 10 05 BPL RDCHNM ;[normal RDCH] 0399 E5E1 ; 0400 E5E1 ; let network supply character 0401 E5E1 ; 0402 E5E1 A9 06 LDAIM NTRDCH 0403 E5E3 6C 24 02 JMINET JMI NETVEC ;network operation call, results returned in A and C 0404 E5E6 0405 E5E6 0406 E5E6 RDCHNM ;not reading from network 0407 E5E6 AD 68 02 LDA SOFKL 0408 E5E9 F0 B3 BEQ RDCHG1 ;[no pending soft key expansion] 0409 E5EB AC C9 02 LDY SOFKP 0410 E5EE B9 01 0B LDAAY SKBUF ;GET EXPANSION CHAR 0411 E5F1 EE C9 02 INC SOFKP ;increment pointer into soft key buffer 0412 E5F4 CE 68 02 DEC SOFKL ;decrement remaining count of soft key characters 0413 E5F7 RDCHGCLC 0414 E5F7 18 CLC ;C=0 => character read successfully 0415 E5F8 RDCHG0 0416 E5F8 60 RTS 0417 E5F9 0418 E5F9 GKEY ;soft key detected AND soft keys enabled 0419 E5F9 68 PLA ;restore softkey code 0420 E5FA 29 0F ANDIM &0F ;convert to soft key number in range 0-15 (assumes SFTKY0=$x0)) 0421 E5FC A8 TAY ;Y := soft key number 0422 E5FD 20 0E E4 JSR SKSIZE ;A := length of soft key string given by Y 0423 E600 8D 68 02 STA SOFKL ;SOFKL := length of soft key string 0424 E603 ; N.B. X = soft key number 0425 E603 B9 00 0B LDAAY SKPTR 0426 E606 8D C9 02 STA SOFKP ;SOFKP points to key string (N.B. pointer always <> 0) 0427 E609 D0 D1 BNE RDCHG ;[ALWAYS JUMP] 0428 E60B 0429 E60B RDCHGY ;copy character at text cursor position 0430 E60B 8A TXA 0431 E60C 48 PHA ;save X 0432 E60D 20 95 D8 JSR COPYCH ;N.B. VDU sets Z bit, but this is not used 0433 E610 A8 TAY ;save character 0434 E611 F0 86 BEQ RDCHGB ;[invalid character at text cursor] 0435 E613 ; valid character at cursor position 0436 E613 68 PLA 0437 E614 AA TAX ;restore X 0438 E615 98 TYA ;restore character 0439 E616 ; C=0, character in A 0440 E616 18 CLC 0441 E617 60 RTS 0442 E618 0443 E618 0444 E618 LNK MOS44 0001 E618 ; > MOS44 0002 E618 TTL MOS44 OSBYTE routines 0003 E618 OPT MOS44 Acorn macro assembler Page 88 MOS44 OSBYTE routines 0004 E618 ;(c) 1981 ACORN Computers Limited 0005 E618 ;BBC Microcomputer Machine Operating System (MOS) 0006 E618 ;Change record: 0007 E618 ;01-Mar-82 PB PEEK and POKE introduced 0008 E618 ;Author(s): 0009 E618 ;PB Paul Bond 0010 E618 0011 E618 0012 E618 BYTET ;table for OSBYTE. N.B. lo-byte followed by hi-byte 0013 E618 ; 0014 E618 ; 0 indicate version number 0015 E618 ; X=0 => BRK message 0016 E618 ; X<>0 => return version number in X 0017 E618 7B EA & VER 0018 E61A 0019 E61A ; 0020 E61A ; 1 set value 0021 E61A AF E9 & V2B156 0022 E61C 0023 E61C ; 0024 E61C ; 2 select input stream 0025 E61C ; X=0 => select keyboard, disable RS423 0026 E61C ; X=1 => select RS423, enable RS423 0027 E61C ; X=2 => select keyboard, enable RS423 0028 E61C 37 E7 & SELIN 0029 E61E 0030 E61E ; 0031 E61E ; 3 select output stream(s) 0032 E61E ; X=rrrrspvl 0033 E61E ; r (reserved) 0034 E61E ; s=0 => spooling enabled 0035 E61E ; p=0 => printing enabled 0036 E61E ; v=0 => output to VDU enabled 0037 E61E ; l=1 => output to RS423 enabled 0038 E61E BE E9 & V2B34 0039 E620 0040 E620 ; 0041 E620 ; 4 enable/disable cursor edit 0042 E620 ; X=0 => cursor editing enabled 0043 E620 ; X=1 => COPY/LEFT/RIGHT/DOWN/UP return $87/$88/$89/$8A/$8B 0044 E620 ; X=2 => COPY/LEFT/RIGHT/DOWN/UP at as soft keys 11 thru 15 0045 E620 BE E9 & V2B34 0046 E622 0047 E622 ; 0048 E622 ; 5 select print destination 0049 E622 ; X=0 => infinite sink 0050 E622 ; X=1 => centronics 0051 E622 ; X=2 => RS423 0052 E622 9D E9 & SPRINT 0053 E624 0054 E624 ; 0055 E624 ; 6 set printer ignore character 0056 E624 ; X=0 => ignore no characters 0057 E624 ; X<>0 => ignore character 0058 E624 AF E9 & V2B156 0059 E626 0060 E626 ; 0061 E626 ; 7 set RS423 receive baud rate 0062 E626 ; X=0 => set default (9600) 0063 E626 ; X=1/2/3/4/5/6/7/8 => 75/150/300/1200/2400/4800/9600/19200 0064 E626 EF E6 & RXBAUD 0065 E628 0066 E628 ; 0067 E628 ; 8 set RS423 trasmit baud rate 0068 E628 ; [values as for OSBYTE(7)] 0069 E628 ED E6 & TXBAUD 0070 E62A 0071 E62A ; 0072 E62A ; 9 set flash mark period 0073 E62A ; X=0 => infinite 0074 E62A ; X<>0 => * 20 milliseconds 0075 E62A 14 E7 & FMRK 0076 E62C 0077 E62C ; 0078 E62C ; 10 set flash space period 0079 E62C ; 9 set flash mark period 0080 E62C ; X=0 => infinite 0081 E62C ; X<>0 => * 20 milliseconds 0082 E62C 16 E7 & FSPC 0083 E62E 0084 E62E ; 0085 E62E ; 11 set auto-repeat delay period 0086 E62E ; X=0 => suppress auto-repeat 0087 E62E ; X<>0 => set delay between first and second character to centiseconds 0088 E62E BC E9 & ARDLY 0089 E630 0090 E630 ; 0091 E630 ; 12 set auto-repeat repeat period 0092 E630 ; X=0 => set delay and period to values on power-up 0093 E630 ; X<>0 => set period between subsequent characters to centiseconds 0094 E630 B3 E9 & ARRPT 0095 E632 0096 E632 ; 0097 E632 ; 13 disable event 0098 E632 ; X=event_code 0099 E632 ; 0: output buffer empty 0100 E632 ; 1: input buffer full 0101 E632 ; 2: character entering input buffer 0102 E632 ; 3: ADC conversion complete 0103 E632 ; 4: vertical SYNC 0104 E632 ; 5: interval timer crossing zero 0105 E632 ; 6: ESCAPE detected 0106 E632 ; 7: RS423 error 0107 E632 5D E7 & MDSABL 0108 E634 0109 E634 ; 0110 E634 ; 14 enable event 0111 E634 ; [values as for OSBYTE(13)] 0112 E634 5E E7 & ENABLE 0113 E636 0114 E636 ; 0115 E636 ; 15 flush buffer class 0116 E636 ; X=0 => flush all buffers 0117 E636 ; X=1 => flush currently selected input buffer 0118 E636 99 E1 & FLUSHC 0119 E638 0120 E638 ; 0121 E638 ; 16 select number of ADC channels 0122 E638 ; X=0 => stop scanning ADC channels 0123 E638 ; X=1/2/3/4 => only scan channels 1 thru 0124 E638 6A E7 & SETADC Acorn macro assembler Page 89 MOS44 OSBYTE routines 0125 E63A 0126 E63A ; 0127 E63A ; 17 start ADC conversion on channel X 0128 E63A ; X=1/2/3/4 => start conversion on channel 0129 E63A 36 DE & ADCBEG 0130 E63C 0131 E63C ; 0132 E63C ; 18 reset soft keys 0133 E63C EF E9 & RSOFT 0134 E63E 0135 E63E ; 0136 E63E ; 19 wait for vertical sync 0137 E63E DD E9 & WFVS 0138 E640 0139 E640 ; 0140 E640 ; 20 implode/explode soft font 0141 E640 FD CC & FONT 0142 E642 0143 E642 ; 0144 E642 ; 21 flush specific buffer 0145 E642 A5 E1 & FLUSHS 0146 E644 0147 E644 ; 0148 E644 0016 BYTEL * .-BYTET:SHR: 1 ;next entry in BYTETL table (lo component) 0149 E644 ; 0150 E644 BYTET2 0151 E644 0075 BYTEM * &0075 0152 E644 ; 0153 E644 ; 0154 E644 96 E8 & VDUST ;read VDU status; $75 0155 E646 0156 E646 ; 0157 E646 00 EA & MOSTST ;reflect state of KSTAT; $76 0158 E648 0159 E648 ; 0160 E648 F3 E2 & SHUTES ;close EXEC and SPOOL files; $77 0161 E64A 0162 E64A ; 0163 E64A 55 F2 & OLDKEY ;set keyboard old key; $78 0164 E64C 0165 E64C ; 0166 E64C D8 F0 & XSCANB ;scan keyboard at specific address; $79 0167 E64E 0168 E64E ; 0169 E64E D6 F0 & XSCANA ;scan keyboard from matrix entry $10; $7A 0170 E650 0171 E650 ; 0172 E650 2E E2 & PFREE ;indicate printer dormant; $7B 0173 E652 0174 E652 ; 0175 E652 D8 E6 & CESCPC ;clear escape flag; $7C 0176 E654 0177 E654 ; 0178 E654 D9 E6 & CESCPS ;set escape flag; $7D 0179 E656 0180 E656 ; 0181 E656 C1 E6 & CESCP ;clear escape flag and purge selected input buffer; $7E 0182 E658 0183 E658 ; 0184 E658 C3 F0 & EOF ;end of file; $7F 0185 E65A 0186 E65A ; 0187 E65A ; $80 0188 E65A ;; read data on ADC channel 0189 E65A ; in: Y>=0 => X=0 => read control information 0190 E65A ; X<>0 => read last conversion on channel X 0191 E65A ; Y<0 => read info for buffer NOT(X) 0192 E65A ; out: Y>=0 => X=0 => X=fire-buttons, Y=last-channel-to-convert 0193 E65A ; X<>0 => X=lo-data, Y=hi-data 0194 E65A ; Y<0 => X=buffer-count (input: bytes ready, output: bytes left) 0195 E65A B3 E7 & RADCX 0196 E65C 0197 E65C ; 0198 E65C ; $81 0199 E65C ; read key with time limit 0200 E65C ; in: Y>=0 => X=lo-count, Y=hi-count (centiseconds) 0201 E65C ; Y<0 => X=NOT(key-matrix-address) 0202 E65C ; out: Y>=0 => Y=$00 => X=character 0203 E65C ; Y=$1B => escape condition detected 0204 E65C ; Y=$FF => timeout 0205 E65C ; Y<0 => X=0 => key not pressed 0206 E65C ; X<>0 => key pressed 0207 E65C 77 E7 & INKY 0208 E65E 0209 E65E ; 0210 E65E ; $82 0211 E65E ; read machine high order address 0212 E65E ; out: X = lo-component, Y = hi-component 0213 E65E 8D E7 & RMHA 0214 E660 0215 E660 ; 0216 E660 ; $83 0217 E660 ; read operating system high water mark 0218 E660 ; out: X = lo-address, Y = hi-address 0219 E660 B2 F0 & RMLA 0220 E662 0221 E662 ; 0222 E662 ; $84 0223 E662 ; read address of start of current screen mode 0224 E662 ; out: X = lo-address, Y = hi-address 0225 E662 B3 D8 & TOPCMD 0226 E664 0227 E664 ; 0228 E664 ; $85 0229 E664 ; read address of start of screen for mode X 0230 E664 ; in: X = mode 0231 E664 ; out: X = lo-address, Y = hi-address 0232 E664 B6 D8 & TOPMDX 0233 E666 0234 E666 ; 0235 E666 ; $86 0236 E666 ;; read text cursor position 0237 E666 ; out: X = x-text-coord, Y = y-text-coord 0238 E666 E3 D5 & CSRPOS 0239 E668 0240 E668 ; 0241 E668 ; $87 0242 E668 ;; read character at text cursor 0243 E668 ; out: X=0 => no character at cursor position 0244 E668 ; X<>0 => X=character 0245 E668 ; Y = current screen mode Acorn macro assembler Page 90 MOS44 OSBYTE routines 0246 E668 5B D7 & READCH 0247 E66A 0248 E66A ; 0249 E66A ; $88 0250 E66A ; *CODE X, Y 0251 E66A ; in: X = arg, Y = arg 0252 E66A ; out: C = return code 0253 E66A ; X = return code 0254 E66A ; Y = return code 0255 E66A BC E6 & MCODE 0256 E66C 0257 E66C ; 0258 E66C ; $89 0259 E66C ; *MOTOR X, Y 0260 E66C ; in: X=0 => turn motor off 0261 E66C ; X=1 => turn motor on 0262 E66C ; Y => motor selection 0263 E66C E3 E6 & MOTOR ;MOTOR command; $89 0264 E66E 0265 E66E ; 0266 E66E ; $8A 0267 E66E ; insert character into buffer 0268 E66E ; in: X = bufferid, Y = character 0269 E66E 15 E5 & INSERT 0270 E670 0271 E670 ; 0272 E670 ; $8B 0273 E670 ; *OPT X, Y 0274 E670 ; in: X = arg, Y = arg (effect is filing system dependent) 0275 E670 C2 F0 & OPT 0276 E672 0277 E672 ; 0278 E672 ; $8C 0279 E672 ; *TAPE X, Y 0280 E672 ; in: X=0 => tape filing system at default baud rate (1200 baud) 0281 E672 ; X=3 => tape filing system at 300 baud 0282 E672 ; X=12 => tape filing system at 1200 baud 0283 E672 ; Y=$00 => tape filing system is cassette 0284 E672 ; Y=$FF => tape filing system is ROMs 0285 E672 4A F1 & TAPE 0286 E674 0287 E674 ; 0288 E674 ; $8D 0289 E674 ; *ROM X, Y 0290 E674 ; X and Y ignored 0291 E674 4A F1 & CROM 0292 E676 0293 E676 ; 0294 E676 ; $8E 0295 E676 ; enter language 0296 E676 ; in: X = ROMid of language, Y = arg 0297 E676 A8 DB & SELANG 0298 E678 0299 E678 ; 0300 E678 ; $8F 0301 E678 ; call paged ROM function 0302 E678 ; in: X = reason code, Y = arg 0303 E678 ; out: C = return code 0304 E678 ; Y = return code 0305 E678 6F F1 & SVOP 0306 E67A 0307 E67A ; 0308 E67A ; $90 0309 E67A ; alter TV characteristics 0310 E67A ; in: X = vertical sync adjust, Y = interlace adjust 0311 E67A 4D EB & TV 0312 E67C 0313 E67C ; 0314 E67C ; $91 0315 E67C ; remove character from buffer 0316 E67C ; in: X = bufferid 0317 E67C ; out: C=0 => Y=character 0318 E67C ; C=1 => buffer empty 0319 E67C C6 E4 & REMOV 0320 E67E 0321 E67E [ MOS125 = &FF 0360 E67E | 0361 E67E ; 0362 E67E ; $92 0363 E67E ; read from FRED 0364 E67E ; in: X = offset 0365 E67E ; out: Y = value 0366 E67E 44 EA & CHEQUE 0367 E680 0368 E680 ; 0369 E680 ; $93 0370 E680 ; write to FRED 0371 E680 ; in: X = offset, Y = value 0372 E680 44 EA & CHEQUE 0373 E682 0374 E682 ; 0375 E682 ; $94 0376 E682 ; read from JIM 0377 E682 ; in: X = offset 0378 E682 ; out: Y = value 0379 E682 44 EA & CHEQUE 0380 E684 0381 E684 ; 0382 E684 ; $95 0383 E684 ; write to JIM 0384 E684 ; in: X = offset, Y = value 0385 E684 44 EA & CHEQUE 0386 E686 0387 E686 ; 0388 E686 ; $96 0389 E686 ; read from SHEILA 0390 E686 ; in: X = offset 0391 E686 ; out: Y = value 0392 E686 44 EA & CHEQUE 0393 E688 0394 E688 ; 0395 E688 ; $97 0396 E688 ; write to SHEILA 0397 E688 ; in: X = offset, Y = value 0398 E688 44 EA & CHEQUE 0399 E68A ] 0400 E68A 0401 E68A ; 0402 E68A ; $98 0403 E68A ; examine character in buffer 0404 E68A ; in: X = bufferid Acorn macro assembler Page 91 MOS44 OSBYTE routines 0405 E68A ; out: C=0 => Y=character 0406 E68A ; C=1 => buffer empty 0407 E68A C1 E4 & EXAM 0408 E68C 0409 E68C ; 0410 E68C ; $99 0411 E68C ; insert character into buffer dealing with ESC code 0412 E68C ; in: X = bufferid, Y = character 0413 E68C 58 E5 & RNSRT 0414 E68E 0415 E68E ; 0416 E68E ;; $9A 0417 E68E ; update vidproc control register 0418 E68E ; in: X = value 0419 E68E 26 EA & VP0 0420 E690 0421 E690 ; 0422 E690 ; $9B 0423 E690 ; update vidproc palette register 0424 E690 ; in: X = value EOR $07 0425 E690 37 EA & VP1 0426 E692 0427 E692 ; 0428 E692 ; $9C 0429 E692 ; update 6850 ACIA 0430 E692 ; in: X = value, Y = mask 0431 E692 13 E2 & RS423 0432 E694 0433 E694 ; 0434 E694 ; $9D 0435 E694 ; fast tube BPUT 0436 E694 ; in: X = byte, Y = handle 0437 E694 66 FF & FXBPUT 0438 E696 0439 E696 ; 0440 E696 ; $9E 0441 E696 ; read from speech chip 0442 E696 ; in: Y = command 0443 E696 ; out: Y = result 0444 E696 A7 EE & RSPECH 0445 E698 0446 E698 ; 0447 E698 ; $9F 0448 E698 ; write to speech chip 0449 E698 ; in: Y = command 0450 E698 B9 EE & WSPECH 0451 E69A 0452 E69A ; 0453 E69A ; $A0 0454 E69A ; read VDU variables 0455 E69A ; in: X = index 0456 E69A ; out: X = variable0, Y = variable1 0457 E69A E7 E9 & VDUVAR 0458 E69C 0459 E69C ; 0460 E69C 00A1 BYTEH * .-BYTET2:SHR: 1+BYTEM ;next entry in BYTET table (hi component) 0461 E69C ; 0462 E69C C3 E9 & SETV ;set variable 0463 E69E 0464 E69E ; 0465 E69E BE E6 & JMIUSR ;OSWORD calls >=$E0 0466 E6A0 0467 E6A0 0468 E6A0 0469 E6A0 WORDT ;table for OSWORD. N.B. lo-byte followed by hi-byte 0470 E6A0 ; 0471 E6A0 25 E9 & RDLN ;read line; $00 0472 E6A2 0473 E6A2 ; 0474 E6A2 FB E8 & RATM ;read absolute time; $01 0475 E6A4 0476 E6A4 ; 0477 E6A4 0A E9 & WATM ;write absolute time; $02 0478 E6A6 0479 E6A6 ; 0480 E6A6 F7 E8 & RITM ;read interval time; $03 0481 E6A8 0482 E6A8 ; 0483 E6A8 0E E9 & WITM ;write interval time; $04 0484 E6AA 0485 E6AA ; 0486 E6AA 68 EA & PEEK ;PEEK; $05 0487 E6AC 0488 E6AC ; 0489 E6AC 69 EA & POKE ;POKE; $06 0490 E6AE 0491 E6AE ; 0492 E6AE 0007 OSWSND * .-WORDT:SHR: 1 0493 E6AE ; 0494 E6AE 57 E8 & NOTE ;sound; $07 0495 E6B0 0496 E6B0 ; 0497 E6B0 D8 E8 & NVLP ;define envelope; $08 0498 E6B2 0499 E6B2 ; 0500 E6B2 34 C7 & RPXLXY ;read pixel at given coordinate to X; $09 0501 E6B4 0502 E6B4 ; 0503 E6B4 CF CB & RCHDEF ;read character definition of XY to XY+1..8; $0A 0504 E6B6 0505 E6B6 ; 0506 E6B6 7A C7 & RPALET ;read palette for XY to XY+1..4; $0B 0507 E6B8 0508 E6B8 ; 0509 E6B8 C6 C8 & PRPAL ;programme palette; $0C 0510 E6BA 0511 E6BA ; 0512 E6BA 7F D5 & CSREAD ;cursor read; $0D 0513 E6BC 0514 E6BC ; 0515 E6BC 000E WORDN * .-WORDT:SHR: 1 ;number of entries in WORDT table 0516 E6BC 0517 E6BC 0518 E6BC [ NOSP = &00 0520 E6BC | 0521 E6BC MCODE ;call user code 0522 E6BC A9 00 LDAIM ZERO 0523 E6BE 6C 00 02 JMIUSR JMI USRVEC ;user OSBYTE call/OSWORD calls 0524 E6C1 ] 0525 E6C1 0526 E6C1 Acorn macro assembler Page 92 MOS44 OSBYTE routines 0527 E6C1 ; OSBYTE specific routines 0528 E6C1 ; N.B. routines must exit with PLP to restore 0529 E6C1 ; caller's interrupt state 0530 E6C1 CESCP ;clear escape flag ad purge selected input buffer 0531 E6C1 A2 00 LDXIM ZERO ;indicate escape not cleared 0532 E6C3 24 FF BIT ESCFLG 0533 E6C5 10 11 BPL CESCPC ;[no escape to clear] 0534 E6C7 ; bypass procedure ? 0535 E6C7 AD 76 02 LDA EAOPT 0536 E6CA D0 0A BNE CESCX ;[bypass normal acknowledge procedure] 0537 E6CC ; Z=1, A=$00 0538 E6CC ; close exec file 0539 E6CC 58 CLI ;********** (close may be a long operation) 0540 E6CD 8D 69 02 STA LINES ;reset page mode page origin 0541 E6D0 20 C5 F6 JSR EXEC ;just close exec file, N.B. needs Z=1, A=$00 0542 E6D3 ; flush all buffers and clear soft key expansion 0543 E6D3 20 9B E1 JSR FLSHAL ;N.B. also kills sound AND cancels VDU queueing 0544 E6D6 CESCX 0545 E6D6 A2 FF LDXIM &FF ;indicate escape cleared 0546 E6D8 CESCPC ;clear system escape flag 0547 E6D8 18 CLC 0548 E6D9 CESCPS ;set system escape flag (N.B. C=1) 0549 E6D9 66 FF ROR ESCFLG 0550 E6DB 2C 7A 02 BIT TUBEM 0551 E6DE [ MOS125 = &FF 0554 E6DE | 0555 E6DE 10 33 BPL TESCO ;[tube inactive] 0556 E6E0 ] 0557 E6E0 ; 0558 E6E0 TESC 0559 E6E0 4C 03 04 JMP TBESC ;tube escape 0560 E6E3 0561 E6E3 0562 E6E3 MOTOR ;control cassette motor 0563 E6E3 ; on entry: X=0 => motor off 0564 E6E3 ; X<>0 => motor on 0565 E6E3 ; N.B. previous instruction was LDX 0566 E6E3 AD 82 02 LDA SPREGA 0567 E6E6 A8 TAY ;Y := old value 0568 E6E7 ; 0569 E6E7 2A ROLA 0570 E6E8 E0 01 CPXIM &01 ;C=0 => X=0, C=1 => X<>0 0571 E6EA 6A RORA 0572 E6EB 50 1E BVC STASP ;[ALWAYS jump] 0573 E6ED 0574 E6ED 0575 E6ED TXBAUD ;set RS423 transmit baudrate (N.B. A=$08) 0576 E6ED A9 38 LDAIM &38 0577 E6EF RXBAUD ;set RS423 receive baudrate (N.B. A=$07) 0578 E6EF 49 3F EORIM &3F ;Rx: A=$38, Tx: A=$07 0579 E6F1 85 FA STA MASK 0580 E6F3 AC 82 02 LDY SPREGA 0581 E6F6 E0 09 CPXIM &09 0582 E6F8 B0 17 BCS BAUD1 ;[bad baud selection] 0583 E6FA 3D D4 E9 ANDAX BAUDS ;extract serproc baud bits 0584 E6FD 85 FB STA BAUD 0585 E6FF 98 TYA 0586 E700 05 FA ORA MASK 0587 E702 45 FA EOR MASK ;clear slot for baudrate 0588 E704 05 FB ORA BAUD 0589 E706 09 40 ORAIM &40 ;set cassette/RS423 bit 0590 E708 4D 5D 02 EOR RSCASS ;select cassette/RS423 0591 E70B ; 0592 E70B STASP ;used by MOTOR and RESET 0593 E70B 8D 82 02 STA SPREGA 0594 E70E 8D 10 FE STA SERPRC 0595 E711 ; 0596 E711 BAUD1 0597 E711 TYATAX ;used by TXBAUD, RXBAUD, FSPC, FMRK 0598 E711 98 TYA 0599 E712 BADEVT 0600 E712 AA TAX ;X := old value (bad events appear disabled) 0601 E713 [ MOS125 = &FF 0602 E713 | 0603 E713 TESCO 0604 E713 ] 0605 E713 60 RTS 0606 E714 0607 E714 0608 E714 FMRK ;set flash mark, Y=0, C=1 0609 E714 C8 INY 0610 E715 18 CLC 0611 E716 ; 0612 E716 ; Y=1, C=0 0613 E716 ; 0614 E716 FSPC ;set flash space, Y=0, C=1 0615 E716 B9 52 02 LDAAY FLASHB 0616 E719 ; 0617 E719 48 PHA 0618 E71A 8A TXA 0619 E71B 99 52 02 STAAY FLASHB 0620 E71E 68 PLA 0621 E71F ; 0622 E71F A8 TAY 0623 E720 ; 0624 E720 ; C=0 => mark, C=1 => space 0625 E720 ; FMS0 exit used, despite X not being corrupted 0626 E720 ; (makes code clearer) 0627 E720 AD 51 02 LDA FLCNT 0628 E723 D0 10 BNE FMS1 ;[flash enabled] 0629 E725 ; 'kick' flash count 0630 E725 8E 51 02 STX FLCNT 0631 E728 ; force mark/space (lsb VPREGA := C) 0632 E728 AD 48 02 LDA VPREGA 0633 E72B [ MOS125 = &FF 0638 E72B | 0639 E72B ;same size, faster, reduce stack load 0640 E72B 29 FE ANDIM &FE 0641 E72D 69 00 ADCIM &00 ;V=0 0642 E72F ] 0643 E72F 8D 48 02 STA VPREGA 0644 E732 8D 20 FE STA VPROC0 0645 E735 FMS1 ; chain from clear escape condition routine 0646 E735 50 DA BVC TYATAX ;[ALWAYS jump] 0647 E737 0648 E737 0649 E737 SELIN ;select input 0650 E737 8A TXA 0651 E738 29 01 ANDIM &01 ;force legal bufferid 0652 E73A 48 PHA ;save change 0653 E73B AD 50 02 LDA RSCTFL ;A := old state of controller status Acorn macro assembler Page 93 MOS44 OSBYTE routines 0654 E73E 2A ROLA 0655 E73F E0 01 CPXIM &01 ;C=0 => disable RS423, C=1 => enable RS423 0656 E741 6A RORA ;A := new state of controller status 0657 E742 ; *FX 2,0 disables RS423, *FX 2,(1,2) enables RS423 0658 E742 ; if RS423 then enable RS423 Rx interrupt 0659 E742 CD 50 02 CMP RSCTFL 0660 E745 08 PHP 0661 E746 8D 50 02 STA RSCTFL 0662 E749 8D 08 FE STA RSCTL ;update RS423 control register 0663 E74C 20 0A E2 JSR RSETX ;set RHITXE if possible 0664 E74F 28 PLP 0665 E750 F0 03 BEQ SELIN1 ;branch if no change 0666 E752 2C 09 FE BIT RSDATA ;purge character in controller 0667 E755 ; this purges data register if: disabled state -> enabled state 0668 E755 ; this does not matter if: enabled state -> disabled state 0669 E755 SELIN1 0670 E755 AE 41 02 LDX RDCHSW ;X := old value 0671 E758 68 PLA 0672 E759 8D 41 02 STA RDCHSW ;update value 0673 E75C 60 RTS 0674 E75D 0675 E75D 0676 E75D MDSABL ;disable event X 0677 E75D ; N.B. Y=0 0678 E75D 98 TYA ;A := 0 0679 E75E ;* LDAIM ZERO 0680 E75E ENABLE ;enable event X (N.B. A<>$00) 0681 E75E E0 0A CPXIM NEVENT 0682 E760 B0 B0 BCS BADEVT 0683 E762 BC BF 02 LDYAX EVENTS 0684 E765 9D BF 02 STAAX EVENTS 0685 E768 ; 0686 E768 50 A7 BVC TYATAX ;[ALWAYS jump] 0687 E76A 0688 E76A 0689 E76A SETADC ;set number of ADC channels to scan 0690 E76A ; N.B. preceeding instruction was LDX 0691 E76A ; Y=0 0692 E76A F0 03 BEQ SETAD1 ;[kill ADC (eventually)] 0693 E76C 20 36 DE JSR ADCBEG ;initiate conversion on channel X, uses Y=0 0694 E76F ; N.B. X not corrupted 0695 E76F SETAD1 0696 E76F ; a value of X=0 stops the ADC after the next (external) channel 1 0697 E76F ; conversion 0698 E76F AD 4D 02 LDA MAXADC 0699 E772 8E 4D 02 STX MAXADC 0700 E775 AA TAX ;X := old value 0701 E776 60 RTS 0702 E777 0703 E777 0704 E777 INKY ;read key with time limit 0705 E777 98 TYA 0706 E778 30 0B BMI RDKY 0707 E77A 58 CLI ;**** ENABLE INTERRUPTS 0708 E77B 20 65 DE JSR INKEY 0709 E77E B0 03 BCS INKY1 ;[escape detected or count exhausted] 0710 E780 ; 0711 E780 ; character read 0712 E780 ; 0713 E780 AA TAX ;X := character (INKEY) or lo-count (BUFN) 0714 E781 A9 00 LDAIM ZERO ;Y = 0 => success 0715 E783 ; 0716 E783 INKY1 ;escape detected or count exhausted, C=1 0717 E783 A8 TAY ;Y < $80 => escape, Y >= $80 => count exhausted 0718 E784 60 RTS 0719 E785 0720 E785 0721 E785 RDKY ;C=1, V=0, read key addressed by X 0722 E785 ; N.B. interrupts disabled 0723 E785 ; 0724 E785 ; test key at matrix address 0725 E785 ; 0726 E785 [ $Tutu 0734 E785 | 0735 E785 8A TXA 0736 E786 49 7F EORIM &7F 0737 E788 AA TAX 0738 E789 20 95 F0 JSR JMIKEY 0739 E78C 2A ROLA ;result into C 0740 E78D ] 0741 E78D ; 0742 E78D BADADC ;entered with C=1 0743 E78D RMHA ;entered with C=1 0744 E78D ; C=0 => return 0, C=1 => return -1 0745 E78D A2 FF LDXIM &FF ;N.B. I/O processor is notionally located at address $FFFFxxxx 0746 E78F A0 FF LDYIM &FF 0747 E791 B0 02 BCS RDKY0 0748 E793 ; INKEY entry (key open) 0749 E793 E8 INX ;X=0 0750 E794 ; invalid soft key read, return Y<>0 0751 E794 C8 INY ;Y=0 (except for soft key read entry) 0752 E795 RDKY0 0753 E795 60 RTS 0754 E796 0755 E796 0756 E796 BUFN ;count entries in buffer, called by FX ADVAL with negative argument 0757 E796 ; -N gives count for buffer with external id N 0758 E796 ; C=1 (by FX conventions) 0759 E796 8A TXA 0760 E797 49 FF EORIM &FF 0761 E799 AA TAX ;X := bufferid 0762 E79A ; 0763 E79A ; count entries (in)/(remaining in) buffer given by X 0764 E79A ; returns: 0765 E79A ; number of entries present for input buffers 0766 E79A ; number of entries remaining for output buffers 0767 E79A ; 0768 E79A E0 02 CPXIM OUTPUT 0769 E79C ; C=0 => count used entries 0770 E79C ; C=1 => count free slots 0771 E79C ; 0772 E79C JMICNT 0773 E79C B8 CLV ;V=0 => count buffer entry 0774 E79D 50 03 BVC JMICNP ;[ALWAYS jump] 0775 E79F ; 0776 E79F 2C 47 D9 JMIPUR BIT FFBYT ;V=1 0777 E7A2 6C 2E 02 JMICNP JMI CNPVEC ;use indirection (defaults to CNP) 0778 E7A5 ; return count in X (lo) and Y (hi) 0779 E7A5 0780 E7A5 0781 E7A5 CNTRS ;count bytes left in RS423 input buffer Acorn macro assembler Page 94 MOS44 OSBYTE routines 0782 E7A5 38 SEC ;count empty slots left ... 0783 E7A6 A2 01 LDXIM BRSI ;... in RS423 input buffer 0784 E7A8 20 9C E7 JSR JMICNT 0785 E7AB ; count in Y (hi) and X (lo) 0786 E7AB C0 01 CPYIM &01 0787 E7AD B0 03 BCS CNTRS0 ;[more than RSOVER bytes left] 0788 E7AF ; 0789 E7AF EC 5B 02 CPX RSHLVL 0790 E7B2 ; 0791 E7B2 CNTRS0 0792 E7B2 ; C=0 => overflow 0793 E7B2 ; C=1 => no overflow 0794 E7B2 60 RTS 0795 E7B3 0796 E7B3 0797 E7B3 RADCX ;read ADC channel X 0798 E7B3 [ MOS125 = &FF 0803 E7B3 | 0804 E7B3 30 E1 BMI BUFN ;[count entries in buffer] 0805 E7B5 E0 05 CPXIM &05 0806 E7B7 B0 D4 BCS BADADC 0807 E7B9 8A TXA 0808 E7BA F0 08 BEQ FIRE ;[get status of fire buttons] 0809 E7BC ] 0810 E7BC ; return latest conversion 0811 E7BC BC B9 02 LDYAX ADCHIV -&01 0812 E7BF BD B5 02 LDAAX ADCLOV -&01 0813 E7C2 AA TAX ;X := lo-byte 0814 E7C3 60 RTS 0815 E7C4 0816 E7C4 0817 E7C4 FIRE ;get status of fire buttons 0818 E7C4 [ MOS125 = &FF 0826 E7C4 | 0827 E7C4 ; X=0, A=0, C=0 0828 E7C4 ED 40 FE SBC PBQ ;take one's complement of system VIA port B 0829 E7C7 6A RORA 0830 E7C8 6A RORA 0831 E7C9 6A RORA 0832 E7CA 6A RORA 0833 E7CB ] 0834 E7CB 29 03 ANDIM &03 ;A := fire buttons 0835 E7CD AC BE 02 LDY ADCFLG ;return latest conversion number 0836 E7D0 ; clear latest conversion number 0837 E7D0 8E BE 02 STX ADCFLG 0838 E7D3 AA TAX ;return status of fire buttons in b0 and b1 0839 E7D4 60 RTS 0840 E7D5 0841 E7D5 0842 E7D5 LNK MOS46 0001 E7D5 ; > MOS46 0002 E7D5 TTL MOS46 OSWORD routines 0003 E7D5 OPT MOS46 Acorn macro assembler Page 95 MOS46 OSWORD routines 0004 E7D5 ;(c) 1981 ACORN Computers Limited 0005 E7D5 ;BBC MOS 0006 E7D5 ;Change record: 0007 E7D5 ;203 01-May-82 PB Fix EXTSND bug 0008 E7D5 ;041 15-Aug-81 PB First edition 0009 E7D5 ;Author(s): 0010 E7D5 ;PB Paul Bond 0011 E7D5 0012 E7D5 0013 E7D5 BYTE ;OSBYTE call 0014 E7D5 ; 0015 E7D5 ; uses: 0016 E7D5 ; BYTEX, BYTEY (may be shared by sei-routines) 0017 E7D5 ; JMILO, JMIHI 0018 E7D5 ; 0019 E7D5 48 PHA 0020 E7D6 08 PHP 0021 E7D7 78 SEI ;**** DISABLE INTERRUPTS **** 0022 E7D8 ; 0023 E7D8 ; save A and X 0024 E7D8 ; 0025 E7D8 85 EF STA BYTEA 0026 E7DA 86 F0 STX BYTEX 0027 E7DC 84 F1 STY BYTEY 0028 E7DE ; 0029 E7DE A2 07 LDXIM SVBYTE ;illegal codes are referred to paged ROM 0030 E7E0 ; 0031 E7E0 ; check for legal code 0032 E7E0 ; 0033 E7E0 C9 75 CMPIM BYTEM 0034 E7E2 90 41 BCC BYTELO ;[interactive code] 0035 E7E4 ; 0036 E7E4 ; code >= BYTEM 0037 E7E4 ; 0038 E7E4 C9 A1 CMPIM BYTEH 0039 E7E6 90 09 BCC BYTEHI ;[code < BYTEH] 0040 E7E8 ; 0041 E7E8 ; check for variable setting 0042 E7E8 ; 0043 E7E8 C9 A6 CMPIM VORG 0044 E7EA 90 3F BCC BYTE0 ;[not a variable setting] 0045 E7EC ; 0046 E7EC ; set variable 0047 E7EC ; 0048 E7EC 18 CLC ;force A=BYTEH 0049 E7ED ; 0050 E7ED WORDU ;user OSWORD call, C=1, force A=BYTEH+$01 0051 E7ED ; 0052 E7ED A9 A1 LDAIM BYTEH 0053 E7EF 69 00 ADCIM ZERO ;add in carry (C=0 => variable, C=1 => user OSWORD) 0054 E7F1 ; 0055 E7F1 BYTEHI 0056 E7F1 ; 0057 E7F1 38 SEC 0058 E7F2 E9 5F SBCIM BYTEM-BYTEL 0059 E7F4 ; 0060 E7F4 BYTE1 ;construct address of specific OSBYTE routine 0061 E7F4 ; 0062 E7F4 0A ASLA ;prepare for Y := 2*code 0063 E7F5 ; 0064 E7F5 38 SEC ;indicate OSBYTE call 0065 E7F6 ; 0066 E7F6 BYTE2 ;C=0 => OSWORD call 0067 E7F6 ; 0068 E7F6 84 F1 STY BYTEY ;save Y 0069 E7F8 ; 0070 E7F8 A8 TAY ;Y := 2*code 0071 E7F9 ; 0072 E7F9 ; allow net to indirect OS call 0073 E7F9 ; 0074 E7F9 [ MOS125 = &FF 0082 E7F9 | 0083 E7F9 AD 5E 02 LDA NETIOC 0084 E7FC B8 CLV 0085 E7FD 10 06 BPL NET1 ;[net not indirecting OS calls] 0086 E7FF ; 0087 E7FF ; indirect OS call thru net 0088 E7FF ; 0089 E7FF 8A TXA ;A := reason code 0090 E800 ] 0091 E800 20 E3 E5 JSR JMINET ;args in BYTEA, BYTEX, BYTEY (call type in A) 0092 E803 70 1A BVS OSRET ;[net substituted result] 0093 E805 ; 0094 E805 ; construct specific OSBYTE routine address 0095 E805 ; 0096 E805 NET1 ;call internal routine 0097 E805 B9 19 E6 LDAAY BYTET+&01 ;hi-byte 0098 E808 85 FB STA JMIHI 0099 E80A B9 18 E6 LDAAY BYTET+&00 ;lo-byte 0100 E80D 85 FA STA JMILO 0101 E80F ; 0102 E80F ; enter specific OSBYTE routine 0103 E80F ; 0104 E80F ; X = SVBYTE or SVWORD 0105 E80F ; 0106 E80F ; 0107 E80F A5 EF LDA BYTEA ;in case OSBYTE call 0108 E811 A4 F1 LDY BYTEY ;restore Y 0109 E813 ; 0110 E813 ; determine type of call 0111 E813 ; 0112 E813 B0 04 BCS OSB ;[OSBYTE call] 0113 E815 ; 0114 E815 ; OSWORD call 0115 E815 ; 0116 E815 A0 00 LDYIM ZERO 0117 E817 B1 F0 LDAIY WORDX 0118 E819 ; 0119 E819 OSB 0120 E819 ; 0121 E819 ; ********** V=0 USED BY OSBYTE ROUTINES ********** 0122 E819 38 SEC ;used by several routines 0123 E81A A6 F0 LDX BYTEX ;restore X (N.B. N, Z status used by several routines) 0124 E81C 20 85 F0 JSR JMI ;enter specific routine 0125 E81F ; 0126 E81F OSRET 0127 E81F ; 0128 E81F 6A RORA ;save C 0129 E820 28 PLP 0130 E821 2A ROLA ;restore C (needed by readline routine - BASIC expects it) 0131 E822 68 PLA ;restore A Acorn macro assembler Page 96 MOS46 OSWORD routines 0132 E823 B8 CLV ;indicate call recognised 0133 E824 60 RTS 0134 E825 0135 E825 0136 E825 [ NOSP = &00 0141 E825 ] 0142 E825 0143 E825 BYTELO ;code has top bit clear - use table lo component 0144 E825 A0 00 LDYIM ZERO ;only one argument, set Y=0 for variable settings and ADC ops 0145 E827 C9 16 CMPIM BYTEL 0146 E829 90 C9 BCC BYTE1 ;[recognised code] 0147 E82B ; 0148 E82B ; unrecognised code 0149 E82B ; 0150 E82B BYTE0 ;unrecognised OSBYTE code 0151 E82B WORD0 ;unrecognised OSWORD code (C=1) 0152 E82B ; force 4 bytes on stack (making 4 before Preg, simulating a return link) 0153 E82B 08 PHP ;N.B. non-zero byte (SEI mode) 0154 E82C 08 PHP 0155 E82D ; 0156 E82D EXTSND ;entry point used by SOUND (return link still on stack) 0157 E82D 68 PLA 0158 E82E 68 PLA 0159 E82F ; 0160 E82F 20 6F F1 JSR SVOP ;offer to paged ROMs (N.B. X=SVBYTE or X=SVWORD) 0161 E832 D0 05 BNE BADOSC ;[unrecognised OS call] 0162 E834 ; 0163 E834 ; recognised OS call 0164 E834 ; 0165 E834 A6 F0 LDX BYTEX ;replace X (corrupted by SVOP) 0166 E836 ; 0167 E836 4C 1F E8 JMP OSRET 0168 E839 0169 E839 0170 E839 BADOSC ;bad OS call 0171 E839 28 PLP ;restore interrupt status 0172 E83A 68 PLA ;restore code to return with 0173 E83B 2C 47 D9 BIT FFBYT ;indicate call not recognised 0174 E83E 60 RTS 0175 E83F 0176 E83F 0177 E83F [ MOS125 = &FF 0193 E83F ] 0194 E83F 0195 E83F 0196 E83F WORD ;OSWORD call 0197 E83F ; uses: 0198 E83F ; WORDX, WORDY (may be shared by sei-routines) 0199 E83F ; JMILO, JMIHI (may be shared by sei-routines) 0200 E83F ; 0201 E83F 48 PHA 0202 E840 08 PHP ;save interrupt state 0203 E841 78 SEI ;**** DISABLE INTERRUPTS **** 0204 E842 ; 0205 E842 ; save A, X and Y 0206 E842 ; 0207 E842 85 EF STA WORDA 0208 E844 86 F0 STX WORDX 0209 E846 84 F1 STY WORDY 0210 E848 ; 0211 E848 A2 08 LDXIM SVWORD ;code used if indirection taken 0212 E84A ; 0213 E84A ; check for user OSWORD call 0214 E84A ; 0215 E84A C9 E0 CMPIM &E0 0216 E84C B0 9F BCS WORDU ;[user OSWORD call - route thru USRVEC, C=1] 0217 E84E ; 0218 E84E ; not a user OSWORD call 0219 E84E ; 0220 E84E ; check for legal code 0221 E84E ; 0222 E84E C9 0E CMPIM WORDN 0223 E850 B0 D9 BCS WORD0 ;[unrecognised code] 0224 E852 ; C=0 0225 E852 ; 0226 E852 ; recognised OSWORD call 0227 E852 ; construct address of specific OSWORD routine 0228 E852 ; 0229 E852 ; C=0 0230 E852 69 44 ADCIM WORDT-BYTET:SHR: 1 0231 E854 ; C=0 0232 E854 ; 0233 E854 ; enter specific OSWORD routine 0234 E854 ; 0235 E854 0A ASLA ;prepare for Y := 2*code 0236 E855 ; C=0 0237 E855 90 9F BCC BYTE2 ;[ALWAYS jump, C=0 => OSWORD call] 0238 E857 0239 E857 [ MOS125 = &FF 0277 E857 ] 0278 E857 0279 E857 NOTE ;add note to note buffer 0280 E857 ; ********************* 0281 E857 ; MAY ENABLE INTERRUPTS 0282 E857 ; ********************* 0283 E857 ; XY -> 8 bytes of info 0284 E857 ; C=1 0285 E857 ; X=SVWORD 0286 E857 ; Y=0 0287 E857 ; 0288 E857 [ NOSP = &00 0300 E857 | 0301 E857 [ $Tutu 0306 E857 | 0307 E857 C8 INY 0308 E858 B1 F0 LDAIY WORDX ;A := command type indicator (hi-byte of 1st argument) 0309 E85A C9 FF CMPIM &FF 0310 E85C ] 0311 E85C F0 59 BEQ SPEECH ;[speech command] 0312 E85E C9 20 CMPIM &20 0313 E860 ] 0314 E860 0315 E860 A2 08 LDXIM SVWORD ;in case EXTSND called 0316 E862 B0 C9 BCS EXTSND ;[route command to paged ROM] 0317 E864 ; 0318 E864 ; sound command 0319 E864 ; 0320 E864 88 DEY ;Y := 0 0321 E865 20 EF E8 JSR NOTEX ;C => flush, A = channel, Y := 1 0322 E868 09 04 ORAIM &04 ;********** N.B. assumes BSND1=4 0323 E86A AA TAX ;X := (internal) sound bufferid Acorn macro assembler Page 97 MOS46 OSWORD routines 0324 E86B 90 05 BCC NOTENF ;[do not flush channel] 0325 E86D ; C=1 0326 E86D ; flush channel 0327 E86D ; 0328 E86D ; C=1 0329 E86D 20 AE E1 JSR PURGEX ;purge buffer 0330 E870 A0 01 LDYIM &01 ;restore Y 0331 E872 ; 0332 E872 NOTENF 0333 E872 20 EF E8 JSR NOTEX ;C => release continue, A = chordcount-1 0334 E875 85 FA STA NOTEWK 0335 E877 ; 0336 E877 08 PHP ;needed in order to share code with BELL 0337 E878 A0 06 LDYIM &06 ;A := duration-lo 0338 E87A B1 F0 LDAIY WORDX 0339 E87C 48 PHA 0340 E87D ; 0341 E87D A0 04 LDYIM &04 ;A := note-lo 0342 E87F B1 F0 LDAIY WORDX 0343 E881 48 PHA 0344 E882 ; 0345 E882 ; C => release continue 0346 E882 ; 0347 E882 A0 02 LDYIM &02 0348 E884 B1 F0 LDAIY WORDX ;A = envelope-lo 0349 E886 2A ROLA ;rotate in release continue bit 0350 E887 38 SEC 0351 E888 E9 02 SBCIM &02 ;envelope numbers start at 1 0352 E88A 0A ASLA 0353 E88B 0A ASLA ;rotate in 2 zero bits 0354 E88C 05 FA ORA NOTEWK ;A := AEEE ERHH 0355 E88E ; 0356 E88E ; insert byte into buffer, waiting if necessary 0357 E88E ; 0358 E88E 20 6B E2 JSR WRITE 0359 E891 90 1E BCC NOTE2 ;[byte inserted] 0360 E893 ; 0361 E893 SPESC ;ESCAPE detected 0362 E893 68 PLA 0363 E894 68 PLA 0364 E895 28 PLP 0365 E896 ; 0366 E896 VDUST ;FX call to return VDU status 0367 E896 A6 D0 LDX STATS 0368 E898 ; 0369 E898 60 RTS 0370 E899 0371 E899 0372 E899 ; 0373 E899 ;; ===== 0374 E899 ; BELL 0375 E899 ; ===== 0376 E899 ; 0377 E899 ; Add BELL to sound queue 0378 E899 ; 0379 E899 ; ENTRY:- No conditions 0380 E899 ; 0381 E899 ; EXIT:- A,X,Y Corrupted 0382 E899 ; Flags preserved 0383 E899 ; 0384 E899 BELL 0385 E899 08 PHP 0386 E89A 78 SEI 0387 E89B ; 0388 E89B ; try to add bell to sound channel queue 0389 E89B ; 0390 E89B AD 63 02 LDA BELLC 0391 E89E 29 07 ANDIM &07 0392 E8A0 09 04 ORAIM &04 0393 E8A2 AA TAX ;force valid sound channel 0394 E8A3 ; 0395 E8A3 ; insert envelope/chord info 0396 E8A3 ; 0397 E8A3 AD 64 02 LDA BELLI 0398 E8A6 20 16 E5 JSR INSRT 0399 E8A9 ; 0400 E8A9 ; N.B. ignore return code 0401 E8A9 ; C=0 => inserted, C=1 => not inserted 0402 E8A9 ; if first INSRT failed then so will the following INSRTs 0403 E8A9 ; set to insert duration 0404 E8A9 ; 0405 E8A9 AD 66 02 LDA BELLD 0406 E8AC 48 PHA 0407 E8AD ; 0408 E8AD ; set to insert note 0409 E8AD ; 0410 E8AD AD 65 02 LDA BELLN 0411 E8B0 48 PHA 0412 E8B1 ; 0413 E8B1 NOTE2 ;buffer slot available 0414 E8B1 ; C=0 => inserted, C=1 => not inserted 0415 E8B1 ; 0416 E8B1 38 SEC 0417 E8B2 7E 00 08 RORAX MACTIV-BSND1 0418 E8B5 [ NOSP = &00 0420 E8B5 | 0421 E8B5 30 17 BMI NOTE3 ;[ALWAYS JUMP] 0422 E8B7 ; 0423 E8B7 SPEECH ;SOUND -1,x,y,z command 0424 E8B7 ; Y=1 0425 E8B7 08 PHP ;needed to share code with BELL 0426 E8B8 C8 INY ;Y := $02 0427 E8B9 B1 F0 LDAIY WORDX 0428 E8BB 48 PHA 0429 E8BC ; 0430 E8BC C8 INY ;Y := $03 0431 E8BD B1 F0 LDAIY WORDX 0432 E8BF 48 PHA 0433 E8C0 ; 0434 E8C0 A0 00 LDYIM ZERO 0435 E8C2 B1 F0 LDAIY WORDX 0436 E8C4 A2 08 LDXIM BSPCH 0437 E8C6 20 6B E2 JSR WRITE ;insert first byte into buffer 0438 E8C9 B0 C8 BCS SPESC ;[escape detected] 0439 E8CB ; 0440 E8CB ; C=0 0441 E8CB ; 0442 E8CB 6E D7 02 ROR SPSTAT ;indicate speech buffer non-empty 0443 E8CE ] 0444 E8CE ; 0445 E8CE NOTE3 ;add note and duration (ignored if first byte not inserted) Acorn macro assembler Page 98 MOS46 OSWORD routines 0446 E8CE 68 PLA 0447 E8CF 20 16 E5 JSR INSRT ;add note data to queue 0448 E8D2 68 PLA 0449 E8D3 20 16 E5 JSR INSRT ;add duration info to queue 0450 E8D6 28 PLP 0451 E8D7 60 RTS 0452 E8D8 0453 E8D8 0454 E8D8 NVLP ;define envelope shape 0455 E8D8 ; A := envelope number 0456 E8D8 ; C=1 0457 E8D8 ; 0458 E8D8 [ MOS125 = &FF 0470 E8D8 | 0471 E8D8 ; 0472 E8D8 ; envelope number forced into range 0 to 15 (1->0, 2->1 ... 16->15) 0473 E8D8 ; (0 forced to 255, which will have the same effect as 15) 0474 E8D8 ; 0475 E8D8 0A ASLA 0476 E8D9 0A ASLA 0477 E8DA 0A ASLA 0478 E8DB 0A ASLA ;envelope number := envelope number * 16 0479 E8DC AA TAX ;N.B. ENVSIZ must be 16! 0480 E8DD ] 0481 E8DD ; 0482 E8DD ; copy envelope definition to envelope slot 0483 E8DD ; padding to 16 bytes with zeroes 0484 E8DD ; 0485 E8DD A9 00 LDAIM ZERO ;padding value 0486 E8DF A0 10 LDYIM ENVSIZ 0487 E8E1 ; 0488 E8E1 NVLP1 0489 E8E1 C0 0E CPYIM ENVSIZ-&02 0490 E8E3 B0 02 BCS NVLP2 ;[still padding] 0491 E8E5 ; 0492 E8E5 B1 F0 LDAIY WORDX 0493 E8E7 NVLP2 0494 E8E7 [ MOS125 = &FF 0497 E8E7 | 0498 E8E7 CA DEX 0499 E8E8 9D C0 08 STAAX ENVEL 0500 E8EB ] 0501 E8EB 88 DEY 0502 E8EC D0 F3 BNE NVLP1 0503 E8EE ; 0504 E8EE 60 RTS 0505 E8EF 0506 E8EF NOTEX ;extract byte info from offset Y of vector 0507 E8EF B1 F0 LDAIY WORDX 0508 E8F1 C9 10 CMPIM &10 ;C => flag (flush or release continue) 0509 E8F3 29 03 ANDIM &03 0510 E8F5 C8 INY ;step Y to next slot 0511 E8F6 60 RTS 0512 E8F7 0513 E8F7 RITM ;read interval time 0514 E8F7 A2 0F LDXIM STPW+&5-TIME 0515 E8F9 D0 03 BNE RTM ;[ALWAYS jump] 0516 E8FB ; NEVER fall thru 0517 E8FB RATM ;read absolute time 0518 E8FB AE 83 02 LDX TIMESW 0519 E8FE RTM 0520 E8FE A0 04 LDYIM &04 0521 E900 RTM1 0522 E900 BD 8D 02 LDAAX TIME -&05 0523 E903 91 F0 STAIY WORDX 0524 E905 E8 INX 0525 E906 88 DEY 0526 E907 10 F7 BPL RTM1 0527 E909 WTM0 0528 E909 60 RTS 0529 E90A 0530 E90A [ MOS125 = &FF 0539 E90A | 0540 E90A WATM ;write absolute time 0541 E90A AC 83 02 LDY TIMESW 0542 E90D 18 CLC ;indicate WATM entry 0543 E90E WITM ;write interval time, C=1, Y=0 0544 E90E 98 TYA 0545 E90F 49 0F EORIM &0F ;assumes STPW-TIME = &A 0546 E911 ] 0547 E911 WTM 0548 E911 48 PHA ;save TIMESW for WATM entry 0549 E912 AA TAX 0550 E913 A0 04 LDYIM &04 0551 E915 WTM1 0552 E915 B1 F0 LDAIY WORDX 0553 E917 9D 8D 02 STAAX TIME -&05 0554 E91A E8 INX 0555 E91B 88 DEY 0556 E91C 10 F7 BPL WTM1 0557 E91E 68 PLA 0558 E91F B0 E8 BCS WTM0 ;[not WATM entry, do not reset TIMESW] 0559 E921 ; WATM entry, reset TIMESW 0560 E921 8D 83 02 STA TIMESW 0561 E924 60 RTS 0562 E925 0563 E925 RDLN ;read input buffer 0564 E925 ; ****************** 0565 E925 ; ENABLES INTERRUPTS 0566 E925 ; ****************** 0567 E925 ;**************** 0568 E925 ;variables: 0569 E925 ;zero page: RDLNX, RDLNY (contiguous) 0570 E925 ;other page: RDLNN, RDLNLC, RDLNHC (contiguous) 0571 E925 ;**************** 0572 E925 ;Called with Y and X the high and low addresses of the information 0573 E925 ;describing what is to be done. The bytes in order are: 0574 E925 ;lsb address of buffer 0575 E925 ;msb address of buffer 0576 E925 ;maximum length allowed 0577 E925 ;minimum character value to be stored in buffer 0578 E925 ;maximum character value to be stored in buffer 0579 E925 ;Return when escape is pressed or seen with CARRY SET 0580 E925 ;Return after CR (which is always stored) with CARRY CLEAR 0581 E925 ;Always returns with Y the number of characters in the buffer 0582 E925 ;DEL,ESC and NAK are always processed 0583 E925 ;**** NOTE **** 0584 E925 ; if the 'other page' variables are put into page zero 0585 E925 ; this routine can be made ~10 bytes shorter. 0586 E925 ; however, an extra pointer variable in page zero would 0587 E925 ; then be required. Acorn macro assembler Page 99 MOS46 OSWORD routines 0588 E925 ; this routine enables interrupts 0589 E925 ; ********** 0590 E925 ; copy 'other page' values 0591 E925 0592 E925 A0 04 LDYIM &04 0593 E927 BUFFPR 0594 E927 B1 F0 LDAIY WORDX 0595 E929 99 B1 02 STAAY RDLNN -&02 ;N.B. offset of -02 0596 E92C 88 DEY 0597 E92D C0 02 CPYIM &02 0598 E92F B0 F6 BCS BUFFPR ;[more arguments to copy] 0599 E931 ; 0600 E931 ; C=0, Y=1 0601 E931 ; copy buffer pointer 0602 E931 ; 0603 E931 B1 F0 LDAIY WORDX ;hi-byte 0604 E933 85 E9 STA RDLNBF +&01 0605 E935 88 DEY ;Y := 0 0606 E936 8C 69 02 STY LINES ;reset page mode page origin 0607 E939 B1 F0 LDAIY WORDX ;lo-byte 0608 E93B 85 E8 STA RDLNBF +&00 0609 E93D ; 0610 E93D ; C=0, Y=0 0611 E93D ; 0612 E93D 58 CLI ;**** ENABLE INTERRUPTS **** 0613 E93E 90 1F BCC BUFFIN ;[ALWAYS JUMP] 0614 E940 ; 0615 E940 ; NEVER fall thru 0616 E940 0617 E940 0618 E940 [ MOS125 = &FF 0622 E940 | 0623 E940 A9 07 BUFEXH LDAIM BEL ;reflect bell to indicate error 0624 E942 D0 18 BNE BUFIGN ;ALWAYS jump 0625 E944 0626 E944 BUFNXB ;check for ESC explicitly in case machine in non ESC mode 0627 E944 ;CMPIM ESC 0628 E944 ;BEQ BUFESC ;[ESC, N.B. C = 1] 0629 E944 ; not DEL, NAK or ESC 0630 E944 91 E8 STAIY RDLNBF ;store character in buffer 0631 E946 C9 0D CMPIM MCR 0632 E948 F0 3F BEQ BUFEND ;[CR detected, exit indicating CR received] 0633 E94A CC B3 02 CPY RDLNN 0634 E94D B0 F1 BCS BUFEXH ;[buffer exhausted, do not echo character] 0635 E94F ; 0636 E94F ; buffer not exhausted 0637 E94F ; 0638 E94F CD B4 02 CMP RDLNLC 0639 E952 90 08 BCC BUFIGN ;[character < lo-character] 0640 E954 CD B5 02 CMP RDLNHC 0641 E957 90 02 BCC BUFECH ;[character < hi-character, so accept] 0642 E959 D0 01 BNE BUFIGN ;[character > hi-character, so ignore] 0643 E95B C8 BUFECH INY ;increment count of characters in buffer 0644 E95C BUFIGN 0645 E95C ] 0646 E95C ; echo character 0647 E95C BFWRCH 0648 E95C 20 EE FF JSR OSWRCH 0649 E95F ; 0650 E95F BUFFIN ;main loop 0651 E95F 20 E0 FF JSR OSRDCH ;read a character 0652 E962 B0 2B BCS BUFESC ;[escape detected] 0653 E964 AA TAX 0654 E965 AD 7C 02 LDA WRCHSW 0655 E968 6A RORA 0656 E969 6A RORA 0657 E96A 8A TXA 0658 E96B B0 05 BCS BUFNQ ;[output does not include VDU] 0659 E96D ; 0660 E96D ; output includes VDU 0661 E96D ; 0662 E96D ; 0663 E96D AE 6A 02 LDX QPOSN 0664 E970 D0 EA BNE BFWRCH ;[VDU queueing, reflect character] 0665 E972 ; 0666 E972 ; output does not include VDU 0667 E972 ; 0668 E972 BUFNQ ;VDU not queueing 0669 E972 [ MOS125 = &FF 0698 E972 | 0699 E972 C9 7F CMPIM MDEL 0700 E974 F0 05 BEQ BUFCNL ;[DEL received] 0701 E976 C9 15 CMPIM MNAK 0702 E978 D0 CA BNE BUFNXB ;[not DEL or NAK] 0703 E97A 18 CLC 0704 E97B BUFCNL ;output DEL once (CC) or for each character in the buffer 0705 E97B 98 TYA 0706 E97C F0 E1 BEQ BUFFIN ;[reached start of line] 0707 E97E 88 DEY 0708 E97F A9 7F LDAIM MDEL 0709 E981 B0 D9 BCS BFWRCH ;[if DEL, reflect DEL and get next char] 0710 E983 20 EE FF JSR OSWRCH 0711 E986 18 CLC 0712 E987 90 F2 BCC BUFCNL ;[ALWAYS jump, more characters to delete] 0713 E989 ] 0714 E989 ; NEVER fall thru 0715 E989 ; 0716 E989 [ MOS125 = &FF 0736 E989 ] 0737 E989 0738 E989 BUFEND ;read line successful 0739 E989 ; echo LF CR 0740 E989 20 E7 FF JSR OSNEWL 0741 E98C 20 E3 E5 JSR JMINET ;N.B. assumes NTCR has value $0D 0742 E98F ; 0743 E98F BUFESC ;escape exit (C=1) 0744 E98F A5 FF LDA ESCFLG 0745 E991 2A ROLA ;C=0 => no escape, C=1 => escape 0746 E992 60 RTS 0747 E993 0748 E993 0749 E993 [ MOS125 = &7F 0750 E993 ;flash keyboard LEDs while waiting for printer buffer to purge 0751 E993 ;C=1 0752 E993 SPFL 0753 E993 [ STARGO = &00 0754 E993 48 PHA ;save FX call number 0755 E994 8A TXA 0756 E995 48 PHA ;save printer selection 0757 E996 20 00 EA JSR MOSTST ;flash LEDs 0758 E999 68 PLA Acorn macro assembler Page 100 MOS46 OSWORD routines 0759 E99A AA TAX ;restore printer selection 0760 E99B 68 PLA ;restore FX call number 0761 E99C 38 SEC ;restore C=1 0762 E99D ] 0763 E99D ] 0764 E99D 0765 E99D SPRINT ;change printer selection (*FX 5) 0766 E99D ; allow interrupts during wait, this means that: 0767 E99D ; (a) the printer can purge AND/OR 0768 E99D ; (b) escape can be detected 0769 E99D 58 CLI 0770 E99E 78 SEI 0771 E99F 24 FF BIT ESCFLG 0772 E9A1 30 30 BMI SPR0 ;[escape detected] 0773 E9A3 2C D2 02 BIT PFLAG 0774 E9A6 [ MOS125 = &7F 0775 E9A6 10 EB BPL SPFL ;printer busy, flash LEDs while purging 0776 E9A8 | 0778 E9A8 ] 0779 E9A8 ; mention change of printer to print routines 0780 E9A8 20 3B E2 JSR UPTX ;N.B. Y corrupted 0781 E9AB ; interrupts may have corrupted BYTEX and BYTEY, so restore them 0782 E9AB A0 00 LDYIM ZERO ;Y altered by call to UPTX 0783 E9AD 84 F1 STY BYTEY 0784 E9AF ; N.B. X reset at SETVX 0785 E9AF ; N.B. A not altered since SPRINT 0786 E9AF ; 0787 E9AF V2B156 ;convert FX 1,5,6 to FX 241,245,246 0788 E9AF 09 F0 ORAIM &F0 0789 E9B1 D0 0E BNE SETVX ;[ALWAYS jump] 0790 E9B3 ; 0791 E9B3 ARRPT ;A = $0C, set auto-repeat repeat count 0792 E9B3 ; N.B. previous instruction was LDX 0793 E9B3 ; C=1 0794 E9B3 D0 07 BNE ARRPT1 ;[X<>0 => do not set defaults] 0795 E9B5 ; set defaults 0796 E9B5 A2 32 LDXIM DAUTOD 0797 E9B7 8E 54 02 STX FARSET 0798 E9BA A2 08 LDXIM DAUTOP 0799 E9BC ARRPT1 ;A = $0C, C=1 0800 E9BC ARDLY ;A = $0B, C=1, set auto-repeat delay count (0 => disable) 0801 E9BC 69 CF ADCIM FARSET-VBASE-&01-&0B- 233 ;$01 for carry, $0B for FX base 0802 E9BE ; 0803 E9BE V2B34 ;C=1 0804 E9BE 18 CLC 0805 E9BF 69 E9 ADCIM 233 ;convert FX 3&4 to FX 236,237 0806 E9C1 ; 0807 E9C1 SETVX 0808 E9C1 86 F0 STX BYTEX 0809 E9C3 ; 0810 E9C3 SETV ;set variable 0811 E9C3 ; A = FX code 0812 E9C3 ; X = value 0813 E9C3 ; Y = mask 0814 E9C3 A8 TAY ;Y := FX code 0815 E9C4 B9 90 01 LDAAY VBASE ;A := old value 0816 E9C7 AA TAX ;X := old value 0817 E9C8 25 F1 AND BYTEY ;apply mask 0818 E9CA 45 F0 EOR BYTEX ;apply value 0819 E9CC 99 90 01 STAAY VBASE ;store new value 0820 E9CF B9 91 01 LDAAY VBASE+&01 0821 E9D2 A8 TAY ;return following byte 0822 E9D3 SPR0 0823 E9D3 60 RTS 0824 E9D4 0825 E9D4 0826 E9D4 BAUDS ;baud rate table (N.B. RS423 bit set cos of B9600 definition) 0827 E9D4 BUFTYP ;**** WARNING - SUBTLE WAY TO DETECT SOUND BUFFERS **** 0828 E9D4 ; (*) = sound buffer 0829 E9D4 0080 SOUNDB * &80 0830 E9D4 64 = B9600 ;default baud rate / buffer 0 0831 E9D5 7F = &7F ;75 111 111 / buffer 1 0832 E9D6 5B = &5B ;150 011 011 / buffer 2 0833 E9D7 6D = &6D ;300 101 101 / buffer 3 0834 E9D8 C9 = &49+SOUNDB ;1200 001 001 / buffer 4 (*) 0835 E9D9 F6 = &76+SOUNDB ;2400 110 110 / buffer 5 (*) 0836 E9DA D2 = &52+SOUNDB ;4800 010 010 / buffer 6 (*) 0837 E9DB E4 = B9600+SOUNDB ;9600 100 100 / buffer 7 (*) 0838 E9DC 40 = &40 ;19200 000 000 / buffer 8 0839 E9DD 0840 E9DD 0841 E9DD WFVS ;wait for vertical sync 0842 E9DD AD 40 02 LDA CYCLE 0843 E9E0 WFVS1 ;wait for CYCLE to alter 0844 E9E0 58 CLI ;must enable interrupts to allow CYCLE to operate 0845 E9E1 ; this should give the user control immediately after VSYNC 0846 E9E1 ; interrupt occurred 0847 E9E1 78 SEI 0848 E9E2 CD 40 02 CMP CYCLE 0849 E9E5 F0 F9 BEQ WFVS1 ;[CYCLE not altered] 0850 E9E7 ; 0851 E9E7 ; share exit with read VDU variable 0852 E9E7 ; 0853 E9E7 VDUVAR ;read VDU variables 0854 E9E7 BC 01 03 LDYAX VARBLE+&01 0855 E9EA BD 00 03 LDAAX VARBLE+&00 0856 E9ED AA TAX 0857 E9EE 60 RTS 0858 E9EF 0859 E9EF 0860 E9EF RSOFT ;reset soft keys 0861 E9EF ; initialise soft key pointers 0862 E9EF ; exits with X=0 (used by RESET) 0863 E9EF ; ********** MUST NOT CORRUPT Y (SEE RESET) ********** 0864 E9EF A9 10 LDAIM NSOFTK 0865 E9F1 8D 84 02 STA USKFLG ;signal soft keys inconsistent 0866 E9F4 A2 00 LDXIM ZERO 0867 E9F6 STTA ;set soft key buffer pointers, including the two end pointers 0868 E9F6 9D 00 0B STAAX SKPTR 0869 E9F9 E8 INX 0870 E9FA D0 FA BNE STTA 0871 E9FC ; X=0 0872 E9FC 8E 84 02 STX USKFLG ;USKFLG set to zero when soft keys consistent 0873 E9FF ; X=0 0874 E9FF 60 RTS 0875 EA00 0876 EA00 0877 EA00 LNK MOS48 0001 EA00 0002 EA00 ; MOS48 0003 EA00 TTL MOS48 Miscellaneous routines Acorn macro assembler Page 101 MOS48 Miscellaneous routines 0004 EA00 OPT MOS48 Acorn macro assembler Page 102 MOS48 Miscellaneous routines 0005 EA00 ;(c) 1981 ACORN Computers Limited 0006 EA00 ;BBC Microcomputer Machine Operating System (MOS) 0007 EA00 0008 EA00 ;Change record: 0009 EA00 ;01/03/82 PB GSINTC CR indication 0010 EA00 ;05/01/82 PB Change from printer claim to RS423 0011 EA00 0012 EA00 ;Author(s): 0013 EA00 ;PB Paul Bond 0014 EA00 0015 EA00 0016 EA00 TTL MOS48 External interface routines 0017 EA00 OPT OPNEWP Acorn macro assembler Page 103 MOS48 External interface routines 0018 EA00 0019 EA00 0020 EA00 ; external interfaces 0021 EA00 0022 EA00 0023 EA00 MOSTST 0024 EA00 ; C=0 => do not set LEDs, C=1 => set LEDs 0025 EA00 ; N.B. must not corrupt X (see WRCH print section) 0026 EA00 08 PHP ;push interrupt state 0027 EA01 78 SEI 0028 EA02 ; test for ESCAPE 0029 EA02 A9 40 LDAIM &40 0030 EA04 20 11 EA JSR LEDSON ;conditionally set LEDs and test escape condition 0031 EA07 30 05 BMI SHIFTX ;[escape pending, simulate SHIFT without CTRL] 0032 EA09 ; 0033 EA09 18 CLC ;indicate test ctrl/shift entry point 0034 EA0A B8 CLV 0035 EA0B 20 95 F0 JSR JMIKEY 0036 EA0E ; 0037 EA0E SHIFTX ;b7(A) => CTRL, b6(A) => SHIFT 0038 EA0E 28 PLP 0039 EA0F 2A ROLA ;C => CTRL, MI => SHIFT 0040 EA10 60 RTS 0041 EA11 0042 EA11 0043 EA11 LEDSON ;turn LEDs on 0044 EA11 ; **************************************** 0045 EA11 ; MUST BE ENTERED WITH INTERRUPTS DISABLED 0046 EA11 ; **************************************** 0047 EA11 ; C=0 => do not turn LEDs on, C=1 => turn LEDs on 0048 EA11 ; returns status of BIT ESCFLG 0049 EA11 90 09 BCC LEDS0 ;[do not turn LEDs on] 0050 EA13 ; set both LEDs (indicating a wait state) 0051 EA13 A0 07 LDYIM &07 0052 EA15 8C 40 FE STY PBQ ;PBQ:=$07 0053 EA18 88 DEY 0054 EA19 8C 40 FE STY PBQ ;PBQ:=$06 0055 EA1C LEDS0 ;set escape status 0056 EA1C 24 FF BIT ESCFLG 0057 EA1E 60 RTS 0058 EA1F 0059 EA1F CREG ;called by VDU module 0060 EA1F ; interrupts are disabled in order that a spurious 0061 EA1F ; ADC interrupt does not occur 0062 EA1F 08 PHP ;save interrupt state 0063 EA20 78 SEI 0064 EA21 8D 40 FE STA PBQ ;set addressable latch value 0065 EA24 28 PLP ;restore interrupt state 0066 EA25 60 RTS 0067 EA26 0068 EA26 0069 EA26 VP0 ;program vidproc register 0 (FX entry) 0070 EA26 8A TXA 0071 EA27 MVPRC0 ;set video processor register 0 0072 EA27 08 PHP 0073 EA28 78 SEI ;**** DISABLE INTERRUPTS **** 0074 EA29 8D 48 02 STA VPREGA ;update RAM image 0075 EA2C 8D 20 FE STA VPROC0 ;update ULA 0076 EA2F AD 53 02 LDA FLMRK 0077 EA32 8D 51 02 STA FLCNT ;reset flash count to mark value 0078 EA35 28 PLP 0079 EA36 60 RTS 0080 EA37 0081 EA37 VP1 ;program vidproc register 1 (FX entry) 0082 EA37 8A TXA 0083 EA38 MVPRC1 ;set video processor register 1 0084 EA38 49 07 EORIM &07 ;adjust value accounting for ULA bug 0085 EA3A 08 PHP 0086 EA3B 78 SEI ;**** DISABLE INTERRUPTS **** 0087 EA3C 8D 49 02 STA VPREGB ;update RAM image 0088 EA3F 8D 21 FE STA VPROC1 ;update ULA 0089 EA42 28 PLP 0090 EA43 60 RTS 0091 EA44 0092 EA44 [ MOS125 = &FF 0093 EA44 | 0094 EA44 ; fetch/store byte from MMIO without dummy read cycle 0095 EA44 ; on entry A=OSBYTE call no. X=addr lo Y=byte C=1 0096 EA44 69 65 CHEQUE ADCIM &65 ;C=1; A=&FC..FE 0097 EA46 38 SEC 0098 EA47 6A RORA ;C=0 read memory C=1 write 0099 EA48 ; fetch/store byte from I/O mem without dummy read 0100 EA48 ; on entry A=addr hi X=addr lo Y=byte C=0 read C=1 write 0101 EA48 BOUNCE 0102 EA48 85 FB STA PEEKHI ;MSB address 0103 EA4A 86 FA STX PEEKLO ;LSB address 0104 EA4C A2 00 LDXIM &00 0105 EA4E 90 04 BCC BREAD 0106 EA50 98 TYA 0107 EA51 81 FA STAIX PEEKLO 0108 EA53 60 RTS 0109 EA54 BREAD 0110 EA54 A1 FA LDAIX PEEKLO 0111 EA56 A8 TAY 0112 EA57 38 SEC ;return C=1 from OSBYTE/OSWORD 0113 EA58 60 RTS 0114 EA59 0115 EA59 MSGON ;used by CFS 0116 EA59 ;Return EQ if messages off and not doing catalogue 0117 EA59 ;or during EXEC/SPOOL (during which messages cannot occur 0118 EA59 ;since this implies writing chars while within RDCH or WRCH) 0119 EA59 0120 EA59 A5 EB LDA ESSEMA 0121 EA5B 30 22 BMI MSGONY ;Inside RDCH/WRCH -> msgs OFF 0122 EA5D 0123 EA5D A9 08 LDAIM CATBIT 0124 EA5F 25 E2 AND CFSTAT 0125 EA61 D0 04 BNE MSGONX ;Out with msgs set. 0126 EA63 0127 EA63 A9 88 LDAIM MONBIT 0128 EA65 25 BB AND USFLGS 0129 EA67 60 MSGONX RTS 0130 EA68 0131 EA68 PEEK ;read byte from I/O processor 0132 EA68 18 CLC 0133 EA69 POKE ;write byte to I/O processor 0134 EA69 AA TAX ;hold address lo-byte 0135 EA6A C8 INY ;Y=1 0136 EA6B B1 F0 LDAIY WORDX ;get address hi-byte 0137 EA6D 48 PHA ;address in X and 1,S 0138 EA6E A0 04 LDYIM &04 ;point to byte to write Acorn macro assembler Page 104 MOS48 External interface routines 0139 EA70 B1 F0 LDAIY WORDX 0140 EA72 A8 TAY ;hold byte to write 0141 EA73 68 PLA ;restore MSB of address 0142 EA74 20 48 EA JSR BOUNCE ;write byte in Y/read byte into A 0143 EA77 A0 04 LDYIM &04 0144 EA79 91 F0 STAIY WORDX ;store byte read in OSWORD block 0145 EA7B VER 0146 EA7B F0 31 BEQ PVER 0147 EA7D A2 01 LDXIM MCVER ;X=1 for OSBYTE 0,1 MOS version 1 0148 EA7F MSGONY ;used by MSGON below 0149 EA7F A9 00 LDAIM ZERO 0150 EA81 60 RTS 0151 EA82 ] 0152 EA82 0153 EA82 GSINTC ;intialise for string access (read item) 0154 EA82 0155 EA82 18 CLC 0156 EA83 GSINTS ;initialise for string access (read item/rest of line) 0157 EA83 66 E4 ROR KQUOTE 0158 EA85 20 A0 E0 JSR SKIPSP ;A := LDAIY WORK 0159 EA88 C8 INY ;skip possible opening quote 0160 EA89 C9 22 CMPIM DQUOTE 0161 EA8B F0 02 BEQ CLIOQ ;[opening quote, C=1] 0162 EA8D ; no opening quote 0163 EA8D 88 DEY ;adjust for erroneous skip 0164 EA8E 18 CLC 0165 EA8F CLIOQ 0166 EA8F 66 E4 ROR KQUOTE ;PL => not a quoted string, MI => a quoted string 0167 EA91 C9 0D CMPIM MCR ;return EQ => end-of-string, NEQ => not end-of-string 0168 EA93 60 RTS 0169 EA94 ; 0170 EA94 GSREAD ;read character from string 0171 EA94 0172 EA94 ; reset key mask (used in top bit option) 0173 EA94 A9 00 LDAIM ZERO 0174 EA96 GSRA ;used by |! option, entered with A=$80 0175 EA96 85 E5 STA KMASK ;KMASK := 0000 0000 (or KMASK := 1000 0000) 0176 EA98 B1 F2 LDAIY WORK ;A := next character 0177 EA9A C9 0D CMPIM MCR 0178 EA9C D0 1A BNE KEYNCR ;[not CR] 0179 EA9E ; CR found, C=1 0180 EA9E ; check that string did not open with double quote 0181 EA9E 24 E4 BIT KQUOTE 0182 EAA0 [ MOS125 = &FF 0185 EAA0 | 0186 EAA0 10 2F BPL GSR1 ;[no unpaired double quote, return C=1 and EQ=>CR] 0187 EAA2 BADSTR 0188 EAA2 00 BRK ;report error 'Bad string' 0189 EAA3 FD = BADST 0190 EAA4 42 61 64 = "Bad string" ;BRK forms terminator 0191 EAAE 00 PVER BRK 0192 EAAF F7 = FX0MSG 0193 EAB0 4F 53 20 = "OS " 0194 EAB3 31 = VERA 0195 EAB4 2E = "." 0196 EAB5 32 = VERB 0197 EAB6 36 = VERC 0198 EAB7 00 = ZERO 0199 EAB8 ] 0200 EAB8 KEYNCR ;character not CR 0201 EAB8 C9 20 CMPIM SPACE 0202 EABA 90 E6 BCC BADSTR ;[control character in string] 0203 EABC D0 06 BNE KEYNSP ;[not space] 0204 EABE ; space character 0205 EABE 24 E4 BIT KQUOTE 0206 EAC0 30 3E BMI GSR0 ;[in quoted string] 0207 EAC2 50 0D BVC GSR1 ;[not in quoted string and not read line, so space is terminator] 0208 EAC4 ; fall thru, space will be returned as a valid character 0209 EAC4 KEYNSP 0210 EAC4 C9 22 CMPIM DQUOTE 0211 EAC6 D0 0E BNE KEYNDQ ;[not double quote] 0212 EAC8 ; double quote found 0213 EAC8 24 E4 BIT KQUOTE 0214 EACA 10 34 BPL GSR0 ;[not in quoted string] 0215 EACC ; in quoted string 0216 EACC C8 INY 0217 EACD [ MOS125 = &FF 0220 EACD | 0221 EACD D1 F2 CMPIY WORK ;A = DQUOTE, compare with next character 0222 EACF ] 0223 EACF F0 2F BEQ GSR0 ;["" found in quoted string] 0224 EAD1 GSR1 ;closing quote of quoted string 0225 EAD1 20 A0 E0 JSR SKIPSP ;skip spaces 0226 EAD4 38 SEC 0227 EAD5 60 RTS 0228 EAD6 0229 EAD6 KEYNDQ ;character not CR or " 0230 EAD6 C9 7C CMPIM "|" ;check for pseudo-escape 0231 EAD8 D0 26 BNE GSR0 ;[valid string character] 0232 EADA ; 0233 EADA C8 INY 0234 EADB B1 F2 LDAIY WORK 0235 EADD C9 7C CMPIM "|" 0236 EADF F0 1F BEQ GSR0 ;[|| found] 0237 EAE1 ; 0238 EAE1 C9 22 CMPIM DQUOTE 0239 EAE3 F0 1B BEQ GSR0 ;[|" found] 0240 EAE5 ; 0241 EAE5 C9 21 CMPIM "!" 0242 EAE7 D0 05 BNE KEYNPL ;[not |!] 0243 EAE9 ; C=1 0244 EAE9 ; |! found - top bit option 0245 EAE9 C8 INY ;step to next character 0246 EAEA ; C=1 0247 EAEA A9 80 LDAIM &80 ;KMASK := 1000 0000 0248 EAEC D0 A8 BNE GSRA ;[ALWAYS jump, get next character reseting key mask] 0249 EAEE ; NEVER fall thru 0250 EAEE 0251 EAEE KEYNPL ;check for control character 0252 EAEE C9 20 CMPIM SPACE 0253 EAF0 90 B0 BCC BADSTR ;[string contains a control character] 0254 EAF2 ; convert to CTRL character 0255 EAF2 C9 3F CMPIM "?" 0256 EAF4 F0 08 BEQ KEYDEL 0257 EAF6 20 29 EB JSR CTRLCH 0258 EAF9 ; fall thru with adjusted character 0259 EAF9 2C 47 D9 BIT FFBYT ;indicate character was escaped 0260 EAFC 70 03 BVS GSRX ;[ALWAYS jump] 0261 EAFE ; 0262 EAFE KEYDEL ;|? 0263 EAFE A9 7F LDAIM MDEL Acorn macro assembler Page 105 MOS48 External interface routines 0264 EB00 ; 0265 EB00 GSR0 ;valid character 0266 EB00 B8 CLV 0267 EB01 ; 0268 EB01 GSRX ;exit with valid character 0269 EB01 ; rotate in selected top bit 0270 EB01 C8 INY ;skip to next character 0271 EB02 05 E5 ORA KMASK ;test character for filing system applications 0272 EB04 18 CLC 0273 EB05 ; C=0, V=0 => not escaped, V=1 => escaped 0274 EB05 60 RTS 0275 EB06 0276 EB06 0277 EB06 [ MOS125 = &FF 0283 EB06 ] 0284 EB06 0285 EB06 SHIFT ;perform shift inversion 0286 EB06 ; 0287 EB06 ; check for '0' character explicitly 0288 EB06 ; 0289 EB06 C9 30 CMPIM "0" 0290 EB08 F0 1E BEQ SHIFT0 ;[character is '0', shift '0' is '0', no action] 0291 EB0A 0292 EB0A ; convert characters in range ['A',DEL) 0293 EB0A ; 0294 EB0A C9 40 CMPIM AT 0295 EB0C F0 1A BEQ SHIFT0 ;[AT, no action] 0296 EB0E 90 12 BCC SHIFT1 ;[ch= 'A' 0299 EB10 ; 0300 EB10 C9 7F CMPIM MDEL 0301 EB12 F0 14 BEQ SHIFT0 ;[ch=DEL, no action] 0302 EB14 B0 10 BCS SHFLIP ;[ch>DEL, is softkey code] 0303 EB16 ; 0304 EB16 ; 'A' <= character < DEL 0305 EB16 ; 0306 EB16 CTRLSK ;used by CTRLCH for CTRL/softkey 0307 EB16 49 30 EORIM &30 ;flip bit to effect shift (N.B. EORIM $10 later) 0308 EB18 ; 0309 EB18 ; N.B. this has mapped '_' to $6F and POUND to $50 0310 EB18 ; swop underline and pound characters 0311 EB18 ; 0312 EB18 C9 6F CMPIM &6F ;i.e. mapped '_' 0313 EB1A F0 04 BEQ SHIFT2 ;[underline character] 0314 EB1C C9 50 CMPIM &50 ;i.e. mapped POUND (not altered by EORIM $20 anyway) 0315 EB1E D0 02 BNE SHIFT1 ;[neither underline nor pound character] 0316 EB20 ; 0317 EB20 SHIFT2 ;swop underline and pound characters 0318 EB20 49 1F EORIM &1F 0319 EB22 ; 0320 EB22 SHIFT1 0321 EB22 0322 EB22 ; convert characters above '!' 0323 EB22 ; 0324 EB22 C9 21 CMPIM "!" 0325 EB24 90 02 BCC SHIFT0 ;[ch<'!', no action] 0326 EB26 ; 0327 EB26 ; '!' <= ch < AT 0328 EB26 ; 0329 EB26 SHFLIP 0330 EB26 49 10 EORIM &10 ;$80..$8F -> $90..$9F and vice-versa 0331 EB28 0332 EB28 SHIFT0 0333 EB28 60 RTS 0334 EB29 0335 EB29 0336 EB29 CTRLCH ;compute CTRL version of character 0337 EB29 C9 7F CMPIM MDEL 0338 EB2B F0 0E BEQ CTRL0 ;[CTRL/DEL = DEL] 0339 EB2D B0 E7 BCS CTRLSK ;[top bit set, therefore softkey needing EORIM $20] 0340 EB2F 0341 EB2F ; pound & underline 0342 EB2F ; 0343 EB2F C9 60 CMPIM POUND ;make CTRL/pound = CTRL/underline 0344 EB31 D0 02 BNE CTRL1 ;[not pound character] 0345 EB33 A9 5F LDAIM "_" ;substitute underline for pound 0346 EB35 CTRL1 0347 EB35 0348 EB35 [ FALSE=0 0354 EB35 ] 0355 EB35 0356 EB35 [ FALSE=0 0362 EB35 ] 0363 EB35 0364 EB35 C9 40 CMPIM AT 0365 EB37 90 02 BCC CTRL4 ;[character < AT so do not convert] 0366 EB39 ; AT <= character < DEL, so convert 0367 EB39 29 1F ANDIM &1F ;convert to ctrl value 0368 EB3B CTRL4 0369 EB3B 0370 EB3B CTRL0 0371 EB3B 60 RTS 0372 EB3C 0373 EB3C [ FALSE=0 0376 EB3C ] 0377 EB3C 0378 EB3C SLBOOT ;'/!BOOT' auto-boot string 0379 EB3C 2F 21 42 = "/!BOOT" 0380 EB42 0D = MCR 0381 EB43 0382 EB43 0383 EB43 BREAK ;conditionally intercept BREAK 0384 EB43 ; type of interception is in C 0385 EB43 AD 87 02 LDA BREAKI 0386 EB46 49 4C EORIM &4C 0387 EB48 D0 13 BNE BREAK0 ;[not a JMP instruction] 0388 EB4A 4C 87 02 JMP BREAKI 0389 EB4D 0390 EB4D 0391 EB4D TV ;alter TV characteristics 0392 EB4D AD 90 02 LDA VERTIC 0393 EB50 8E 90 02 STX VERTIC ;vertical height adjust 0394 EB53 AA TAX ;X := old state 0395 EB54 98 TYA 0396 EB55 29 01 ANDIM &01 0397 EB57 AC 91 02 LDY INTERL ;Y := old state 0398 EB5A 8D 91 02 STA INTERL ;interlace invert 0399 EB5D BREAK0 0400 EB5D 60 RTS 0401 EB5E Acorn macro assembler Page 106 MOS48 External interface routines 0402 EB5E [ MOS125 = &FF 0417 EB5E ] 0418 EB5E 0419 EB5E LNK MOS52 0001 EB5E 0002 EB5E ; MOS52 0003 EB5E TTL MOS52 Sound generator 0004 EB5E OPT MOS52 Acorn macro assembler Page 107 MOS52 Sound generator 0005 EB5E ;(c) 1981 ACORN Computers Limited 0006 EB5E ;BBC Microcomputer Machine Operating System (MOS) 0007 EB5E ;Change record: 0008 EB5E ;Prototype version 14/1/82 0009 EB5E ;Author(s): 0010 EB5E ;PBM Peter Miller 0011 EB5E ;Internal variable allocation $0800 to $08C0 0012 EB5E 08C0 ENV * ENVEL ;envelope table 16 bytes per envelope 0013 EB5E 0804 ATTN * SNDWRK+&04 ;current attenuation 0014 EB5E 0808 EPERD * ATTN +&04 ;current envelope period 0015 EB5E 080C SNOTE * EPERD +&04 ;base note 0016 EB5E 0810 NPERD * SNOTE +&04 ;the current frequency envelope period 0-3 0017 EB5E 0814 NCONT * NPERD +&04 ;number of ticks left in current frequency period 0018 EB5E 0818 DUR * NCONT +&04 ;remaining number of ticks in the current note 0019 EB5E 081C DRDIV * DUR +&04 ;division of 1/100 sewc to 1/20 sec 0020 EB5E 0820 ENVLP * DRDIV +&04 ;current envelope ( TIMES 16) 0021 EB5E 0824 SCONT * ENVLP +&04 ;number of 1/100th secs before next envelope tick 0022 EB5E 0828 WAIT * SCONT +&04 ;channel waiting for sWATGO flag 0023 EB5E 082C OLDNTE * WAIT +&04 ;current note in chip 0024 EB5E 0830 NTADD * OLDNTE +&04 ;current offset from base note 0025 EB5E 0026 EB5E 0027 EB5E 0838 NOWAT * NTADD +&08 ;number of other channels required for chord 0028 EB5E 0839 ATINC * NOWAT +&01 ;current rate of attn change 0029 EB5E 083A PEAK * ATINC +&01 ;peak of amplitude envelope 0030 EB5E 083B WATGO * PEAK +&01 ;flag <>0 => play chord 0031 EB5E 083C FRACT * WATGO +&01 ;fractional part of current note 0032 EB5E 083D PRDL * FRACT +&01 ;low period during convert 0033 EB5E 083E PRDH * PRDL +&01 ;hign period during convert 0034 EB5E 083F NOTDIF * PRDH +&01 ;Note difference used in interpolation 0035 EB5E 0036 EB5E 02CF FLUSH * SFLUSH -&04 0037 EB5E 0800 ACTIV * MACTIV -&04 0038 EB5E 0039 EB5E 0040 EB5E ;Externally referenced data 0041 EB5E ;ACTIV 0042 EB5E ;FLUSH 0043 EB5E ;ENVEL 0044 EB5E ;SNDWRK 0045 EB5E ;Externally referenced routines 0046 EB5E ;EXAM 0047 EB5E ;REMOV 0048 EB5E ;Entry points 0049 EB5E ;SNDRST Initialise sound system, shut sound chip up 0050 EB5E ; Acc,X,Y ,P destroyed 0051 EB5E ;SNDIRQ Service entry point 1/100th second 0052 EB5E ; only use after initialisation 0053 EB5E ; Acc,X ,Y and P destroyed 0054 EB5E ;; A,X,P preserved, Y set to zero on exit 0055 EB5E 0056 EB5E 0057 EB5E MINATN ;set minimum attenuation 0058 EB5E A9 04 LDAIM &04 0059 EB60 9D 08 08 STAAX EPERD 0060 EB63 A9 C0 LDAIM &C0 0061 EB65 0062 EB65 0063 EB65 UPATN ;update attenuation 0064 EB65 9D 04 08 STAAX ATTN 0065 EB68 ; 0066 EB68 ; shut up mode ? 0067 EB68 ; 0068 EB68 AC 62 02 LDY SHUTUP 0069 EB6B F0 02 BEQ NOISY ;[sound allowed] 0070 EB6D ; sound suppressed 0071 EB6D A9 C0 LDAIM &C0 ;force minimum attenuation 0072 EB6F NOISY 0073 EB6F ; 0074 EB6F [ MOS125 = &FF 0083 EB6F | 0084 EB6F ; in: x ~b3 b2 b1 b0 x x x 0085 EB6F ;out: c2 c1 c0 1 ~b3 ~b2 ~b1 ~b0 0086 EB6F 4A LSRA 0087 EB70 4A LSRA 0088 EB71 4A LSRA 0089 EB72 1D 94 EB ORAAX CHAN 0090 EB75 29 EF ANDIM &EF 0091 EB77 49 17 EORIM &17 0092 EB79 ] 0093 EB79 ;fall into the send routine 0094 EB79 SNDOUT 0095 EB79 SEND 0096 EB79 08 PHP 0097 EB7A SENDX ;entered by code which has already done a PHP 0098 EB7A 78 SEI 0099 EB7B A0 FF LDYIM &FF 0100 EB7D 8C 43 FE STY &FE43 0101 EB80 8D 4F FE STA &FE4F 0102 EB83 C8 INY 0103 EB84 8C 40 FE STY &FE40 0104 EB87 A0 02 LDYIM &02 0105 EB89 SWAIT 0106 EB89 88 DEY 0107 EB8A D0 FD BNE SWAIT 0108 EB8C A0 08 LDYIM &08 0109 EB8E 8C 40 FE STY &FE40 0110 EB91 A0 04 LDYIM &04 0111 EB93 SWAT2 0112 EB93 88 DEY 0113 EB94 D0 FD BNE SWAT2 0114 EB96 28 PLP 0115 EB97 60 RTS 0116 EB98 RCHAN 0117 EB98 EB94 CHAN * RCHAN -&04 0118 EB98 E0 = &E0 0119 EB99 C0 = &C0 0120 EB9A A0 = &A0 0121 EB9B 80 = &80 0122 EB9C 0123 EB9C 0124 EB9C HENDS 0125 EB9C 4C 9D EC JMP ENDSW ;finished all envelope processing 0126 EB9F 0127 EB9F SNDIRQ 0128 EB9F A9 00 LDAIM ZERO 0129 EBA1 8D 3B 08 STA WATGO 0130 EBA4 AD 38 08 LDA NOWAT 0131 EBA7 D0 06 BNE MAN2 0132 EBA9 EE 3B 08 INC WATGO 0133 EBAC CE 38 08 DEC NOWAT Acorn macro assembler Page 108 MOS52 Sound generator 0134 EBAF MAN2 0135 EBAF A2 08 LDXIM &08 ;X always contains current channel 0136 EBB1 MNLOP 0137 EBB1 CA DEX ;first real channel is 3 0138 EBB2 BD 00 08 LDAAX ACTIV ;check if channel X is doing anything 0139 EBB5 F0 E5 BEQ HENDS ;[channel not active so take quick route] 0140 EBB7 BD CF 02 LDAAX FLUSH 0141 EBBA 30 05 BMI MAN8 ;[must abort current note] 0142 EBBC BD 18 08 LDAAX DUR 0143 EBBF D0 03 BNE MAN10 ;[note finished] 0144 EBC1 MAN8 0145 EBC1 20 AF EC JSR NXTNT ;[get new note from queue if it exists] 0146 EBC4 MAN10 0147 EBC4 BD 18 08 LDAAX DUR 0148 EBC7 F0 13 BEQ MAN13 ;next note now 0149 EBC9 C9 FF CMPIM &FF 0150 EBCB F0 12 BEQ MAN12 0151 EBCD DE 1C 08 DECAX DRDIV 0152 EBD0 D0 0D BNE MAN12 ;[not 1/20th sec tick] 0153 EBD2 A9 05 LDAIM &05 0154 EBD4 9D 1C 08 STAAX DRDIV ; set counter to wait for further 1/20th sec 0155 EBD7 DE 18 08 DECAX DUR 0156 EBDA D0 03 BNE MAN12 0157 EBDC MAN13 0158 EBDC 20 AF EC JSR NXTNT ;try to get a new note 0159 EBDF MAN12 0160 EBDF BD 24 08 LDAAX SCONT 0161 EBE2 F0 05 BEQ MAN11 0162 EBE4 DE 24 08 DECAX SCONT ;dec envelope scaling counter 0163 EBE7 D0 B3 BNE HENDS ;[not time for new envelope tick] 0164 EBE9 MAN11 0165 EBE9 BC 20 08 LDYAX ENVLP ;get envelope offset into Y 0166 EBEC [ MOS125 = &FF 0170 EBEC | 0171 EBEC C8 INY 0172 EBED F0 AD BEQ HENDS 0173 EBEF B9 BF 08 LDAAY ENV-&01 ;get first envelope parameter 0174 EBF2 ] 0175 EBF2 29 7F ANDIM &7F ;mask off sweep repeat bit 0176 EBF4 9D 24 08 STAAX SCONT ;set up scaling counter again 0177 EBF7 BD 08 08 LDAAX EPERD ;envelope period 0178 EBFA C9 04 CMPIM &04 ;check for 'finished' period 0179 EBFC F0 52 BEQ ENDEV ;[no longer in middle of envelope] 0180 EBFE ; 0181 EBFE [ MOS125 = &FF 0183 EBFE ] 0184 EBFE 18 CLC 0185 EBFF 7D 20 08 ADCAX ENVLP ;get offset to current amplitude envelope parameters 0186 EC02 A8 TAY ;ENV+7,Y now point to attninc rate and sENV+11 to attnlevel 0187 EC03 B9 CB 08 LDAAY ENV+&0B ;atenuation level 0188 EC06 38 SEC 0189 EC07 E9 3F SBCIM &3F 0190 EC09 8D 3A 08 STA PEAK ;temp data for following calculations 0191 EC0C B9 C7 08 LDAAY ENV+&7 ;amount by which attenuation is changed each tick 0192 EC0F 8D 39 08 STA ATINC ;temp data for calculations 0193 EC12 BD 04 08 LDAAX ATTN 0194 EC15 48 PHA 0195 EC16 18 CLC 0196 EC17 6D 39 08 ADC ATINC ;add incremnet to attenuation 0197 EC1A 50 04 BVC OK8 ;first check for 8 bit overflow 0198 EC1C [ MOS125 = &FF 0216 EC1C | 0217 EC1C ;else overflow. carry=~b7. generate &C0 if b7=0 or &3F if b7=1 0218 EC1C 09 7F ORAIM &7F ;n111 1111 C=~n 0219 EC1E 69 40 ADCIM &40 ;~~nn nnnn C=n 0220 EC20 OK8 0221 EC20 C9 C0 CMPIM &C0 ;compare b7 and b6 (thanks again Woz) 0222 EC22 10 06 BPL ATOK ;if b7=b6 then value in range 0223 EC24 ;else overflow. generate &3F if b7=0 or &C0 if b7=1 0224 EC24 09 7F ORAIM &7F ;n111 1111 C=0 0225 EC26 69 40 ADCIM &40 ;~011 1111 C=n 0226 EC28 69 80 ADCIM &80 ;nn~~ ~~~~ C=~n 0227 EC2A ATOK 0228 EC2A 9D 04 08 STAAX ATTN ;store as new attenuation 0229 EC2D CE 39 08 DEC ATINC 0230 EC30 ;the following code checks that (ATTN-PEAK)*SIGN(increment)>=0 0231 EC30 ] 0232 EC30 38 SEC 0233 EC31 ED 3A 08 SBC PEAK 0234 EC34 4D 39 08 EOR ATINC 0235 EC37 30 09 BMI SMPER ;[attenuation has not reached limit yet] 0236 EC39 AD 3A 08 LDA PEAK ;attn was too large therefore set to peak 0237 EC3C 9D 04 08 STAAX ATTN 0238 EC3F FE 08 08 INCAX EPERD ;next envelope period 0239 EC42 SMPER ;same envelope period 0240 EC42 68 PLA 0241 EC43 5D 04 08 EORAX ATTN 0242 EC46 29 F8 ANDIM &F8 0243 EC48 F0 06 BEQ NNEWA ;no new chip attenuation output (hasn't changed)] 0244 EC4A BD 04 08 LDAAX ATTN 0245 EC4D 20 65 EB JSR UPATN ;update chip attenuation 0246 EC50 NNEWA 0247 EC50 ENDEV 0248 EC50 ;frequency sweeping part of envelope 0249 EC50 BD 10 08 LDAAX NPERD 0250 EC53 C9 03 CMPIM &03 0251 EC55 F0 46 BEQ ENDSW 0252 EC57 [ MOS125 = &FF 0258 EC57 | 0259 EC57 BC 14 08 LDYAX NCONT ;number of ticks left in this frequency period 0260 EC5A D0 25 BNE GTPRD 0261 EC5C FE 10 08 INCAX NPERD ;next period 0262 EC5F C9 02 CMPIM &03-&01 ;check for period=3 =>end of all periods 0263 EC61 38 SEC ;A=next period - 1, increment it before forming pointer 0264 EC62 ] 0265 EC62 D0 11 BNE NTLF ;[not last period] 0266 EC64 BC 20 08 LDYAX ENVLP ;the following checks for bit 8 set in the first envelope byte=> no sweep repeat 0267 EC67 B9 C0 08 LDAAY ENV 0268 EC6A 30 31 BMI ENDSW ;[not a repeating sweep therefore jump to end] 0269 EC6C A9 00 LDAIM ZERO 0270 EC6E 9D 30 08 STAAX NTADD ;reset amount added to note to zero for next sweep 0271 EC71 9D 10 08 STAAX NPERD ;first sweep period 0272 EC74 [ MOS125 = &FF 0276 EC74 | 0277 EC74 18 CLC ;A=next period, do not adjust 0278 EC75 NTLF 0279 EC75 ;the following points Y to the sweep parameters of the current envelope/period 0280 EC75 ] 0281 EC75 7D 20 08 ADCAX ENVLP 0282 EC78 A8 TAY 0283 EC79 B9 C4 08 LDAAY ENV+&04 Acorn macro assembler Page 109 MOS52 Sound generator 0284 EC7C 9D 14 08 STAAX NCONT ;number of cycles for this frequency period 0285 EC7F F0 1C BEQ ENDSW ;zero frequency period 0286 EC81 GTPRD 0287 EC81 DE 14 08 DECAX NCONT 0288 EC84 BD 20 08 LDAAX ENVLP 0289 EC87 18 CLC 0290 EC88 7D 10 08 ADCAX NPERD 0291 EC8B A8 TAY 0292 EC8C B9 C1 08 LDAAY ENV+&01 ;note increment for this frequency period 0293 EC8F 18 CLC 0294 EC90 7D 30 08 ADCAX NTADD 0295 EC93 9D 30 08 STAAX NTADD ;add increment to the note offset 0296 EC96 18 CLC 0297 EC97 7D 0C 08 ADCAX SNOTE 0298 EC9A 20 41 ED JSR CNVRT ;convert note to period and output 0299 EC9D ENDSW 0300 EC9D E0 04 CPXIM &04 ;'test channel number for zero' 0301 EC9F F0 0D BEQ EDUP ;[channel was zero therefore leave loop] 0302 ECA1 4C B1 EB JMP MNLOP 0303 ECA4 0304 ECA4 0305 ECA4 SNDRST 0306 ECA4 A2 08 LDXIM &08 0307 ECA6 ; 0308 ECA6 RLOP 0309 ECA6 CA DEX 0310 ECA7 20 E3 EC JSR SCRST ;reset sound channel X 0311 ECAA E0 04 CPXIM &04 0312 ECAC D0 F8 BNE RLOP 0313 ECAE ; 0314 ECAE EDUP ;end of 1/100th sec processing 0315 ECAE 60 RTS 0316 ECAF 0317 ECAF 0318 ECAF NXTNT 0319 ECAF BD 08 08 LDAAX EPERD ;get current amplitude period 0320 ECB2 C9 04 CMPIM &04 ;period 4 => note has fully released 0321 ECB4 F0 05 BEQ ELDDN 0322 ECB6 A9 03 LDAIM &03 0323 ECB8 9D 08 08 STAAX EPERD ;put note in the release phase of the envelope 0324 ECBB ELDDN 0325 ECBB BD CF 02 LDAAX FLUSH 0326 ECBE F0 13 BEQ NOFL ;[no flush has been flagged] 0327 ECC0 A9 00 LDAIM ZERO 0328 ECC2 9D CF 02 STAAX FLUSH ;clear the flush flag 0329 ECC5 [ MOS125 = &FF 0344 ECC5 | 0345 ECC5 A0 03 LDYIM &03 ;the following clears all wait variables 0346 ECC7 SWTLOP 0347 ECC7 99 2C 08 STAAY WAIT +&04 0348 ECCA 88 DEY 0349 ECCB 10 FA BPL SWTLOP 0350 ECCD 9D 18 08 STAAX DUR ;set duration to zero => note finished 0351 ECD0 8C 38 08 STY NOWAT ;reset chord building status 0352 ECD3 NOFL ;A=0 0353 ECD3 DD 28 08 CMPAX WAIT ;check it channel waiting for chord 0354 ECD6 F0 43 BEQ NOTWT 0355 ECD8 CD 3B 08 CMP WATGO ;check if chord now ready to play 0356 ECDB F0 34 BEQ NOTGO ;[chord not ready yet] else C=0 0357 ECDD ] 0358 ECDD 9D 28 08 STAAX WAIT ;clear waiting for chord status 0359 ECE0 NNWAT 0360 ECE0 4C D4 ED JMP STRNT ;start playing note 0361 ECE3 SCRST ;reset sound channel X 0362 ECE3 20 5E EB JSR MINATN 0363 ECE6 98 TYA 0364 ECE7 9D 18 08 STAAX DUR 0365 ECEA 9D CF 02 STAAX FLUSH 0366 ECED 9D 00 08 STAAX ACTIV 0367 ECF0 ; 0368 ECF0 ;clear wait periods to zero 0369 ECF0 ; 0370 ECF0 A0 03 LDYIM &03 0371 ECF2 CWP 0372 ECF2 99 2C 08 STAAY WAIT+&04 0373 ECF5 88 DEY 0374 ECF6 10 FA BPL CWP ;[more wait periods to clear] 0375 ECF8 ; Y=$FF 0376 ECF8 ; MI true 0377 ECF8 ; 0378 ECF8 ; indicate no channels waiting 0379 ECF8 ; 0380 ECF8 8C 38 08 STY NOWAT 0381 ECFB ; 0382 ECFB 30 49 BMI FCNVRT ;[ALWAYS JUMP, set period of chip to zero] 0383 ECFD 0384 ECFD 0385 ECFD NGONG 0386 ECFD 08 PHP 0387 ECFE 78 SEI 0388 ECFF BD 08 08 LDAAX EPERD ;while irq disabled check if active can be cleared 0389 ED02 C9 04 CMPIM &04 ;if envelope period=4 then note finished 0390 ED04 D0 0A BNE NOGO2 ;[note not yet released] 0391 ED06 20 C1 E4 JSR EXAM ;check for recent arrival of note 0392 ED09 90 05 BCC NOGO2 ;queue no longer empty 0393 ED0B A9 00 LDAIM ZERO 0394 ED0D 9D 00 08 STAAX ACTIV ;set channel as inactive 0395 ED10 NOGO2 0396 ED10 28 PLP 0397 ED11 NOTGO 0398 ED11 BC 20 08 LDYAX ENVLP 0399 ED14 [ MOS125 = &FF 0401 ED14 | 0402 ED14 C8 INY 0403 ED15 ] 0404 ED15 D0 03 BNE PROG 0405 ED17 20 5E EB JSR MINATN ;update attenuation of box envelopes 0406 ED1A PROG 0407 ED1A PRTS ;rts pointer 0408 ED1A 60 RTS 0409 ED1B 0410 ED1B 0411 ED1B NOTWT 0412 ED1B 20 C1 E4 JSR EXAM ;examine byte at head of queue 0413 ED1E B0 DD BCS NGONG ;[queue empty] 0414 ED20 29 03 ANDIM &03 0415 ED22 F0 BC BEQ NNWAT ;[no chord commands for next note] 0416 ED24 AD 38 08 LDA NOWAT 0417 ED27 F0 15 BEQ SRTS ;[full chord already accepted,ignore this channel for now] 0418 ED29 FE 28 08 INCAX WAIT ;set waiting flag 0419 ED2C 2C 38 08 BIT NOWAT ;check for chord being built Acorn macro assembler Page 110 MOS52 Sound generator 0420 ED2F 10 0A BPL SMCRD ;chord already being built 0421 ED31 20 C1 E4 JSR EXAM ;getheader byte again 0422 ED34 29 03 ANDIM &03 ;select chord bits 0423 ED36 8D 38 08 STA NOWAT ;new chord so set number of other channels required 0424 ED39 10 03 BPL LNOTGO 0425 ED3B SMCRD 0426 ED3B CE 38 08 DEC NOWAT ;decrement the number of channels still required for chord 0427 ED3E SRTS ;must point to RTS command 0428 ED3E LNOTGO 0429 ED3E 4C 11 ED JMP NOTGO 0430 ED41 0431 ED41 0432 ED41 ;routine to convert note to period 0433 ED41 ;and output to the chip 0434 ED41 CNVRT 0435 ED41 DD 2C 08 CMPAX OLDNTE 0436 ED44 F0 D4 BEQ PRTS ;no need to update chip 0437 ED46 FCNVRT ;force note output 0438 ED46 9D 2C 08 STAAX OLDNTE 0439 ED49 E0 04 CPXIM &04 ;check if noise channel 0440 ED4B D0 08 BNE TONE 0441 ED4D 29 0F ANDIM &0F ;noise input is only 4 bits 0442 ED4F 1D 94 EB ORAAX CHAN ;add channel information 0443 ED52 08 PHP ;push P (will immediately be pulled) 0444 ED53 [ MOS125 = &FF 0446 ED53 | 0447 ED53 B0 7C BCS CDONE ;output and return 0448 ED55 ] 0449 ED55 TONE ;tone channel 0450 ED55 48 PHA 0451 ED56 29 03 ANDIM &03 0452 ED58 8D 3C 08 STA FRACT ;low 2 bits give fraction of semitone 0453 ED5B [ MOS125 = &FF 0465 ED5B | 0466 ED5B 68 PLA 0467 ED5C 4A LSRA 0468 ED5D 4A LSRA 0469 ED5E 8D 3D 08 STA PRDL 0470 ED61 OCTL 0471 ED61 C9 0C CMPIM &0C ;check if note > one octave 0472 ED63 90 07 BCC ENDOL 0473 ED65 E9 0C SBCIM &0C 0474 ED67 6E 3D 08 ROR PRDL ;use PRDL as octave counter for division 0475 ED6A 30 F5 BMI OCTL ;branch always taken 0476 ED6C ] 0477 ED6C ENDOL 0478 ED6C A8 TAY 0479 ED6D AD 3D 08 LDA PRDL ;number octaves up 0480 ED70 48 PHA 0481 ED71 B9 32 EE LDAAY NTABL ;low period from table 0482 ED74 8D 3D 08 STA PRDL 0483 ED77 B9 3E EE LDAAY NTABH ;high period for lowest octave 0484 ED7A 48 PHA 0485 ED7B 29 03 ANDIM &03 0486 ED7D 8D 3E 08 STA PRDH 0487 ED80 68 PLA ;get semitone difference from top bits of NTABH 0488 ED81 4A LSRA 0489 ED82 4A LSRA 0490 ED83 4A LSRA 0491 ED84 4A LSRA 0492 ED85 8D 3F 08 STA NOTDIF 0493 ED88 AD 3D 08 LDA PRDL 0494 ED8B AC 3C 08 LDY FRACT ;number of times NOTDIF has to be added 0495 ED8E F0 0C BEQ INTRPE ;[true semitone] 0496 ED90 INTRPL 0497 ED90 ;following subtracts NOTDIF from period 0498 ED90 38 SEC 0499 ED91 ED 3F 08 SBC NOTDIF 0500 ED94 B0 03 BCS INTRPO 0501 ED96 CE 3E 08 DEC PRDH 0502 ED99 INTRPO 0503 ED99 88 DEY 0504 ED9A D0 F4 BNE INTRPL ;[add another fraction] 0505 ED9C INTRPE 0506 ED9C 8D 3D 08 STA PRDL 0507 ED9F 68 PLA 0508 EDA0 [ MOS125 = &FF 0516 EDA0 | 0517 EDA0 10 09 BPL ODONE ;if lowest octave then no shifts 0518 EDA2 SSHIFT 0519 EDA2 4E 3E 08 LSR PRDH ;divide period by 2 0520 EDA5 6E 3D 08 ROR PRDL 0521 EDA8 0A ASLA 0522 EDA9 30 F7 BMI SSHIFT ;[up another octave] 0523 EDAB ] 0524 EDAB ODONE 0525 EDAB AD 3D 08 LDA PRDL ;extract low four bits of period 0526 EDAE 18 CLC 0527 EDAF 7D 3D C4 ADCAX SCHOFF 0528 EDB2 8D 3D 08 STA PRDL 0529 EDB5 90 03 BCC NOFOV 0530 EDB7 EE 3E 08 INC PRDH 0531 EDBA NOFOV 0532 EDBA 29 0F ANDIM &0F 0533 EDBC 1D 94 EB ORAAX CHAN ;add channel address 0534 EDBF 08 PHP 0535 EDC0 78 SEI ;make sure another request does not mess up sequence 0536 EDC1 20 79 EB JSR SEND ;output to chip 0537 EDC4 AD 3D 08 LDA PRDL ;get next 6 bits of period 0538 EDC7 4E 3E 08 LSR PRDH 0539 EDCA 6A RORA 0540 EDCB 4E 3E 08 LSR PRDH 0541 EDCE 6A RORA 0542 EDCF 4A LSRA ;transfer to low 6 bits of Acc 0543 EDD0 4A LSRA 0544 EDD1 CDONE 0545 EDD1 4C 7A EB JMP SENDX ;output period to chip 0546 EDD4 ;routine to start note at head of queue 0547 EDD4 STRNT 0548 EDD4 08 PHP ;start indivisible section to stop new 0549 EDD5 78 SEI ;note being added to queue half way through extraction 0550 EDD6 20 C6 E4 JSR REMOV ;get byte at head queue 0551 EDD9 [ MOS125 = &FF 0558 EDD9 | 0559 EDD9 A8 TAY ;save byte at head queue 0560 EDDA 29 04 ANDIM &04 ;extract 'continue' bit 0561 EDDC F0 12 BEQ NOCONT ;[not continue] 0562 EDDE BC 20 08 LDYAX ENVLP ;must check for continue to auto envelope 0563 EDE1 C8 INY 0564 EDE2 ] 0565 EDE2 D0 03 BNE SCON1 Acorn macro assembler Page 111 MOS52 Sound generator 0566 EDE4 20 5E EB JSR MINATN ;update attenuation 0567 EDE7 SCON1 0568 EDE7 20 C6 E4 JSR REMOV ;throw away note 0569 EDEA 20 C6 E4 JSR REMOV ;get duration 0570 EDED 28 PLP ;end of indivisible section 0571 EDEE [ MOS125 = &FF 0575 EDEE | 0576 EDEE 90 3E BCC DODUR ;C=0 from NNWAT->STRNT; always branch to update duration 0577 EDF0 NOCONT 0578 EDF0 98 TYA ;restore header byte 0579 EDF1 ] 0580 EDF1 29 F8 ANDIM &F8 ;extract 5 envelope bits 0581 EDF3 0A ASLA ;programmable envelope select bit >carry 0582 EDF4 90 0A BCC PENV ;[programmed envelope] 0583 EDF6 [ MOS125 = &FF 0588 EDF6 | 0589 EDF6 ; in: ~b3 ~b2 ~b1 ~b0 0 0 0 x 0590 EDF6 ;out: ~b3 ~b3 b2 b1 b0 1 1 1 0591 EDF6 C9 80 CMPIM &80 ;convert box envelope to signed amplitude 0592 EDF8 6A RORA 0593 EDF9 49 3F EORIM &3F 0594 EDFB ] 0595 EDFB 20 65 EB JSR UPATN 0596 EDFE A9 FF LDAIM &FF ;flag box envelope by setting top bit of ENVLP 0597 EE00 PENV 0598 EE00 9D 20 08 STAAX ENVLP ;envelope pointer,envelope*16 0599 EE03 A9 05 LDAIM &05 ;start timing first 1/20th second from now 0600 EE05 9D 1C 08 STAAX DRDIV 0601 EE08 A9 01 LDAIM &01 0602 EE0A 9D 24 08 STAAX SCONT ;first envelope update next tick 0603 EE0D [ MOS125 = &FF 0605 EE0D | 0606 EE0D 4A LSRA 0607 EE0E ] 0608 EE0E 9D 14 08 STAAX NCONT 0609 EE11 9D 08 08 STAAX EPERD ;first amplittude envelope 0610 EE14 9D 30 08 STAAX NTADD ;note add envelope starts at 0 0611 EE17 A9 FF LDAIM &FF 0612 EE19 9D 10 08 STAAX NPERD ;set frequency envelope to -1,incremented on first tick 0613 EE1C 20 C6 E4 JSR REMOV ;extract note byte from queue 0614 EE1F 9D 0C 08 STAAX SNOTE ;store note 0615 EE22 20 C6 E4 JSR REMOV ;Remove duration 0616 EE25 28 PLP ;end of indivisible section 0617 EE26 48 PHA ;remember duration 0618 EE27 BD 0C 08 LDAAX SNOTE 0619 EE2A 20 41 ED JSR CNVRT ;convert to period and output 0620 EE2D 68 PLA ;get duration back 0621 EE2E DODUR 0622 EE2E 9D 18 08 STAAX DUR ;set up duration 0623 EE31 60 RTS 0624 EE32 [ MOS125 = &FF 0625 EE32 | 0626 EE32 ;NB swapping JSR CNVRT and STAAX DUR (to save PHA/PLA) 0627 EE32 ;would cause an interrupt occurring during CNVRT to decrement 0628 EE32 ;the new count instead of the old. Preserving current order. 0629 EE32 ] 0630 EE32 0631 EE32 0632 EE32 NTABL ;lookup table for low 8 bit of period 0633 EE32 F0 = &F0 0634 EE33 B7 = &B7 0635 EE34 82 = &82 0636 EE35 4F = &4F 0637 EE36 20 = &20 0638 EE37 F3 = &F3 0639 EE38 C8 = &C8 0640 EE39 A0 = &A0 0641 EE3A 7B = &7B 0642 EE3B 57 = &57 0643 EE3C 35 = &35 0644 EE3D 16 = &16 0645 EE3E NTABH ;lookup table for high 2 bits of period 0646 EE3E E7 = &E7 ;and 6 bits of note difference being the difference 0647 EE3F D7 = &D7 ;between this and the next note 0648 EE40 CB = &CB 0649 EE41 C3 = &C3 0650 EE42 B7 = &B7 0651 EE43 AA = &AA 0652 EE44 A2 = &A2 0653 EE45 9A = &9A 0654 EE46 92 = &92 0655 EE47 8A = &8A 0656 EE48 82 = &82 0657 EE49 7A = &7A 0658 EE4A 0659 EE4A 0660 EE4A LNK MOS54 0001 EE4A ; MOS54 0002 EE4A TTL MOS54 SPEECH DRIVING 0003 EE4A OPT MOS54 Acorn macro assembler Page 112 MOS54 SPEECH DRIVING 0004 EE4A ;(c) 1981 ACORN Computers Limited 0005 EE4A ;BBC Microcomputer Machine Operating System (MOS) 0006 EE4A ;Change record: 0007 EE4A ;004 07-Nov-81 PBM Prototype version 0008 EE4A ;Author(s): 0009 EE4A ;Paul Bond 0010 EE4A 0011 EE4A 0012 EE4A SRINIT ;initialise SEROM environment for CFS 0013 EE4A [ NOSP = &00 0016 EE4A | 0017 EE4A A9 EF LDAIM &F0-&01 ;$01 adjusts for future INC SEROM 0018 EE4C ] 0019 EE4C ; SEROM will cycle $F0 ... $FF ... $00 ... $10 (max) 0020 EE4C 85 F5 STA SEROM 0021 EE4E [ MOS125 = &FF 0023 EE4E ] 0024 EE4E 0025 EE4E 0026 EE4E SRNEXT ;move on to next SEROM 0027 EE4E ; 0028 EE4E ; scans phrase ROM first, then paged ROM 0029 EE4E ; 0030 EE4E SPCPYF ;entry point from failed copyright message test 0031 EE4E A2 0D LDXIM SVISFS 0032 EE50 E6 F5 INC SEROM 0033 EE52 A4 F5 LDY SEROM 0034 EE54 [ NOSP = &00 0039 EE54 | 0040 EE54 [ MOS125 = &7F 0041 EE54 30 05 BMI SPPH ;[process PHROM, V not altered] 0042 EE56 C0 10 CPYIM NROM ;if we get here with SEROM >= NROM, 0043 EE58 90 39 BCC SPSV ;then no paged ROM is to respond 0044 EE5A 60 RTS ;so exit C=1, call unclaimed 0045 EE5B SPPH 0046 EE5B | 0048 EE5B ] 0049 EE5B ; 0050 EE5B ; process PHROM, V not altered 0051 EE5B ; 0052 EE5B ; no need to check for speech chip present 0053 EE5B ; reads from chip will not indicate copyright message 0054 EE5B ; 0055 EE5B ; check for existence of speech SEROM 0056 EE5B ; 0057 EE5B ; set pointer to 1 0058 EE5B ; 0059 EE5B A2 00 LDXIM ZERO 0060 EE5D 86 F7 STX ROMPTR+&01 0061 EE5F E8 INX ;X := 1 0062 EE60 86 F6 STX ROMPTR+&00 0063 EE62 20 F5 EE JSR SPLOAD ;set address 0064 EE65 ; 0065 EE65 ; check for copyright (C) 0066 EE65 ; 0067 EE65 A2 03 LDXIM &03 0068 EE67 SPCPY ;V not altered 0069 EE67 20 9C EE JSR RDBYTE ;does not alter X 0070 EE6A DD 21 F5 CMPAX COPYR 0071 EE6D D0 DF BNE SPCPYF ;[failed test for copyright message] 0072 EE6F ; C=1 0073 EE6F CA DEX 0074 EE70 10 F5 BPL SPCPY 0075 EE72 ; 0076 EE72 ; C=1 0077 EE72 ; 0078 EE72 ; copyright message is present 0079 EE72 ; 0080 EE72 ; we have read 5 bytes so far 0081 EE72 ; skip more bytes allowing for copyright/title strings 0082 EE72 ; 0083 EE72 ; position serial ROM to cassette image data 0084 EE72 ; (indirect pointer held at offset $3E) 0085 EE72 ; 0086 EE72 A9 3E LDAIM &3E 0087 EE74 85 F6 STA ROMPTR+&00 0088 EE76 ; 0089 EE76 ; C=1 0090 EE76 ; 0091 EE76 SPLIND ;load address indirect, V not altered, returns C=0 0092 EE76 20 F5 EE JSR SPLOAD 0093 EE79 [ TRUE=0 0094 EE79 ; perform soft version of read-and-branch 0095 EE79 ; 0096 EE79 A2 FF LDXIM &FF 0097 EE7B RABLP 0098 EE7B ; read lo byte when X=0, hi byte when X=1 0099 EE7B 20 9C EE JSR RDBYTE ;does not corrupt X 0100 EE7E ; 0101 EE7E [ MOS125 = &FF 0108 EE7E | 0109 EE7E 38 SEC ;C undefined if entered at SPLIND 0110 EE7F 2A ROLA 0111 EE80 RABLO ;reverse bits in A into ROMPTR+(0/1) 0112 EE80 76 F7 RORAX ROMPTR+&01 0113 EE82 0A ASLA 0114 EE83 D0 FB BNE RABLO ;[process 8 bits] 0115 EE85 ; C=1, Y clobbered in SPLOAD->SPL->SPL1 0116 EE85 ] 0117 EE85 ; 0118 EE85 E8 INX 0119 EE86 F0 F3 BEQ RABLP ;repeat loop once more with X=0 0120 EE88 ; 0121 EE88 18 CLC ;indicate next successful 0122 EE89 90 6A BCC SPLOAD ;[ALWAYS jump, set indirected address AND return] 0123 EE8B | 0136 EE8B ] 0137 EE8B ] 0138 EE8B 0139 EE8B 0140 EE8B RDSPCH ;read byte from SEROM 0141 EE8B A2 0E LDXIM SVRSFS 0142 EE8D [ NOSP = &00 0144 EE8D | 0145 EE8D A4 F5 LDY SEROM 0146 EE8F 30 0B BMI RDBYTE ;[reading from PHROM, V not altered] 0147 EE91 ] 0148 EE91 ; 0149 EE91 ; reading from paged ROM 0150 EE91 ; 0151 EE91 A0 FF LDYIM 0-MCVER ;enter paged ROM with M/C indicator in Y Acorn macro assembler Page 113 MOS54 SPEECH DRIVING 0152 EE93 ; 0153 EE93 SPSV ;used by read byte routine, V not altered 0154 EE93 08 PHP 0155 EE94 20 6F F1 JSR SVOP ;search for paged SEROM (N.B. SVOPSP) 0156 EE97 ; 0157 EE97 28 PLP ;restore V-flag 0158 EE98 C9 01 CMPIM &01 ;claimed => C=0, not claimed => C=1 0159 EE9A 98 TYA ;A := read character (useful for read byte routine only) 0160 EE9B 60 RTS 0161 EE9C 0162 EE9C 0163 EE9C [ NOSP = &00 0166 EE9C | 0167 EE9C RDBYTE ;read byte from speech ROM, V not altered 0168 EE9C 08 PHP 0169 EE9D 78 SEI 0170 EE9E A0 10 LDYIM SPOPRB ;set to read byte 0171 EEA0 20 B9 EE JSR WSPECH 0172 EEA3 ; read byte (following code shorter than JSR RSPECH; PLP; RTS) 0173 EEA3 A0 00 LDYIM ZERO 0174 EEA5 F0 17 BEQ SENDSX ;[ALWAYS JUMP, N.B. does PLP & RTS, SEI already active] 0175 EEA7 0176 EEA7 0177 EEA7 RSPECH ;read from speech processor, must not corrupt X 0178 EEA7 A0 00 LDYIM ZERO 0179 EEA9 F0 11 BEQ SENDSP ;[ALWAYS jump] 0180 EEAB ; 0181 EEAB ; 0182 EEAB SPL ;send load address nibbles 0183 EEAB ; A = hl 0184 EEAB ; h is hi-nibble 0185 EEAB ; l is lo-nibble 0186 EEAB 48 PHA 0187 EEAC 20 B4 EE JSR SPL1 ;send lo-nibble 0188 EEAF 68 PLA 0189 EEB0 6A RORA 0190 EEB1 6A RORA 0191 EEB2 6A RORA 0192 EEB3 6A RORA 0193 EEB4 ; 0194 EEB4 ; send hi-nibble 0195 EEB4 ; 0196 EEB4 SPL1 0197 EEB4 29 0F ANDIM &0F ;isolate lo-nibble 0198 EEB6 09 40 ORAIM SPOPLA 0199 EEB8 ; 0200 EEB8 A8 TAY ;Y := command 0201 EEB9 ; 0202 EEB9 WSPECH ;write to speech processor, must not corrupt X 0203 EEB9 98 TYA ;A := command 0204 EEBA A0 01 LDYIM &01 0205 EEBC ; 0206 EEBC SENDSP ;read/write from/to speech processor 0207 EEBC ; Y=0 => read 0208 EEBC ; Y=1 => write 0209 EEBC 08 PHP 0210 EEBD 78 SEI 0211 EEBE SENDSX ;entry used by routines which have done a PHP & SEI 0212 EEBE 2C 7B 02 BIT SPFLAG 0213 EEC1 10 21 BPL SNDSX0 ;[speech chip not present] 0214 EEC3 ; 0215 EEC3 48 PHA ;save command 0216 EEC4 ; 0217 EEC4 ; select PA7-0 as inputs/outputs 0218 EEC4 ; 0219 EEC4 B9 A2 F0 LDAAY SENDD 0220 EEC7 8D 43 FE STA DDRAQ 0221 EECA ; 0222 EECA ; place command onto data bus 0223 EECA ; 0224 EECA 68 PLA ;restore command 0225 EECB 8D 4F FE STA PAPQ 0226 EECE ; 0227 EECE ; speech enable 0228 EECE ; 0229 EECE B9 A4 F0 LDAAY SENDS 0230 EED1 8D 40 FE STA PBQ 0231 EED4 ; 0232 EED4 ; wait for speech ready 0233 EED4 ; 0234 EED4 SPWAIT 0235 EED4 2C 40 FE BIT PBQ 0236 EED7 30 FB BMI SPWAIT ;[not ready] 0237 EED9 ; 0238 EED9 ; read possible speech data 0239 EED9 ; 0240 EED9 AD 4F FE LDA PAPQ 0241 EEDC 48 PHA 0242 EEDD ; 0243 EEDD ; speech disable 0244 EEDD ; 0245 EEDD B9 A6 F0 LDAAY SENDF 0246 EEE0 8D 40 FE STA PBQ 0247 EEE3 ; 0248 EEE3 ; return 0249 EEE3 ; 0250 EEE3 68 PLA ;restore speech data (not relevant if write) 0251 EEE4 ; 0252 EEE4 SNDSX0 0253 EEE4 28 PLP 0254 EEE5 A8 TAY ;set processor status flags (useful for RSPECH) and Y (for FX calls) 0255 EEE6 60 RTS 0256 EEE7 ] 0257 EEE7 0258 EEE7 0259 EEE7 SRSKIP ;skip to SEROM pointer indicated by SRPTR 0260 EEE7 AD CB 03 LDA SRPTR+&00 0261 EEEA 85 F6 STA ROMPTR+&00 0262 EEEC AD CC 03 LDA SRPTR+&01 0263 EEEF 85 F7 STA ROMPTR+&01 0264 EEF1 [ NOSP = &00 0265 EEF1 | 0266 EEF1 A5 F5 LDA SEROM 0267 EEF3 10 1B BPL SRSK0 ;[skipping within paged ROM] 0268 EEF5 ; 0269 EEF5 ; skipping within speech SEROM 0270 EEF5 ; load address from SEROM/ROMPTR 0271 EEF5 ; 0272 EEF5 SPLOAD ;load address, must not corrupt V 0273 EEF5 ; address given in SEROM/ROMPTR 0274 EEF5 08 PHP Acorn macro assembler Page 114 MOS54 SPEECH DRIVING 0275 EEF6 78 SEI ;N.B. uses SPWK1 0276 EEF7 A5 F6 LDA ROMPTR+&00 0277 EEF9 20 AB EE JSR SPL ;send address lo-byte 0278 EEFC [ MOS125 = &FF 0291 EEFC | 0292 EEFC A5 F5 LDA SEROM 0293 EEFE 4A LSRA 0294 EEFF 6A RORA 0295 EF00 48 PHA 0296 EF01 6A RORA 0297 EF02 45 F7 EOR ROMPTR+&01 0298 EF04 29 C0 ANDIM &C0 0299 EF06 45 F7 EOR ROMPTR+&01 0300 EF08 20 AB EE JSR SPL ;send address hi-byte 0301 EF0B 68 PLA 0302 EF0C 20 B4 EE JSR SPL1 ;send address hi-nibble 0303 EF0F ] 0304 EF0F 28 PLP 0305 EF10 SRSK0 0306 EF10 ] 0307 EF10 60 RTS 0308 EF11 0309 EF11 0310 EF11 [ FALSE=0 0323 EF11 ] 0324 EF11 0325 EF11 0326 EF11 < &0001 0327 EF11 0328 EF11 0329 EF11 LNK MOS56 0001 EF11 0002 EF11 ; > MOS56 0003 EF11 TTL MOS56 Keyboard management 0004 EF11 OPT MOS56 Acorn macro assembler Page 115 MOS56 Keyboard management 0005 EF11 ;(c) 1981 ACORN Computers Limited 0006 EF11 ;BBC Microcomputer Machine Operating System (MOS) 0007 EF11 ;Change record: 0008 EF11 ;202 01-May-82 PB Programmable TAB key 0009 EF11 ;.05 16-Nov-81 PB Fix CTRL/SHIFT matrix h/w problem 0010 EF11 ;100 04-Sep-81 PB Remove SHIFT and CTRL debounce 0011 EF11 ;Author(s): 0012 EF11 ;PB Paul Bond 0013 EF11 ;MP Mike Prees 0014 EF11 ; STATUS BYTE USES (KSTAT) 0015 EF11 ; N.B. status byte is NEVER zero 0016 EF11 ; (CAPITALS and SHIFT lock never concurrent) 0017 EF11 ; BIT 0 not used 0018 EF11 ; BIT 1 not used 0019 EF11 ; BIT 2 not used 0020 EF11 ; BIT 3 SHIFT 0021 EF11 ; BIT 4 not CAPITALS lock 0022 EF11 ; BIT 5 not SHIFT lock 0023 EF11 ; BIT 6 CTRL 0024 EF11 ; BIT 7 shift enable (only meaningful if a lock is active) 0025 EF11 ; SEQUENCE OF EVENTS :- 0026 EF11 ; 1. CHECK SHIFT KEY 0027 EF11 ; 2. CHECK CONTROL KEY 0028 EF11 ; 3. PROCESS CURRENT KEY 0029 EF11 ; 4. PROCESS OLD KEY 0030 EF11 ; 5. SCAN KEYS IF REQ'D 0031 EF11 ; 6. ENABLE CA2 IF REQ'D 0032 EF11 0033 EF11 0034 EF11 KBDAW 0035 EF11 A2 FF LDXIM &FF ;prepare to enable keyboard timer interrupts 0036 EF13 ; 0037 EF13 ; IF ALL KEYS UP & FORGOTTEN, RESTORE INTERRUPTS 0038 EF13 ; 0039 EF13 A5 EC LDA CKEY 0040 EF15 05 ED ORA OKEY 0041 EF17 D0 06 BNE KBDISX ;[at least one active key, so keep keyboard interrupt disabled] 0042 EF19 ; 0043 EF19 ; enable keyboard interrupt 0044 EF19 ; 0045 EF19 A9 81 LDAIM &81 0046 EF1B 8D 4E FE STA IERQ 0047 EF1E E8 INX ;X:=0, disable keyboard timer interrupts 0048 EF1F ; 0049 EF1F KBDISX 0050 EF1F 8E 42 02 STX KSEMA ;set keyboard timer interrupt control flag 0051 EF22 ; $00 => disabled, $FF => enabled 0052 EF22 ; 0053 EF22 KBDIS 0054 EF22 08 PHP 0055 EF23 ; disable keyboard, coping with CAPITALS & SHIFT lock LEDs 0056 EF23 AD 5A 02 LDA KSTAT 0057 EF26 ; isolate CAPITALS lock and SHIFT lock states 0058 EF26 4A LSRA 0059 EF27 29 18 ANDIM &18 0060 EF29 ; update LED1 (CAPITALS lock) 0061 EF29 09 06 ORAIM &06 ;use addressable latch output 6 0062 EF2B 8D 40 FE STA PBQ ;store LED1 0063 EF2E ; update LED2 (SHIFT lock) 0064 EF2E 4A LSRA ;move state into bit3 0065 EF2F 09 07 ORAIM &07 ;use addressable latch output 7 0066 EF31 8D 40 FE STA PBQ ;store LED2 0067 EF34 ; 0068 EF34 [ TRUE=0 0069 EF34 20 37 F1 JSR KALLOX 0070 EF37 | 0073 EF37 ] 0074 EF37 ; 0075 EF37 68 PLA 0076 EF38 60 RTS 0077 EF39 0078 EF39 DEFKEY ;keyboard control effect 0079 EF39 ; 0080 EF39 ; entered with: 0081 EF39 ; C=0, V=0 => SHIFT/CTRL test 0082 EF39 ; C=1, V=0 => keyboard scan 0083 EF39 ; C=0, V=1 => keyboard interrupt 0084 EF39 ; C=1, V=1 => timer interrupt 0085 EF39 ; 0086 EF39 ; route keyboard entry reason 0087 EF39 ; 0088 EF39 50 0A BVC KEYV0 ;[V=0] 0089 EF3B ; 0090 EF3B A9 01 LDAIM &01 0091 EF3D 8D 4E FE STA IERQ 0092 EF40 ; 0093 EF40 B0 08 BCS KYBD ;[timer interrupt entry] 0094 EF42 4C 3C F0 JMP KBDAT ;[keyboard interrupt] 0095 EF45 ; 0096 EF45 KEYV0 0097 EF45 90 06 BCC TSHIFT ;[SHIFT/CTRL test] 0098 EF47 4C DA F0 JMP SKFMA ;C=1, scan keyboard 0099 EF4A 0100 EF4A KYBD ;C=1 0101 EF4A ; entered when key(s) active AND timer interrupt 0102 EF4A ; 0103 EF4A ; ensure no more keyboard timer interrupts 0104 EF4A EE 42 02 INC KSEMA ;KSEMA := 0 0105 EF4D ; 0106 EF4D TSHIFT ;C=0 0107 EF4D ; entry point used by test shift routine (uses C=1) 0108 EF4D ; clear SHIFT and CTRL status 0109 EF4D AD 5A 02 LDA KSTAT 0110 EF50 29 B7 ANDIM CTLSHI ;N.B. A will accumulate new state 0111 EF52 ; set SHIFT key status 0112 EF52 A2 00 LDXIM ZERO ;N.B. SHIFT key is at matrix entry 0 0113 EF54 20 57 F0 JSR KC ;get state of SHIFT key 0114 EF57 ; N.B. C not corrupted 0115 EF57 86 FA STX KTEMP ;save state of SHIFT key for SHIFT/CAPS invert feature 0116 EF59 ; KTEMP = 1xxx xxxx => SHIFT 0117 EF59 ; KTEMP = 0xxx xxxx => no SHIFT 0118 EF59 B8 CLV 0119 EF5A 10 05 BPL KYBD1 ;[SHIFT key not active] 0120 EF5C ; shift key active and within timer interrupt routine 0121 EF5C 2C 47 D9 BIT FFBYT 0122 EF5F 09 08 ORAIM SHFT 0123 EF61 KYBD1 0124 EF61 ; set CTRL key status 0125 EF61 E8 INX ;X := 1, N.B. CTRL key is at matrix entry 1 0126 EF62 20 57 F0 JSR KC ;get state of CTRL key 0127 EF65 90 BB BCC KBDIS ;[testing CTRL and SHIFT, MI=>CTRL, V=>SHIFT] Acorn macro assembler Page 116 MOS56 Keyboard management 0128 EF67 10 02 BPL KYBD2 ;[CTRL key not active] 0129 EF69 ; CTRL key active 0130 EF69 09 40 ORAIM CTRL 0131 EF6B KYBD2 ;A has accumulated new keyboard status 0132 EF6B 8D 5A 02 STA KSTAT ;update keyboard status 0133 EF6E ; evaluate status of the current key 0134 EF6E ; IF IT IS & WAS OPEN, THEN FORGET IT 0135 EF6E ; IF OPEN & WAS CLOSED, MARK AS OPEN 0136 EF6E ; IF CLOSED & WAS OPEN, MARK AS CLOSED 0137 EF6E ; IF CLOSED & WAS CLOSED, THEN DECREMENT 0138 EF6E ; AUTO-REPEAT COUNTER. IF THIS GOES TO 0139 EF6E ; ZERO (IT STARTS AT 1 INITIALLY) THEN 0140 EF6E ; TRANSMIT CHARACTER TO RDCH BUFFER 0141 EF6E ; (UNLESS IT IS SHF LOCK OR CAPS LOCK) 0142 EF6E ; IF AUTO REPEAT PERMANENTLY DISABLED 0143 EF6E ; THEN DON'T RESET THIS COUNTER. 0144 EF6E A6 EC LDX CKEY 0145 EF70 F0 12 BEQ KBDWU ;[no current key] 0146 EF72 ; current key exists 0147 EF72 20 57 F0 JSR KC ;get status of current key 0148 EF75 30 10 BMI KBDX ;[current key closed] 0149 EF77 ; current key open 0150 EF77 E4 EC CPX CKEY 0151 EF79 KBDW 0152 EF79 86 EC STX CKEY ;update open/closed state of current key 0153 EF7B D0 07 BNE KBDWU ;[current key: is open was closed, or is closed was open] 0154 EF7D ; CURRENT KEY HAS BEEN OPEN FOR TWO CLOCK 0155 EF7D ; CYCLES, SO 'FORGET' IT BY ZEROING CKEY 0156 EF7D ; (KEY VALUES START AT 16 IN THIS RTNE) 0157 EF7D ; ALSO SET COUNTER TO 1 0158 EF7D ; indicate no current key 0159 EF7D A2 00 LDXIM ZERO 0160 EF7F 86 EC STX CKEY 0161 EF81 FCSP ;fix to CTRL/SHIFT h/w problem 0162 EF81 20 4C F0 JSR AR ;update auto-repeat intervals 0163 EF84 KBDWU 0164 EF84 4C 16 F0 JMP KBDY 0165 EF87 KBDX ;current KEY IS CLOSED:IF WAS OPEN,SIMPLY 0166 EF87 ; UPDATE STATUS,ELSE CHECK COUNTER 0167 EF87 ; AND PROCESS CHAR IF REQ'D. 0168 EF87 E4 EC CPX CKEY 0169 EF89 D0 EE BNE KBDW ;[current key: is closed, was open] 0170 EF8B ; current key is closed and was closed 0171 EF8B A5 E7 LDA ARCTR 0172 EF8D F0 23 BEQ KBDXS ;[auto-repeat suppressed] 0173 EF8F ; decrement auto-repeat countdown 0174 EF8F C6 E7 DEC ARCTR 0175 EF91 D0 1F BNE KBDXS ;[auto-repeat interval not exhausted] 0176 EF93 ; auto-repeat interval exhausted 0177 EF93 ; auto-repeat countdown := delay/repeat period 0178 EF93 AD CA 02 LDA FARCTR 0179 EF96 85 E7 STA ARCTR 0180 EF98 ; next auto-repeat interval := repeat period 0181 EF98 AD 55 02 LDA ARSET 0182 EF9B 8D CA 02 STA FARCTR 0183 EF9E ; 0184 EF9E AD 5A 02 LDA KSTAT 0185 EFA1 ; test for shift lock key 0186 EFA1 A6 EC LDX CKEY 0187 EFA3 E0 D0 CPXIM SHLKKY ;IS THIS THE SHIFT LOCK? 0188 EFA5 D0 0D BNE KCPLK ;[key is not SHIFT lock] 0189 EFA7 ; 0190 EFA7 ; SHIFT LOCK key processing 0191 EFA7 09 90 ORAIM CAPSL+INVERT ;clear CAPITALS lock state 0192 EFA9 49 A0 EORIM SHFTL+INVERT ;flip SHIFT lock state and clear invert 0193 EFAB KEYBD3 ;update keyboard status 0194 EFAB 8D 5A 02 STA KSTAT ;store SHIFT lock state 0195 EFAE ; suppress auto-repeat 0196 EFAE A9 00 LDAIM ZERO 0197 EFB0 85 E7 STA ARCTR 0198 EFB2 KBDXS 0199 EFB2 [ MOS125 = &FF 0201 EFB2 | 0202 EFB2 B0 62 BCS KBDY ;always branch 0203 EFB4 ] 0204 EFB4 0205 EFB4 KCPLK ;CAPS key processing 0206 EFB4 E0 C0 CPXIM CPLKKY 0207 EFB6 D0 0E BNE KCPLK1 ;[not CAPITALS lock] 0208 EFB8 ; clear SHIFT lock state 0209 EFB8 09 A0 ORAIM SHFTL+INVERT 0210 EFBA ; add in SHIFT invert status 0211 EFBA 24 FA BIT KTEMP 0212 EFBC 10 04 BPL KCPLK2 ;[not SHIFT/CAPS] 0213 EFBE ; SHIFT/CAPS - force CAPS invert 0214 EFBE 09 10 ORAIM CAPSL 0215 EFC0 49 80 EORIM INVERT 0216 EFC2 KCPLK2 0217 EFC2 ; flip CAPITALS lock state 0218 EFC2 49 90 EORIM CAPSL+INVERT 0219 EFC4 ; set CAPITALS lock state and disable auto-repeat 0220 EFC4 [ MOS125 = &FF 0222 EFC4 | 0223 EFC4 B0 E5 BCS KEYBD3 ;C=1 from CPXIM 0224 EFC6 ] 0225 EFC6 0226 EFC6 KCPLK1 0227 EFC6 ; AT THIS POINT, WE HAVE A CHARACTER FOR RDCH 0228 EFC6 ; NOW LOOK UP CODE AND MODIFY BY SHIFT 0229 EFC6 ; CONTROL OR CAPS LOCK AS APPROPRIATE 0230 EFC6 ; convert current key code to ASCII 0231 EFC6 BD D8 EF LDAAX KTBL -&80 0232 EFC9 D0 03 BNE NTAB ;[not TAB key] 0233 EFCB ; TAB key 0234 EFCB AD 6B 02 LDA TABCOD 0235 EFCE NTAB 0236 EFCE 0237 EFCE [ FALSE=0 0256 EFCE ] 0257 EFCE 0258 EFCE ; setup for KSTAT tests 0259 EFCE AE 5A 02 LDX KSTAT 0260 EFD1 86 FA STX KTEMP 0261 EFD3 ; check for CTRL 0262 EFD3 26 FA ROL KTEMP 0263 EFD5 10 07 BPL KCONV6 ;[no CTRL] 0264 EFD7 ; cannot support two-key rollover with CTRL (h/w constraint) 0265 EFD7 A6 ED LDX OKEY 0266 EFD9 FCSP1 ;chained branch 0267 EFD9 D0 A6 BNE FCSP ;[at least two keys pressed] 0268 EFDB ; convert character to associated control character Acorn macro assembler Page 117 MOS56 Keyboard management 0269 EFDB 20 29 EB JSR CTRLCH 0270 EFDE KCONV6 0271 EFDE ; check for SHIFT lock 0272 EFDE [ MOS125 = &FF 0290 EFDE | 0291 EFDE 26 FA ROL KTEMP 0292 EFE0 26 FA ROL KTEMP ;skip over CAPITALS lock state 0293 EFE2 90 07 BCC KCONV4 ;[SHIFT lock] 0294 EFE4 ; check for CAPS lock 0295 EFE4 30 0D BMI KCONV2 ;[no CAPS lock or SHIFT lock] 0296 EFE6 ; convert character to upper case 0297 EFE6 ; check for character in the range 'A' to 'Z' or 'a' to 'z' 0298 EFE6 20 49 E5 JSR CAPS 0299 EFE9 B0 08 BCS KCONV2 ;[not alpha] 0300 EFEB ; character is an alpha 0301 EFEB KCONV4 0302 EFEB 20 06 EB JSR SHIFT ;invert case of alpha 0303 EFEE ] 0304 EFEE ; check for shift disabled 0305 EFEE AE 5A 02 LDX KSTAT 0306 EFF1 10 0B BPL KCONV1 ;[shift disabled] 0307 EFF3 KCONV2 ;check for SHIFT 0308 EFF3 26 FA ROL KTEMP 0309 EFF5 10 07 BPL KCONV1 ;[no SHIFT] 0310 EFF7 ; cannot support two-key rollover with SHIFT (h/w constraint) 0311 EFF7 A6 ED LDX OKEY 0312 EFF9 D0 DE BNE FCSP1 ;[at least two keys pressed] 0313 EFFB ; shift character 0314 EFFB 20 06 EB JSR SHIFT 0315 EFFE KCONV1 0316 EFFE ; 0317 EFFE ; check for interrupt character 0318 EFFE ; 0319 EFFE CD 6C 02 CMP INTCH 0320 F001 D0 07 BNE KESC1 ;[not interrupt character] 0321 F003 AE 75 02 LDX ESCHAR 0322 F006 D0 02 BNE KESC1 ;[treat as normal character] 0323 F008 ; 0324 F008 ; X=0, Z=1 0325 F008 ; 0326 F008 86 E7 STX ARCTR ;suppress auto-repeat for escape if escape condition enabled 0327 F00A KESC1 0328 F00A ; 0329 F00A ; allow interrupts 0330 F00A ; 0331 F00A A8 TAY ;Y := character (will be passed to RDCHS) 0332 F00B 20 32 F1 JSR KALLOW 0333 F00E ; 0334 F00E ; insert character into RDCH buffer 0335 F00E ; 0336 F00E AD 59 02 LDA NETKDS 0337 F011 D0 03 BNE KBDY ;[keyboard disabled] 0338 F013 20 56 E5 JSR RDCHS 0339 F016 ; 0340 F016 KBDY ; NOW WE EVALUATE THE OLD KEY STATUS. 0341 F016 ; IF OPEN FOR 2 CLOCK CYCLES, FORGET IT 0342 F016 ; OTHERWISE, SIMPLY MEMORISE IT! 0343 F016 A6 ED LDX OKEY 0344 F018 F0 0B BEQ KBDA ;[old key does not exist] 0345 F01A ; 0346 F01A ; old key exists 0347 F01A 20 57 F0 JSR KC 0348 F01D 86 ED STX OKEY ;remember old key state 0349 F01F 30 04 BMI KBDA ;[old key closed] 0350 F021 ; 0351 F021 ; old key open 0352 F021 [ FALSE=0 0356 F021 ] 0357 F021 ; 0358 F021 ; old key: is open, was open 0359 F021 A2 00 LDXIM ZERO 0360 F023 86 ED STX OKEY ;indicate no old key 0361 F025 KBDA ; NOW CHECK TO SEE IF A SCAN IS NEEDED. 0362 F025 ; IF OLD KEY ZERO, DO SCAN. IF KEY DOWN & 0363 F025 ; NOT EQUAL CKEY THEN SET OLD=CURRENT, & THIS 0364 F025 ; ONE = CURRENT, RESET STATUS CHANGE BITS 0365 F025 A6 ED LDX OKEY 0366 F027 D0 16 BNE KBDAU ;[old key exists] 0367 F029 ; no old key so scan keyboard 0368 F029 A0 EC LDYIM CKEY 0369 F02B 20 D5 F0 JSR ISCAN 0370 F02E 30 09 BMI KBDAS ;[all keys searched] 0371 F030 ; closed key found other than current key 0372 F030 ; new current key found 0373 F030 ; set old key = current key 0374 F030 A5 EC LDA CKEY 0375 F032 85 ED STA OKEY 0376 F034 KBDAR ;set new current key 0377 F034 86 EC STX CKEY ;current key := new key number 0378 F036 20 4C F0 JSR AR ;update auto-repeat intervals 0379 F039 4C 11 EF KBDAS JMP KBDAW 0380 F03C KBDAT 0381 F03C ; ENTRY POINT FROM ANY KEY 0382 F03C ; DOWN INTERRUPT 0383 F03C ; enable keyboard by scanning random key (X) 0384 F03C 20 57 F0 JSR KC 0385 F03F KBDAU ;find new current key 0386 F03F A5 EC LDA CKEY 0387 F041 D0 F6 BNE KBDAS ;[current key exists, should only exist during power up] 0388 F043 ; scan keyboard matrix entries 0389 F043 A0 ED LDYIM OKEY 0390 F045 20 D5 F0 JSR ISCAN 0391 F048 30 EF BMI KBDAS ;[processed all keys] 0392 F04A ; pressed key found other than old key 0393 F04A ; new current key identified 0394 F04A 10 E8 BPL KBDAR ;[ALWAYS JUMP] 0395 F04C ; NEVER fall thru 0396 F04C 0397 F04C 0398 F04C AR ;set auto-repeat interval to reflect next character 0399 F04C A2 01 LDXIM &01 0400 F04E 86 E7 STX ARCTR 0401 F050 ; set next auto-repeat interval to delay period 0402 F050 AE 54 02 LDX FARSET 0403 F053 8E CA 02 STX FARCTR 0404 F056 60 RTS 0405 F057 0406 F057 0407 F057 [ FALSE=0 0414 F057 ] 0415 F057 Acorn macro assembler Page 118 MOS56 Keyboard management 0416 F057 KC 0417 F057 ; KEYBOARD ACCESS SUBROUTINE 0418 F057 ; read state of key 0419 F057 ; X = 0rrrcccc 0420 F057 ; r = row, c = column 0421 F057 ; N.B. A and C not corrupted 0422 F057 [ 1=0 ;$Tutu 0434 F057 | 0435 F057 ; enable keyboard 0436 F057 A0 03 LDYIM &03 0437 F059 8C 40 FE STY PBQ 0438 F05C ; select VIAA PA6-PA0 as outputs 0439 F05C A0 7F LDYIM &7F 0440 F05E 8C 43 FE STY DDRAQ 0441 F061 8E 4F FE STX PAPQ ;select matrix element 0442 F064 AE 4F FE LDX PAPQ ;read element status: N=0 => open, N=1 => closed 0443 F067 60 RTS 0444 F068 ] 0445 F068 0446 F068 0447 F068 0448 F068 0449 F068 ; KEY CONVERSION TABLE 0450 F068 ; ROW 0 0451 F068 ; not relevant 0452 F068 ; (consists of SHIFT, CTRL and start-up options) 0453 F068 KTBL0 0454 F068 F058 KTBL * KTBL0 -&10 0455 F068 ; ROW 1 0456 F068 71 = "q" 0457 F069 33 = "3" ;shift '#' 0458 F06A 34 = "4" ;shift '$' 0459 F06B 35 = "5" ;shift '%' 0460 F06C 84 = SOFTK4 ;f4 0461 F06D 38 = "8" ;shift '(' 0462 F06E 87 = SOFTK7 ;f7 0463 F06F 2D = "-" ;shift '=' 0464 F070 5E = "^" ;shift '~' 0465 F071 8C = CURLFT ;cursor left (fC) 0466 F072 0467 F072 ; 'hide' 6 bytes 0468 F072 [ MOS125 = &FF 0474 F072 | 0475 F072 PUTCHK 0476 F072 0477 F072 ;Output byte to cassette and add to check sum. 0478 F072 0479 F072 20 AB F8 JSR PUTCAS 0480 F075 4C E6 F7 JMP ADDCRC 0481 F078 ] 0482 F078 0483 F078 ; ROW 2 0484 F078 80 = SOFTK0 ;f0 0485 F079 77 = "w" 0486 F07A 65 = "e" 0487 F07B 74 = "t" 0488 F07C 37 = "7" ;shift single quote 0489 F07D 69 = "i" 0490 F07E 39 = "9" ;shift ')' 0491 F07F 30 = "0" ;same shifted 0492 F080 POUNDM 0493 F080 5F = "_" ;shift POUND 0494 F081 8E = CURDWN ;cursor down (fE) 0495 F082 0496 F082 ; 'hide' 6 bytes 0497 F082 6C FE FD JMITST JMI TSTSFT 0498 F085 6C FA 00 JMI JMI JMILO ;jump to specific OSBYTE routine, C=1 0499 F088 0500 F088 ; ROW 3 0501 F088 31 = "1" ;shift '!' 0502 F089 32 = "2" ;shift double quote 0503 F08A 64 = "d" 0504 F08B 72 = "r" 0505 F08C 36 = "6" ;shift '&' 0506 F08D 75 = "u" 0507 F08E 6F = "o" 0508 F08F 70 = "p" 0509 F090 5B = "[" ;shift curly left bracket 0510 F091 8F = CURUP ;cursor up (fF) 0511 F092 0512 F092 ; 'hide' 6 bytes 0513 F092 2C 47 D9 JMIKYV BIT FFBYT 0514 F095 6C 28 02 JMIKEY JMI KEYVEC 0515 F098 0516 F098 ; ROW 4 0517 F098 01 = &01 ;CAPS lock 0518 F099 61 = "a" 0519 F09A 78 = "x" 0520 F09B 66 = "f" 0521 F09C 79 = "y" 0522 F09D 6A = "j" 0523 F09E 6B = "k" 0524 F09F 40 = AT ;same shifted 0525 F0A0 3A = ":" ;shift '*' 0526 F0A1 0D = MCR ;same shifted 0527 F0A2 0528 F0A2 [ NOSP = &00 0538 F0A2 | 0539 F0A2 ; 'hide' 6 bytes 0540 F0A2 SENDD 0541 F0A2 00 = &00 ;inputs 0542 F0A3 FF = &FF ;outputs 0543 F0A4 SENDS 0544 F0A4 01 = &01 ;read enable 0545 F0A5 02 = &02 ;write enable 0546 F0A6 SENDF 0547 F0A6 09 = &09 ;read disable 0548 F0A7 0A = &0A ;write disable 0549 F0A8 ] 0550 F0A8 0551 F0A8 ; ROW 5 0552 F0A8 02 = &02 ;SHIFT lock 0553 F0A9 73 = "s" 0554 F0AA 63 = "c" 0555 F0AB 67 = "g" 0556 F0AC 68 = "h" 0557 F0AD 6E = "n" 0558 F0AE 6C = "l" 0559 F0AF 3B = ";" ;shift '+' 0560 F0B0 5D = "]" ;shift curly right bracket 0561 F0B1 7F = MDEL ;same shifted Acorn macro assembler Page 119 MOS56 Keyboard management 0562 F0B2 0563 F0B2 ; 'hide' 6 bytes 0564 F0B2 RMLA ;read machine low memory address 0565 F0B2 AC 44 02 LDY HWM 0566 F0B5 A2 00 LDXIM ZERO 0567 F0B7 60 RTS 0568 F0B8 0569 F0B8 ; ROW 6 0570 F0B8 00 = ZERO ;TAB - programmable TAB key 0571 F0B9 7A = "z" 0572 F0BA 20 = SPACE ;same shifted 0573 F0BB 76 = "v" 0574 F0BC 62 = "b" 0575 F0BD 6D = "m" 0576 F0BE 2C = "," ;shift '<' 0577 F0BF 2E = "." ;shift '>' 0578 F0C0 2F = "/" ; shift '?' 0579 F0C1 8B = MCOPY ;copy character at cursor (fB) 0580 F0C2 0581 F0C2 ; 'hide' 6 bytes 0582 F0C2 [ MOS125 = &FF 0587 F0C2 | 0588 F0C2 OPT 0589 F0C2 0A ASLA ;lsb(A) := 0 0590 F0C3 ;* LDAIM $00 0591 F0C3 EOF 0592 F0C3 29 01 ANDIM &01 ;$00 => OPT, $01 => EOF 0593 F0C5 4C 9C E0 JMP JMIFSC ;[ALWAYS JUMP, present option to file system AND return] 0594 F0C8 ] 0595 F0C8 0596 F0C8 ; ROW 7 0597 F0C8 1B = ESC ;same shifted 0598 F0C9 81 = SOFTK1 ;f1 0599 F0CA 82 = SOFTK2 ;f2 0600 F0CB 83 = SOFTK3 ;f3 0601 F0CC 85 = SOFTK5 ;f5 0602 F0CD 86 = SOFTK6 ;f6 0603 F0CE 88 = SOFTK8 ;f8 0604 F0CF 89 = SOFTK9 ;f9 0605 F0D0 5C = "\" ;shift '|' 0606 F0D1 8D = CURRHT ;cursor right (fD) 0607 F0D2 ENDKT 0608 F0D2 0609 F0D2 0610 F0D2 6C 20 02 JMIEVT JMI EVTVEC ;user event 0611 F0D5 0612 F0D5 0613 F0D5 [ MOS125 = &FF 0653 F0D5 ] 0654 F0D5 0655 F0D5 0656 F0D5 ISCAN ;scan keys from matrix address $10 0657 F0D5 18 CLC ;ignore key addressed by Y 0658 F0D6 ; 0659 F0D6 XSCANA ;FX entry, scan keys from matrix address $10, C=1 (ignore no keys) 0660 F0D6 A2 10 LDXIM &10 0661 F0D8 ; 0662 F0D8 XSCANB ;FX entry, scan keys from matrix address X, C=1 (ignore no keys) 0663 F0D8 B0 BB BCS JMIKEY ;[route FX entries thru indirection] 0664 F0DA ; 0665 F0DA SKFMA ;scan keys from matrix address (should have C=1) 0666 F0DA ; start scan address in X 0667 F0DA ; X>=0 => scan keys starting at X 0668 F0DA ; X<0 => investigate key NOT(X) 0669 F0DA ; 0670 F0DA 8A TXA 0671 F0DB 10 05 BPL SKFMA2 ;[scan keys] 0672 F0DD ; C=1 0673 F0DD ; look at key 0674 F0DD ; 0675 F0DD 20 57 F0 JSR KC ;result in top bit of X (N.B. does not alter C) 0676 F0E0 ; C=1 0677 F0E0 B0 55 BCS KALLOX ;return result in A 0678 F0E2 ; 0679 F0E2 SKFMA2 0680 F0E2 ; 0681 F0E2 08 PHP ;save request source indicator (in C) 0682 F0E3 90 02 BCC SKFMA1 ;[CKEY or OKEY entry] 0683 F0E5 A0 EE LDYIM CKEY+&02 0684 F0E7 SKFMA1 0685 F0E7 ; 0686 F0E7 99 DF 01 STAAY KSCSTA-CKEY ;save scan start address 0687 F0EA ; return MI => no keys, otherwise X = key 0688 F0EA A2 09 LDXIM &09 0689 F0EC ; 0690 F0EC ISCAN1 0691 F0EC ; allow interrupts 0692 F0EC ; 0693 F0EC 20 32 F1 JSR KALLOW 0694 F0EF ; 0695 F0EF ; select VIAA PA6-PA0 as outputs 0696 F0EF ; 0697 F0EF A9 7F LDAIM &7F 0698 F0F1 8D 43 FE STA DDRAQ 0699 F0F4 ; 0700 F0F4 ; claim keyboard 0701 F0F4 ; 0702 F0F4 A9 03 LDAIM &03 0703 F0F6 8D 40 FE STA PBQ 0704 F0F9 ; 0705 F0F9 ; reset keyboard interrupt line 0706 F0F9 ; 0707 F0F9 A9 0F LDAIM &0F ;N.B. use non-existent group which does not interrupt 0708 F0FB 8D 4F FE STA PAPQ 0709 F0FE ; 0710 F0FE ; clear latched event 0711 F0FE ; 0712 F0FE A9 01 LDAIM &01 0713 F100 8D 4D FE STA IFRQ 0714 F103 ; 0715 F103 8E 4F FE STX PAPQ ;select key (force no key first time thru loop) 0716 F106 0717 F106 2C 4D FE BIT IFRQ ;test for latched event 0718 F109 F0 21 BEQ ISCAND ;[no group key pressed] 0719 F10B ; 0720 F10B ; key pressed in this group 0721 F10B ; 0722 F10B 8A TXA ;A := key at start of group 0723 F10C ; 0724 F10C ISCANC ;scan group to find pressed key within group 0725 F10C ; check key against start scan address Acorn macro assembler Page 120 MOS56 Keyboard management 0726 F10C ; 0727 F10C D9 DF 01 CMPAY KSCSTA-CKEY 0728 F10F 90 16 BCC ISCANE ;[ignore key] 0729 F111 ; 0730 F111 8D 4F FE STA PAPQ 0731 F114 2C 4F FE BIT PAPQ 0732 F117 10 0E BPL ISCANE ;[individual key not pressed] 0733 F119 ; 0734 F119 ; individual key pressed 0735 F119 ; 0736 F119 ISCANB ;key press detected at key A 0737 F119 ; 0738 F119 ; key found 0739 F119 ; 0740 F119 28 PLP 0741 F11A 08 PHP 0742 F11B B0 13 BCS ISCAN9 ;[ignore no character] 0743 F11D ; 0744 F11D 48 PHA ;save key code 0745 F11E ; 0746 F11E ; check whether to ignore character 0747 F11E ; 0748 F11E 59 00 00 EORAY ZERO 0749 F121 0A ASLA ;ignore top bit 0750 F122 C9 01 CMPIM &01 0751 F124 68 PLA ;restore key code 0752 F125 B0 09 BCS ISCAN9 ;[accept key] 0753 F127 ; 0754 F127 ; ignore key 0755 F127 ; 0756 F127 ISCANE ;ignore key 0757 F127 18 CLC 0758 F128 69 10 ADCIM &10 0759 F12A 10 E0 BPL ISCANC ;[step to next key within group] 0760 F12C ; 0761 F12C ; key group exhausted 0762 F12C ; 0763 F12C ISCAND ;scan within group failed 0764 F12C CA DEX 0765 F12D 10 BD BPL ISCAN1 ;[try next group] 0766 F12F ; no key found, X<0 0767 F12F 8A TXA ;set up to negate effect of TAX 0768 F130 ; 0769 F130 ISCAN9 ;accept key 0770 F130 AA TAX ;X := key address 0771 F131 ; 0772 F131 28 PLP 0773 F132 ; 0774 F132 KALLOW ;release keyboard and allow interrupts 0775 F132 ; **** MUST NOT CORRUPT Y **** 0776 F132 ; release keyboard 0777 F132 ; 0778 F132 20 37 F1 JSR KALLOX ;release keyboard 0779 F135 ; 0780 F135 ; allow interrupts 0781 F135 ; 0782 F135 58 CLI 0783 F136 78 SEI 0784 F137 ; 0785 F137 KALLOX ;release keyboard 0786 F137 A9 0B LDAIM &0B 0787 F139 8D 40 FE STA PBQ 0788 F13C ; 0789 F13C ; return result in N 0790 F13C ; 0791 F13C 8A TXA ;N=1 => no new key, N=0 => new key in X 0792 F13D 60 RTS 0793 F13E 0794 F13E 0795 F13E 0796 F13E < 3 0797 F13E 0798 F13E LNK MOS70 0001 F13E TTL C.F.S. Manifest File - MOS70 0002 F13E OPT &01 0003 F13E 0004 F13E 0005 MOS70 * DEFOPT 0005 F13E 0005 MOS72 * DEFOPT 0006 F13E 0005 MOS74 * DEFOPT 0007 F13E 0005 MOS76 * DEFOPT 0008 F13E 0009 F13E OPT MOS70 Acorn macro assembler Page 121 C.F.S. Manifest File - MOS70 0010 F13E 0011 F13E < &0003 0012 F13E > &0002 0013 F13E 0014 F13E 0015 F13E ;****** C.F.S HEADER FILE ****** 0016 F13E 0017 F13E 0018 F13E 0019 F13E ;cIOBYTS * $00 ;No longer used 0020 F13E 0000 LENSW * &00 ;Zero => LOAD modify's OSFILE block 0021 F13E 0001 DEBUG * &01 ;zero => messages. +ve => no messages 0022 F13E 0000 TUBESW * &00 ;Zero => tube, +ve => no tube 0023 F13E 00FF PREMRG * &FF ;Zero => entry indirections, +ve => none 0024 F13E 00FF GLYN * &FF ;Zero => special IBG code for 0025 F13E ;Glynn. +ve => as per spec. 0026 F13E 0027 F13E ;MANIFESTS 0028 F13E 0029 F13E 00FE ENDBYT * &FE ;Byte after end of file (GETBYT) 0030 F13E 0031 F13E 0091 FXCDRV * &0091 ;FX call number 0032 F13E 00FF READFX * &FF 0033 F13E 0000 WRITFX * &00 0034 F13E 0035 F13E 0001 INHAND * &0001 ;Input handle 0036 F13E 0002 OUTHND * &0002 ;Output handle 0037 F13E 0003 HNDS * &03 ;Both handles 0038 F13E 00FD NOUTHD * &FD 0039 F13E 000B FTSIZE * &000B ;File title size (incl. CR) 0040 F13E 0041 F13E ;Note that the 6850 status bytes (following) 0042 F13E ;have their bottom nybble modified according to 0043 F13E ;the setting of SPEED in the routines RXINIT and TXINIT 0044 F13E 0045 F13E 0030 TXSTAT * &30 ;6850 TX status 0046 F13E ;TXSTAT = ~RTS lo;TXI enabled;8 bits + 1 stop 0047 F13E 00D0 RXSTAT * &D0 0048 F13E ;RXSTAT = ~RTS hi;TXI disabled;8 bits + 1 stop 0049 F13E 0050 F13E 0002 TXBIT * &02 0051 F13E 0001 RXBIT * &01 0052 F13E 0004 DCDBIT * &04 0053 F13E 0054 F13E 0085 SERON * &85 ;Motor on/cass. on/RXCLK=0/TXCLK= 1,0,1 0055 F13E 0005 SEROFF * &05 ;As SERON but motor off 0056 F13E ;ERRORS 0057 F13E 0058 F13E 00DF ERRBAS * &DF 0059 F13E 0060 F13E 00DF CFSERD * ERRBAS -&00 ;EOF 0061 F13E 00DE CFSERB * ERRBAS -&01 ;Channel 0062 F13E 00DD CFSERK * ERRBAS -&02 ;Address 0063 F13E 00DC SYNXER * ERRBAS -&03 ;Syntax 0064 F13E 00DB CFSERF * ERRBAS -&04 ;File 0065 F13E 00DA CFSERH * ERRBAS -&05 ;Block 0066 F13E 00D9 CFSERI * ERRBAS -&06 ;Header 0067 F13E 00D8 CFSERJ * ERRBAS -&07 ;Data 0068 F13E 00D8 CFSERR * CFSERJ ;Bad tape 0069 F13E 0070 F13E 00D7 SFSERR * ERRBAS -&08 ;Bad ROM 0071 F13E 00D6 SFSER1 * ERRBAS -&09 ;File not found 0072 F13E 0073 F13E 00D5 CFSERL * ERRBAS -&0A ;Locked 0074 F13E 0075 F13E 0076 F13E ;STATUS BYTE MASKS 0077 F13E 0078 F13E 0001 INOPEN * &01 0079 F13E 0002 OUTOPN * &02 0080 F13E 0040 LSTBYT * &40 ;Last byte read (GETBYTE) 0081 F13E 0080 EOFBIT * &80 ;Last byte +1 read (GETBYTE) 0082 F13E 00C0 LSTEOF * &C0 ;Last byte & EOF 0083 F13E 0084 F13E 00F7 NCTBIT * &F7 ;Complement of CATBIT 0085 F13E 003F NEFBIT * &3F ;Complement of EOFBIT/lastbyte 0086 F13E 00FE NINHND * &FE ;Complement of INHAND 0087 F13E 003E NECBIT * &3E ;Complement of EOFBIT/lastbyte/openin bit 0088 F13E 0089 F13E 0090 F13E 0091 F13E ;MESSAGE/ERROR SELECTION MASKS 0092 F13E 0093 F13E 0094 F13E 00CC ERRMSK * &CC ;Error bits to zero 0095 F13E 0033 MSGMSK * &33 ;Message bits to zero 0096 F13E 0088 MSGS1 * &88 ;Short messages 0097 F13E 00CC MSGS2 * &CC ;Long messages 0098 F13E 0099 F13E 0011 ABTBIT * &11 ;Abort set 0100 F13E 0022 RETBIT * &22 ;Retry set 0101 F13E 0000 IGBIT * &00 ;Both error bits off => ignore 0102 F13E 0030 NIGBIT * &30 ;Complement of ignore bits 0103 F13E 0104 F13E 00A1 DEFLT * &A1 0105 F13E 0106 F13E ;Default is retry/messages for loaded and saved 0107 F13E ;files, abort/no messages for sequential files. 0108 F13E 0109 F13E 0110 F13E ;INFO FIELDS 0111 F13E 0112 F13E 000C BKINFO * FTSIZE +&01 0113 F13E 000C BKLOAD * BKINFO 0114 F13E 000C BKLDLO * BKLOAD 0115 F13E 000D BKLDHI * BKLDLO +&01 0116 F13E 0010 BKEXEC * BKLOAD +&04 0117 F13E 0014 BKNOLO * BKEXEC +&04 0118 F13E 0015 BKNOHI * BKNOLO +&01 ;Block no. (lo & hi) 0119 F13E 0016 BKSZEL * BKNOHI +&01 0120 F13E 0017 BKSZEH * BKSZEL +&01 0121 F13E 0018 BKFLAG * BKSZEH +&01 ;b7 => last block 0122 F13E 0019 BKSPAR * BKFLAG +&01 0123 F13E 001D BKLAST * BKSPAR +&04 ;Length of info. 0124 F13E 0125 F13E 001D BKWORKK * BKLAST 0126 F13E 001E BKWRK1 * BKWORKK +&01 0127 F13E 001F BKWRK2 * BKWRK1 +&01 0128 F13E 0129 F13E 0130 F13E Acorn macro assembler Page 122 C.F.S. Manifest File - MOS70 0131 F13E 0132 F13E ;BLOCK FLAG MASKS 0133 F13E 0134 F13E 0080 LASTBK * &80 ;NOTE - don't change, BMI and BVS etc. used 0135 F13E 0136 F13E 0137 F13E 0138 F13E ;TIMES 0139 F13E 0140 F13E 0019 DEFGAP * &19 ;25/10 Secs inter block gap 0141 F13E 0006 GAP * &06 ;SAVE/LOAD gap 0142 F13E 0143 F13E 0144 F13E ;BITS AND PIECES 0145 F13E 0146 F13E 0147 F13E 0148 F13E 0149 F13E 0008 CATBIT * &08 ;Doing a CAT 0150 F13E 0088 MONBIT * &88 ;Messages on/off 0151 F13E 0152 F13E 0153 F13E 02EA INBSZE * CFSA ;GBYT block size (retained over FS change) 0154 F13E 02EC BUFFLG * INBSZE +&02 ;Note BUFFLG & INBZSE must be contig. 0155 F13E 0156 F13E 02ED FINBYT * CFSD ;Last byte in GETBYT buffer 0157 F13E 0158 F13E ;BUFFERS 0159 F13E 0160 F13E 0A00 INBUFR * &0A00 0161 F13E 0900 OUTBFR * &0900 ;Sequential access I/O buffers 0162 F13E 0163 F13E ;VARS 0164 F13E 0165 F13E 0380 VARSS * &0380 0166 F13E 0300 VARPGE * &0300 0167 F13E 0168 F13E 0380 OUTHDR * VARSS ;Header buffer for PUTBYTE 0169 F13E 039D OUTPTR * OUTHDR +BKLAST 0170 F13E 039E INPTR * OUTPTR +&01 0171 F13E 039F INLDEX * INPTR +&01 ;8 bytes load/exec for input file 0172 F13E 03A7 INFILE * INLDEX +&08 ;GETBYTE file name 0173 F13E 03B2 INFO * INFILE +FTSIZE ;Header buffer 0174 F13E 03CF WORKK * INFO +BKWORKK ;Space to read CRC during RDHEAD 0175 F13E 03D1 SEQGAP * WORKK +&02 0176 F13E 03D2 FILNAM * SEQGAP +&01 0177 F13E 03DD NEXTIN * FILNAM +FTSIZE ;Next expected block (GETBYTE) 0178 F13E 03DF OLDFLG * NEXTIN +&02 0179 F13E 0180 F13E 03CB SRPTR * INFO +BKSPAR 0181 F13E 0182 F13E 0183 F13E ;CHIP LOCATIONS 0184 F13E 0185 F13E FE08 STATUS * &FE08 0186 F13E FE09 PORT * &FE09 0187 F13E 0188 F13E 0189 F13E 0190 F13E ;DOS/MOS ROUTINES & ADDRESSES 0191 F13E 0192 F13E 0193 F13E 00FF ESCADD * &00FF ;b7 = 1 if ESCAPE occured 0194 F13E 0195 F13E 0196 F13E ;TUBE THINGS 0197 F13E 0198 F13E 0000 TUBER * &00 ;Value in A for tube READ initialisation 0199 F13E 0001 TUBEW * &01 ;Value in A for tube WRITE initialisation 0200 F13E 0004 TUBEX * &04 ;Value in A for tube execute 0201 F13E 0202 F13E 0080 TUBERL * &80 ;A reg. for tube RELEASE 0203 F13E 00C0 TUBECL * &C0 ;A reg. for tube CLAIM 0204 F13E 0205 F13E 002B SFSEND * "+" ;Marker for end of SERROM 0206 F13E 0207 F13E ; interface to code in MOS 0208 F13E ; 0209 F13E 0210 F13E 0211 F13E LNK MOS72 0001 F13E ; FILE -> MOS72 0002 F13E 0003 F13E [ MOS125 = &FF 0005 F13E ] 0006 F13E 0007 F13E TTL C.F.S. Main Routines - INIT 0008 F13E OPT MOS72 Acorn macro assembler Page 123 C.F.S. Main Routines - INIT 0009 F13E 0010 F13E 0011 F13E [ MOS125 = &FF 0045 F13E | 0046 F13E INIT 0047 F13E 0048 F13E ;Initialises CLI and file operation 0049 F13E ;vectors. Motor turned OFF 0050 F13E 0051 F13E ;Z set => 300 baud => speed nybble = 6 0052 F13E ;Z unset => 1200 baud => speed nybble = 5 0053 F13E 0054 F13E ;Speed nybble is OR'd in with 0055 F13E ;6850 status byte during TX/RXinit 0056 F13E 0057 F13E 08 PHP 0058 F13F A9 A1 LDAIM DEFLT 0059 F141 85 E3 STA OPTS ;User status = retry & msgs on 0060 F143 A9 19 LDAIM DEFGAP 0061 F145 8D D1 03 STA SEQGAP 0062 F148 D0 09 BNE SOFTPT 0063 F14A 0064 F14A 0065 F14A CROM ;A=$8D, V=0 0066 F14A TAPE ;A=$8C, V=0 0067 F14A 49 8C EORIM &8C 0068 F14C TAPE12 ;used by RESET, A=X=$00 0069 F14C 0A ASLA 0070 F14D 8D 47 02 STA SROMSW ;A=0 => *TAPE, A=2 => *ROM 0071 F150 E0 03 CPXIM &03 ;test for *TAPE3 0072 F152 08 PHP 0073 F153 0074 F153 0075 F153 ;Note CFSTAT (CFS0) set to zero by MOS free of charge 0076 F153 ;on hard reset 0077 F153 0078 F153 SOFTPT ;Soft entry point (*TAPE) 0079 F153 ] 0080 F153 A9 06 LDAIM FSDIE 0081 F155 20 9C E0 JSR JMIFSC ;present command to file system 0082 F158 A2 06 LDXIM &06 0083 F15A 28 PLP 0084 F15B F0 01 BEQ INITON 0085 F15D CA DEX 0086 F15E 86 C6 INITON STX SPEED 0087 F160 ; 0088 F160 ; initialise filing system indirection table 0089 F160 ; 0090 F160 A2 0E LDXIM &0E 0091 F162 BD E1 D8 INITLP LDAAX CFSTAB -&01 0092 F165 9D 11 02 STAAX FILVEC -&01 0093 F168 CA DEX 0094 F169 D0 F7 BNE INITLP 0095 F16B 86 C2 STX ITYPE ;No i'rupts pending 0096 F16D ; 0097 F16D ; inform paged ROMs of change 0098 F16D ; 0099 F16D A2 0F LDXIM SVFSIC 0100 F16F ; 0101 F16F SVOP ;issue service ROM operati 0102 F16F ; optype in X 0103 F16F A5 F4 LDA ROMID ;save current ROM id 0104 F171 48 PHA 0105 F172 8A TXA ;A = optype 0106 F173 ; 0107 F173 A2 0F LDXIM NROM-&1 0108 F175 SVOP1 0109 F175 [ $Tutu ; Less farting about with page 02 0115 F175 | 0116 F175 FE A1 02 INCAX ROMS ;test 0117 F178 DE A1 02 DECAX ROMS ;ROMS 0118 F17B 10 0B BPL SVOP2 ;[not a service ROM] 0119 F17D ] 0120 F17D ; found a service ROM 0121 F17D [ MOS125 = &FF 0124 F17D | 0125 F17D 20 D9 DB JSR STXROM 0126 F180 ] 0127 F180 ; call service routine 0128 F180 20 03 80 JSR ROMSFT ;initialise service ROM 0129 F183 AA TAX 0130 F184 F0 05 BEQ SVOP3 ;[service claimed, do not offer to other ROMs] 0131 F186 ; 0132 F186 A6 F4 LDX ROMID ;restore ROM id 0133 F188 SVOP2 0134 F188 CA DEX 0135 F189 10 EA BPL SVOP1 0136 F18B ; X<>0 0137 F18B SVOP3 ;C = return code 0138 F18B ; restore caller's ROMid 0139 F18B 68 PLA 0140 F18C 85 F4 STA ROMID 0141 F18E 8D 30 FE STA ROM 0142 F191 ; restore return code 0143 F191 8A TXA ;A=0 => claimed, A<>0 => not claimed 0144 F192 60 RTS 0145 F193 0146 F193 0147 F193 TTL C.F.S. Main Routines - ARGGO 0148 F193 OPT &01 0149 F193 0150 F193 0151 F193 ;Returns 1 if in 1200 baud cassette 0152 F193 ;2 300 0153 F193 ;3 if in SERROM filing system 0154 F193 0155 F193 ;Note SPEED is 5 if in 1200 and 6 in 300 0156 F193 0157 F193 0158 F193 ARGGO 0159 F193 09 00 ORAIM 0 0160 F195 D0 0D BNE INTRTS ;No action on non-zero entry condition 0161 F197 C0 00 CPYIM &00 0162 F199 D0 09 BNE INTRTS ;If handle not zero -> don't do 0163 F19B [ MOS125 = &FF 0170 F19B | 0171 F19B A9 03 LDAIM &03 0172 F19D 2C 47 02 BIT SROMSW 0173 F1A0 D0 02 BNE INTRTS 0174 F1A2 25 C6 AND SPEED 0175 F1A4 ] Acorn macro assembler Page 124 C.F.S. Main Routines - ARGGO 0176 F1A4 60 INTRTS RTS 0177 F1A5 0178 F1A5 0179 F1A5 TTL C.F.S Main Routines - FSFUNC 0180 F1A5 OPT &01 0181 F1A5 0182 F1A5 [ MOS125 = &FF 0209 F1A5 | 0210 F1A5 FSFUNC 0211 F1A5 0212 F1A5 ;File system operation entry pt. 0213 F1A5 0214 F1A5 C9 07 CMPIM NOTAB 0215 F1A7 B0 FB BCS INTRTS ;Check call legal otherwise, exit 0216 F1A9 0217 F1A9 86 BC STX TEMP 0218 F1AB AA TAX ;Get address from table 0219 F1AC BD F9 FB LDAAX JMPTAB +NOTAB 0220 F1AF 48 PHA ;push hi byte 0221 F1B0 BD F2 FB LDAAX JMPTAB 0222 F1B3 48 PHA ;push lo byte 0223 F1B4 A6 BC LDX TEMP ;Restore argument 0224 F1B6 60 RTS ;enter routine 0225 F1B7 ] 0226 F1B7 0227 F1B7 TTL C.F.S. Main Routines - LOAD 0228 F1B7 OPT &01 0229 F1B7 0230 F1B7 0231 F1B7 ;*********** 0232 F1B7 ;* L O A D * 0233 F1B7 ;*********** 0234 F1B7 0235 F1B7 0236 F1B7 ;On entry A NZ => load from OSFILE 0237 F1B7 ; A =0 => load and run 0238 F1B7 ;Differentiating between these is necessary 0239 F1B7 ;so that the protection bit in the flags 0240 F1B7 ;byte can be checked. 0241 F1B7 0242 F1B7 0243 F1B7 [ MOS125 = &FF 0358 F1B7 ] 0359 F1B7 0360 F1B7 0361 F1B7 0362 F1B7 TTL C.F.S. Main Routines - FILEGO 0363 F1B7 OPT &01 0364 F1B7 0365 F1B7 0366 F1B7 GETFLN 0367 F1B7 0368 F1B7 ;X/Y -> start of file name 0369 F1B7 0370 F1B7 0371 F1B7 MOVFT 0372 F1B7 0373 F1B7 ;Moves file title from ptr. pointed to by X,Y (lo,hi) 0374 F1B7 ;to FILNAM. 0375 F1B7 0376 F1B7 ; SEI 0377 F1B7 86 F2 STX WORK 0378 F1B9 84 F3 STY WORK +&01 0379 F1BB A0 00 LDYIM &00 0380 F1BD 20 82 EA JSR GSINTC ;Initialise 0381 F1C0 A2 00 LDXIM &00 0382 F1C2 20 94 EA MOVFTL JSR GSREAD 0383 F1C5 B0 0D BCS MOVFTX 0384 F1C7 F0 08 BEQ STRERR 0385 F1C9 9D D2 03 STAAX FILNAM 0386 F1CC E8 INX 0387 F1CD E0 0B CPXIM FTSIZE 0388 F1CF D0 F1 BNE MOVFTL 0389 F1D1 0390 F1D1 STRNG0 0391 F1D1 4C A2 EA STRERR JMP BADSTR 0392 F1D4 0393 F1D4 A9 00 MOVFTX LDAIM &00 0394 F1D6 9D D2 03 STAAX FILNAM 0395 F1D9 ; CLI 0396 F1D9 60 RTS 0397 F1DA 0398 F1DA 0399 F1DA FILEGO 0400 F1DA 0401 F1DA ;Entry here from OSFILE. 0402 F1DA 0403 F1DA 48 PHA ;Store load/save indication 0404 F1DB 86 C8 STX GENPTR 0405 F1DD 84 C9 STY GENPTR +&01 0406 F1DF 0407 F1DF A0 00 LDYIM &00 0408 F1E1 B1 C8 LDAIY GENPTR 0409 F1E3 AA TAX ;Set ptr. to file name for MOVFT 0410 F1E4 C8 INY 0411 F1E5 B1 C8 LDAIY GENPTR 0412 F1E7 A8 TAY 0413 F1E8 0414 F1E8 20 B7 F1 JSR MOVFT ;File title -> FILNAM 0415 F1EB A0 02 LDYIM &02 0416 F1ED B1 C8 FILELP LDAIY GENPTR 0417 F1EF 99 BC 03 STAAY INFO +BKLOAD -&02 ;Set LOAD/EXEC address in header buffer 0418 F1F2 99 AE 00 STAAY BKADDR -&02 ;Optional load address stored for LOAD 0419 F1F5 C8 INY 0420 F1F6 C0 0A CPYIM &0A ;Ten coz 2*4 + 2 initially 0421 F1F8 D0 F3 BNE FILELP 0422 F1FA 0423 F1FA 68 PLA 0424 F1FB [ MOS125 = &FF 0429 F1FB | 0430 F1FB D0 5D BNE FILENE 0431 F1FD ] 0432 F1FD 0433 F1FD ;Now doing save 0434 F1FD 0435 F1FD 8D C6 03 FILEL2 STA INFO +BKNOLO ;Set block number in header 0436 F200 8D C7 03 STA INFO +BKNOHI ;while A is zero 0437 F203 B1 C8 FILEL3 LDAIY GENPTR 0438 F205 99 A6 00 STAAY BKADDR -&0A ;BKADDR := data start 0439 F208 C8 INY ;Also sets HIADDR which 0440 F209 ;must be contiguous with BKADDR Acorn macro assembler Page 125 C.F.S. Main Routines - FILEGO 0441 F209 C0 12 CPYIM &12 0442 F20B D0 F6 BNE FILEL3 0443 F20D 0444 F20D 8A TXA ;X preserved from MOVFT 0445 F20E F0 C1 BEQ STRNG0 ;Drops through to SAVE if string OK 0446 F210 0447 F210 0448 F210 TTL C.F.S Main Routines - SAVE 0449 F210 OPT &01 0450 F210 0451 F210 ;*********** 0452 F210 ;* S A V E * 0453 F210 ;*********** 0454 F210 0455 F210 0456 F210 0457 F210 ;Entry here from OSFILE call 0458 F210 0459 F210 20 1C FB JSR SETDEF 0460 F213 0461 F213 20 5F F5 JSR RECORD ;Prompt and motor ON 0462 F216 0463 F216 [ TUBESW=0 0464 F216 A9 00 LDAIM TUBER ;initialise tube for reading 0465 F218 20 B0 FB JSR TBINIT 0466 F21B ] 0467 F21B 0468 F21B 20 D5 FB JSR BUGFIX ;Put out extra char 0469 F21E 0470 F21E 38 SAVELP SEC 0471 F21F A2 FD LDXIM &FD 0472 F221 [ MOS125 = &FF 0475 F221 | 0476 F221 B5 B7 SAVEL1 LDAZX (HIADDR -&FD):AND:&FF 0477 F223 F5 B3 SBCZX (BKADDR -&FD):AND:&FF 0478 F225 ] 0479 F225 9D CB 02 STAAX INFO +BKSZEL-&FD ;Note corrupts Flags byte 0480 F228 E8 INX 0481 F229 D0 F6 BNE SAVEL1 ;Do HIADDR - BKADDR 0482 F22B A8 TAY 0483 F22C D0 0A BNE SAVEL2 ;Msb non-zero => not last block 0484 F22E 0485 F22E ;Now: IF $0100 < block size THEN block size := $0100, 0486 F22E ; not last block 0487 F22E ; ELSE last block 0488 F22E 0489 F22E [ MOS125 = &FF 0502 F22E | 0503 F22E CD C8 03 CMP INFO +BKSZEL ;Note A = X = Y = 0 0504 F231 2A ROLA ;if L=0 then C := (H<=1) else C := (H==0) 0505 F232 CD C9 03 CMP INFO +BKSZEH ;use constant C=1 from CMP 0506 F235 6A RORA ;A = $80 if <=$0100, A = 0 if more 0507 F236 30 08 BMI SAVEL3 ;if last block then don't clamp block size 0508 F238 SAVEL2 ;X = 0, A = Y = undefined 0509 F238 8A TXA ;clear last block flag 0510 F239 8E C8 03 STX INFO +BKSZEL ;Default block size = $0100 0511 F23C E8 INX 0512 F23D 8E C9 03 STX INFO +BKSZEH ;Note N=0 preserved by WRBLOK 0513 F240 8D CA 03 SAVEL3 STA INFO +BKFLAG ;WRBLOK clobbers A, X 0514 F243 ] 0515 F243 0516 F243 20 1C F8 JSR WRBLOK ;Write out data + header 0517 F246 30 11 BMI SAVFIN ;Last block => finished 0518 F248 0519 F248 20 61 F9 JSR ADDBKA ;Add block size to address 0520 F24B 0521 F24B EE C6 03 INC INFO +BKNOLO 0522 F24E D0 CE BNE SAVELP 0523 F250 EE C7 03 INC INFO +BKNOHI ;Inc. block no. for next time 0524 F253 D0 C9 BNE SAVELP ;Assumed always +ve 0525 F255 0526 F255 [ MOS125 = &FF 0527 F255 | 0528 F255 OLDKEY ;force old key state 0529 F255 84 EC STY CKEY ;CKEY := 0 0530 F257 86 ED STX OKEY ;force old key state 0531 F259 SAVFIN ;Exit from SAVE 0532 F259 60 RTS 0533 F25A 0534 F25A C9 FF FILENE CMPIM &FF 0535 F25C D0 FB BNE SAVFIN 0536 F25E 0537 F25E LOADGO 0538 F25E 0539 F25E 08 PHP ;Store interrupt status 0540 F25F 48 PHA ;Store indication of load or load/run 0541 F260 20 1C FB JSR SETDEF ;Set defaults if nesc. 0542 F263 0543 F263 AD C2 03 LDA INFO +BKEXEC 0544 F266 48 PHA ;EQ=> use addr. from C.line or OSFILE 0545 F267 0546 F267 20 64 F6 JSR SRCH0 ;Find file on tape. 0547 F26A LOADL6 0548 F26A 0549 F26A 68 PLA 0550 F26B F0 17 BEQ LOADLB ;Use load address from command line or OSFILE 0551 F26D 0552 F26D ;Move load address from OSFILE command block 0553 F26D ;and check if is $FFFFFFFF, in which case 0554 F26D ;give BAD ADDRESS error 0555 F26D 0556 F26D A2 03 LDXIM &03 0557 F26F 38 SEC 0558 F270 LOADL1 0559 F270 BD BE 03 LDAAX INFO +BKLOAD ;Address from command block 0560 F273 95 B0 STAAX BKADDR 0561 F275 90 02 BCC LOADL2 ;not ADCIM &00 as V may be in use 0562 F277 C9 FF CMPIM &FF 0563 F279 LOADL2 0564 F279 CA DEX 0565 F27A 10 F4 BPL LOADL1 0566 F27C 0567 F27C 90 06 BCC LOADLB ;If CS, all bytes are $FF => error 0568 F27E 0569 F27E 20 DD FA JSR BEEPOF ;Motor off/beep 0570 F281 4C E5 E2 JMP MBADHX 0571 F284 0572 F284 AD CA 03 LOADLB LDA INFO +BKFLAG ;Check protection bit 0573 F287 4A LSRA ;CS -> prot. CC -> unprot 0574 F288 68 PLA ;Check if loading and running 0575 F289 90 18 BCC LOADLA ;Not protected -> carry on Acorn macro assembler Page 126 C.F.S Main Routines - SAVE 0576 F28B F0 0C BEQ LOADLC ;Yes => carry on 0577 F28D 0578 F28D 20 E7 FA PROTER JSR CASMOF ;Turn motor off 0579 F290 ;Also called from RDBFER 0580 F290 0581 F290 00 BRK 0582 F291 D5 = CFSERL 0583 F292 4C 6F 63 = "Locked" 0584 F298 00 = &00 0585 F299 0586 F299 LOADLC 0587 F299 A9 03 LDAIM &03 0588 F29B 8D 58 02 STA CRIT ;Loading/running & prot., so disable ESCAPE and trap BREAK 0589 F29E D0 03 BNE LOADLA ;always branch 0590 F2A0 0591 F2A0 20 6A F6 LODRTR JSR SEARCH ;Search for current block (BLOKNO) 0592 F2A3 LOADLA 0593 F2A3 A9 30 LDAIM NIGBIT 0594 F2A5 25 BB AND USFLGS 0595 F2A7 F0 04 BEQ LOADL8 ;If ignore set, just read block 0596 F2A9 A5 C1 LDA HDRCRC ;Check hdr. checksum 0597 F2AB 0598 F2AB ;Don't start bg job if header CRC is no good, 0599 F2AB ;otherwise data may be loaded somewhere strange 0600 F2AB 0601 F2AB D0 0A BNE LOADL7 0602 F2AD 98 LOADL8 TYA 0603 F2AE 48 PHA ;Store "Loading" flag 0604 F2AF 20 AE FB JSR TWINIT ;Initialise tube for writing if nesc. 0605 F2B2 68 PLA 0606 F2B3 A8 TAY ;Restore "Loading" flag 0607 F2B4 20 05 F8 JSR RDBLOK 0608 F2B7 20 AA F9 LOADL7 JSR LODHDR ;Print header and error msgs. 0609 F2BA D0 E4 BNE LODRTR ;=> retry 0610 F2BC 0611 F2BC 20 5E FB JSR NXTBLK ;Next block := blk. found + 1 0612 F2BF 2C CA 03 BIT INFO +BKFLAG 0613 F2C2 30 08 BMI LOADEX ;Just loaded last block => finish 0614 F2C4 0615 F2C4 20 61 F9 JSR ADDBKA ;Add block size to BKADDR 0616 F2C7 0617 F2C7 20 B1 F7 JSR RDHEAD 0618 F2CA D0 D7 BNE LOADLA ;Always jump 0619 F2CC 0620 F2CC LOADEX 0621 F2CC [ LENSW =0 ;Alter OSFILE control block 0622 F2CC A0 0A LDYIM &0A ;Length offset in OSFILE block 0623 F2CE A5 CC LDA FSIZE ;File size set in PRTHDR 0624 F2D0 91 C8 STAIY GENPTR ;Note GENPTR kept from OSFILE 0625 F2D2 C8 INY 0626 F2D3 A5 CD LDA FSIZE + 1 0627 F2D5 91 C8 STAIY GENPTR 0628 F2D7 A9 00 LDAIM &00 ;Set high bytes of length = 0 0629 F2D9 C8 INY 0630 F2DA 91 C8 STAIY GENPTR 0631 F2DC C8 INY 0632 F2DD 91 C8 STAIY GENPTR 0633 F2DF ] 0634 F2DF 0635 F2DF 28 PLP ;Restore interrupt status 0636 F2E0 0637 F2E0 FINOP 0638 F2E0 0639 F2E0 20 DD FA JSR BEEPOF ;Motor OFF/BEEP 0640 F2E3 0641 F2E3 24 BA NOOLN1 BIT ERRSW ;If error taken place, already new line 0642 F2E5 30 07 BMI FINOPX 0643 F2E7 08 NOOLIN PHP 0644 F2E8 20 3B FA JSR MSGOUT 0645 F2EB 0D = MCR 0646 F2EC 00 = &00 ;Print new line if msgs on 0647 F2ED 28 PLP 0648 F2EE 60 FINOPX RTS 0649 F2EF 0650 F2EF 0651 F2EF 0652 F2EF ] 0653 F2EF 0654 F2EF 0655 F2EF TTL C.F.S. Main Routines - RUN 0656 F2EF OPT &01 0657 F2EF 0658 F2EF RUN 0659 F2EF 20 B7 F1 JSR GETFLN 0660 F2F2 [ MOS125 = &FF 0663 F2F2 | 0664 F2F2 ;initialise GENPTR as this is not an OSFILE load 0665 F2F2 A2 C2 LDXIM FSIZE - &0A ;note value assumed nonzero 0666 F2F4 86 C8 STX GENPTR ;so LOADEX overwrites FSIZE with itself 0667 F2F6 85 C9 STA GENPTR+1 ;A=0 from GETFLN 0668 F2F8 8E C2 03 STX INFO +BKEXEC ;=> >0 loads file to header addr 0669 F2FB ] 0670 F2FB 0671 F2FB ;Note, is assumed here that A = 0 from GETFLN 0672 F2FB ;since LOADGO tests A 0673 F2FB 0674 F2FB [ MOS125 = &7F 0675 F2FB [ STARGO = &00 0676 F2FB 84 E6 STY CLIRY ;use temp, stack is snooped by CompROMs during LOADGO 0677 F2FD 20 5E F2 JSR LOADGO ;Load file from tape 0678 F300 A4 E6 LDY CLIRY 0679 F302 RUNGO 0680 F302 98 TYA 0681 F303 20 6F E0 JSR CLIXY2 ;XY = tail ptr, A = Y on entry = offset 0682 F306 8E D0 02 STX TAILLO ;save pointer to command line tail 0683 F309 C8 INY ;permute so a page of OS ROM becomes zero 0684 F30A 8C D1 02 STY TAILHI ;marking all other addresses valid 0685 F30D A8 TAY ;set up registers to simulate entry from Acorn DFS 0686 F30E A2 FF LDXIM &FF ;from filename comparison 0687 F310 38 SEC 0688 F311 [ TUBESW=0 0689 F311 2C 7A 02 BIT TUBE 0690 F314 10 0A BPL NOTUB1 ;No tube - jump to IO proc. address 0691 F316 0692 F316 AD C4 03 LDA INFO +BKEXEC +&02 ;Check if execution address 0693 F319 2D C5 03 AND INFO +BKEXEC +&03 ;of file is accross tube 0694 F31C C9 FF CMPIM &FF 0695 F31E D0 05 BNE RUNL1 ;Yes, set up tube call 0696 F320 A9 01 NOTUB1 LDAIM &01 ;enter with A=1, X=&FF, Y=arg offset, C=1 0697 F322 6C C2 03 JMI INFO +BKEXEC ;No, just jump 0698 F325 Acorn macro assembler Page 127 C.F.S. Main Routines - RUN 0699 F325 A2 C2 RUNL1 LDXIM INFO +BKEXEC ;Point to exec. address 0700 F327 A0 03 LDYIM /(INFO +BKEXEC ) 0701 F329 A9 04 LDAIM TUBEX ;=> execute to tube 0702 F32B 4C BA FB JMP TBINT1 ;Claim tube and jump to address 0703 F32E | 0706 F32E ] 0707 F32E | 0729 F32E ] 0730 F32E | 0752 F32E ] 0753 F32E 0754 F32E 0755 F32E TTL C.F.S Main Routines - CAT 0756 F32E OPT &01 0757 F32E 0758 F32E 0759 F32E ;********* 0760 F32E ;* C A T * 0761 F32E ;********* 0762 F32E 0763 F32E 0764 F32E 0765 F32E CAT 0766 F32E 0767 F32E ;Entered from MOS with two args 0768 F32E ;in X and Y as per OPT. These are not used. 0769 F32E 0770 F32E A9 08 LDAIM CATBIT 0771 F330 20 47 F3 JSR ORSTAT 0772 F333 20 1C FB JSR SETDEF ;Set message type etc. 0773 F336 A9 00 LDAIM &00 ;Indicate verify only 0774 F338 20 4B F3 JSR LOOK ;In CFS, will never return 0775 F33B ;In SFS, will return 0776 F33B 20 F1 FA JSR RELEAS ;So in SFS release RS423 0777 F33E ;NOTE - only release call outside CASMOF 0778 F33E 0779 F33E 0780 F33E A9 F7 CATOFF LDAIM NCTBIT 0781 F340 0782 F340 25 E2 ANDSTA AND CFSTAT 0783 F342 85 E2 ANDSTB STA CFSTAT 0784 F344 0785 F344 [ MOS125 = &FF 0787 F344 ] 0788 F344 60 RTS 0789 F345 0790 F345 ORLST 0791 F345 A9 40 LDAIM LSTBYT 0792 F347 ; 0793 F347 05 E2 ORSTAT ORA CFSTAT 0794 F349 D0 F7 BNE ANDSTB ;Assumed always non-zero 0795 F34B 0796 F34B 0797 F34B 0798 F34B 0799 F34B 0800 F34B 48 LOOK PHA 0801 F34C AD 47 02 LDA SROMSW 0802 F34F F0 08 BEQ LOOKLR ;No SFS -> don't call SFS routines 0803 F351 0804 F351 20 4A EE JSR SRINIT ;Initialise SERROM ptr. 0805 F354 [ MOS125 = &FF 0807 F354 ] 0808 F354 90 03 BCC LOOKLR 0809 F356 0810 F356 B8 CLV ;Indicate end of rom to outside world 0811 F357 50 5B BVC LOOKEX 0812 F359 0813 F359 20 B1 F7 LOOKLR JSR RDHEAD 0814 F35C AD C6 03 LDA INFO +BKNOLO 0815 F35F 85 B4 STA BLOKNO 0816 F361 AD C7 03 LDA INFO +BKNOHI 0817 F364 85 B5 STA BLOKNO +&01 0818 F366 A2 FF LDXIM &FF 0819 F368 8E DF 03 STX OLDFLG 0820 F36B E8 INX 0821 F36C 86 BA STX ERRSW 0822 F36E F0 20 BEQ LOOKL5 ;Always new line 0823 F370 0824 F370 [ MOS125 = &FF 0825 F370 | 0826 F370 50 05 LOOKL4 BVC LOOKL3 ;Header interrupted 0827 F372 A9 FF LDAIM &FF 0828 F374 20 07 F8 JSR CHKBIN ;Check data 0829 F377 0830 F377 A2 00 LOOKL3 LDXIM &00 0831 F379 20 CF F9 JSR CATERR ;Print errors and header 0832 F37C 0833 F37C AD 47 02 LDA SROMSW 0834 F37F F0 04 BEQ LOOKL9 ;In CFS -> continue 0835 F381 24 BB BIT USFLGS 0836 F383 50 36 BVC LOOKL8 ;=> short msgs and skip beween files 0837 F385 0838 F385 2C CA 03 LOOKL9 BIT INFO +BKFLAG 0839 F388 30 34 BMI LOOKLA ;Look for block zero 0840 F38A ] 0841 F38A 0842 F38A 20 5E FB LOOKL1 JSR NXTBLK ;Blokno := INFO +BKNO + 1 0843 F38D 0844 F38D 20 B1 F7 JSR RDHEAD ;Read header 0845 F390 AD 47 02 LOOKL5 LDA SROMSW 0846 F393 F0 02 BEQ LOOKL7 0847 F395 0848 F395 ;Check V from RDHEAD 0849 F395 0850 F395 50 1D BVC LOOKEX ;In SFS and VC => end of all ROMs 0851 F397 0852 F397 68 LOOKL7 PLA 0853 F398 48 PHA ;Check if just verifying 0854 F399 F0 D5 BEQ LOOKL4 ;If just verifying, continue 0855 F39B 20 67 FA JSR CMPFT ;Otherwise, check file titles 0856 F39E D0 16 BNE LOOKL2 ;Not the same, continue 0857 F3A0 A9 30 LDAIM NIGBIT 0858 F3A2 25 BB AND USFLGS 0859 F3A4 F0 0E BEQ LOOKEX ;If ignore set, just exit 0860 F3A6 0861 F3A6 AD C6 03 LDA INFO +BKNOLO ;Otherwise, check block no. 0862 F3A9 C5 B6 CMP SRCHBK 0863 F3AB D0 09 BNE LOOKL2 ;Not found ... 0864 F3AD AD C7 03 LDA INFO +BKNOHI 0865 F3B0 C5 B7 CMP SRCHBK +&01 Acorn macro assembler Page 128 C.F.S Main Routines - CAT 0866 F3B2 D0 02 BNE LOOKL2 0867 F3B4 68 LOOKEX PLA 0868 F3B5 0869 F3B5 ;On exit, V indicates in CFS if header 0870 F3B5 ;interrupted by DCD. In SFS, indicates 0871 F3B5 ;if end of ROM filing system reached. 0872 F3B5 0873 F3B5 60 RTS 0874 F3B6 0875 F3B6 LOOKL2 0876 F3B6 0877 F3B6 ;Here, file not recognised. In CFS, just 0878 F3B6 ;carry on reading next block. In SFS, 0879 F3B6 ;skip to block zero of next file. 0880 F3B6 0881 F3B6 AD 47 02 LDA SROMSW 0882 F3B9 F0 B5 BEQ LOOKL4 ;In CFS, carry on 0883 F3BB 20 E7 EE LOOKL8 JSR SRSKIP ;Not recognised => skip 0884 F3BE A9 FF LOOKLA LDAIM &FF 0885 F3C0 8D C6 03 STA INFO +BKNOLO ;Look for block zero of next file 0886 F3C3 8D C7 03 STA INFO +BKNOHI 0887 F3C6 D0 C2 BNE LOOKL1 0888 F3C8 0889 F3C8 [ MOS125 = &FF 0905 F3C8 ] 0906 F3C8 0907 F3C8 0908 F3C8 TTL C.F.S Main Routines - FIND 0909 F3C8 OPT &01 0910 F3C8 0911 F3C8 ;****** SEQUENTIAL ACCESS ****** 0912 F3C8 0913 F3C8 0914 F3C8 0915 F3C8 ;*********** 0916 F3C8 ;* F I N D * 0917 F3C8 ;*********** 0918 F3C8 0919 F3C8 0920 F3C8 FIND ;FIND 0921 F3C8 0922 F3C8 0923 F3C8 ;Entered from OSFIND: 0924 F3C8 0925 F3C8 ;A NZ => open 0926 F3C8 ;b6 => file already exists and opened for read/ud 0927 F3C8 ;A EQ => shut 0928 F3C8 0929 F3C8 ;For open: X,Y -> file name lo,hi 0930 F3C8 0931 F3C8 ;For shut: Y = handle. If zero, all files shut. 0932 F3C8 0933 F3C8 0934 F3C8 0935 F3C8 85 BC STA TEMP 0936 F3CA 8A TXA 0937 F3CB 48 PHA 0938 F3CC 98 TYA 0939 F3CD 48 PHA 0940 F3CE A5 BC LDA TEMP 0941 F3D0 D0 1E BNE FINDON 0942 F3D2 0943 F3D2 98 TYA 0944 F3D3 D0 0C BNE SHUTL1 ;Y non-zero => shut one file 0945 F3D5 ; 0946 F3D5 20 F3 E2 JSR SHUTES ;shut EXEC and SPOOL files opened by CFS 0947 F3D8 20 76 F4 JSR SHUTW ;Else shut write file 0948 F3DB ; Shut read file and exit 0949 F3DB 46 E2 SHUTR LSR CFSTAT 0950 F3DD 06 E2 ASL CFSTAT ;Note assumes input bit = b0 0951 F3DF ; C=0 0952 F3DF 90 0C BCC JFINDEX ;[ALWAYS jump] 0953 F3E1 ; 0954 F3E1 ; 0955 F3E1 4A SHUTL1 LSRA 0956 F3E2 B0 F7 BCS SHUTR ;Shut input file 0957 F3E4 4A LSRA 0958 F3E5 B0 03 BCS SHUTL2 ;Shut output file 0959 F3E7 0960 F3E7 4C A4 FB JMP HNDERR ;Invalid handle 0961 F3EA 0962 F3EA 20 76 F4 SHUTL2 JSR SHUTW 0963 F3ED JFINDEX 0964 F3ED 4C 6F F4 JMP FINDEX 0965 F3F0 0966 F3F0 0967 F3F0 0968 F3F0 20 B7 F1 FINDON JSR MOVFT 0969 F3F3 0970 F3F3 24 BC BIT TEMP 0971 F3F5 50 3D BVC FINDO ;Find for output if b.6 = 0 0972 F3F7 0973 F3F7 ;Opening files already open 0974 F3F7 ;is the same as if not already open 0975 F3F7 0976 F3F7 0977 F3F7 ;Open for reading 0978 F3F7 ;Set handle and read in first buffer 0979 F3F7 0980 F3F7 A9 00 LDAIM &00 0981 F3F9 8D 9E 03 STA INPTR ;Set buffer ptr. := 0 0982 F3FC 8D DD 03 STA NEXTIN 0983 F3FF 8D DE 03 STA NEXTIN +&01 ;Set expected block := 0 0984 F402 0985 F402 A9 3E LDAIM NECBIT ;End of file/last byte unset/input file closed 0986 F404 20 40 F3 JSR ANDSTA 0987 F407 0988 F407 20 0F FB JSR SETSDF ;Set seq. access default 0989 F40A 0990 F40A 08 PHP ;Store interrupt status 0991 F40B 20 64 F6 JSR SRCH0 ;Find file, first block. 0992 F40E 20 EC F6 JSR RDBFRS ;Check hdr. read ok, and get first bfr. 0993 F411 28 PLP ;Restore interrupt status 0994 F412 0995 F412 A2 FF LDXIM &FF 0996 F414 E8 FINDL5 INX ;Make file name found = file name 0997 F415 BD B2 03 LDAAX INFO ;for subsequent block reads 0998 F418 9D A7 03 STAAX INFILE ;so that OPENIN "" locks onto one filet block. 0999 F41B D0 F7 BNE FINDL5 1000 F41D 1001 F41D A9 01 LDAIM INOPEN Acorn macro assembler Page 129 C.F.S Main Routines - FIND 1002 F41F 20 47 F3 JSR ORSTAT 1003 F422 AD EA 02 LDA INBSZE 1004 F425 0D EB 02 ORA INBSZE +&01 1005 F428 D0 03 BNE FINDL6 ;If non-empty, don't worry 1006 F42A 20 45 F3 JSR ORLST ;Otherwise, at end of file 1007 F42D 1008 F42D A9 01 FINDL6 LDAIM INHAND 1009 F42F 0D 47 02 ORA SROMSW ;If in SFS, return 3 1010 F432 D0 39 BNE OPENEX ;Return input handle 1011 F434 1012 F434 1013 F434 1014 F434 8A FINDO TXA ;Can't openout "" 1015 F435 D0 03 BNE FINABC 1016 F437 4C A2 EA JMP BADSTR 1017 F43A 1018 F43A A2 FF FINABC LDXIM &FF 1019 F43C E8 FINDL2 INX 1020 F43D BD D2 03 LDAAX FILNAM ;Store output file name 1021 F440 9D 80 03 STAAX OUTHDR 1022 F443 D0 F7 BNE FINDL2 1023 F445 1024 F445 A9 FF LDAIM &FF 1025 F447 A2 08 LDXIM &08 1026 F449 9D 8B 03 FINDL4 STAAX OUTHDR +BKLOAD -&01 1027 F44C CA DEX 1028 F44D D0 FA BNE FINDL4 ;Set load/EXEC address to default value 1029 F44F 1030 F44F 8A TXA 1031 F450 A2 14 LDXIM BKNOLO 1032 F452 1033 F452 ;Set block no./block len./last bk. =0 1034 F452 ;Note also sets OUTPTR which must 1035 F452 ;be contiguous with OUTHDR 1036 F452 1037 F452 9D 80 03 FINDL3 STAAX OUTHDR 1038 F455 E8 INX 1039 F456 E0 1E CPXIM BKLAST +&01 1040 F458 D0 F8 BNE FINDL3 ;Note carry set 1041 F45A 2E 97 03 ROL OUTHDR +BKSZEH ;Set hi byte of size 1042 F45D 1043 F45D 20 1C FB JSR SETDEF ;If default, print prompt 1044 F460 20 5F F5 JSR RECORD 1045 F463 20 E7 FA JSR CASMOF ;OFF for putbyte call 1046 F466 1047 F466 A9 02 LDAIM OUTOPN 1048 F468 20 47 F3 JSR ORSTAT ;Indicate file open for output 1049 F46B 1050 F46B A9 02 LDAIM OUTHND 1051 F46D 1052 F46D 85 BC OPENEX STA TEMP 1053 F46F FINDEX ;Common exit for PUT/GETBYTE and FIND 1054 F46F 68 GBEXX PLA 1055 F470 A8 TAY 1056 F471 68 PLA 1057 F472 AA TAX 1058 F473 A5 BC LDA TEMP 1059 F475 FINDXX 1060 F475 60 RTS 1061 F476 1062 F476 1063 F476 1064 F476 1065 F476 1066 F476 1067 F476 SHUTW 1068 F476 1069 F476 A9 02 LDAIM OUTHND 1070 F478 25 E2 AND CFSTAT 1071 F47A F0 F9 BEQ FINDXX ;If already shut, dont bother 1072 F47C 1073 F47C A9 00 LDAIM &00 1074 F47E 8D 97 03 STA OUTHDR +BKSZEH 1075 F481 1076 F481 A9 80 LDAIM LASTBK 1077 F483 AE 9D 03 LDX OUTPTR 1078 F486 8E 96 03 STX OUTHDR +BKSZEL 1079 F489 8D 98 03 STA OUTHDR +BKFLAG 1080 F48C 20 94 F4 JSR WRTBFR ;Write out block 1081 F48F A9 FD LDAIM NOUTHD 1082 F491 4C 40 F3 JMP ANDSTA ;Mark file as closed 1083 F494 1084 F494 1085 F494 WRTBFR ;Write out buffer 1086 F494 1087 F494 20 0F FB JSR SETSDF ;Set sequential defaults 1088 F497 1089 F497 A2 11 LDXIM BKLAST -BKLOAD 1090 F499 BD 8C 03 WRTBL3 LDAAX OUTHDR +BKLOAD 1091 F49C 9D BE 03 STAAX INFO +BKLOAD 1092 F49F CA DEX 1093 F4A0 10 F7 BPL WRTBL3 1094 F4A2 1095 F4A2 ; Set buffer address for WBLOCK call 1096 F4A2 1097 F4A2 86 B2 STX BKADDR +&02 1098 F4A4 86 B3 STX BKADDR +&03 ;Output buffer is in IO proc. 1099 F4A6 1100 F4A6 0000 T * OUTBFR:SHL: 8 1101 F4A6 [ T=0 1102 F4A6 E8 INX 1103 F4A7 86 B0 STX BKADDR ;If OUTBFR on page boundary, set lo byte = 0 1104 F4A9 | 1107 F4A9 ] 1108 F4A9 1109 F4A9 A9 09 LDAIM /(OUTBFR ) 1110 F4AB 85 B1 STA BKADDR +&01 1111 F4AD 1112 F4AD A2 7F LDXIM OUTHDR -&01 1113 F4AF 20 78 FB JSR MOVFN ;File name -> FILNAM etc. 1114 F4B2 8D DF 03 STA OLDFLG 1115 F4B5 1116 F4B5 20 85 FB JSR MOTONW ;Motor on and select output drive 1117 F4B8 20 D5 FB JSR BUGFIX 1118 F4BB 20 1C F8 JSR WBLOCK ;Write out block 1119 F4BE EE 94 03 INC OUTHDR +BKNOLO ;Next block 1120 F4C1 D0 03 BNE WRTBL4 1121 F4C3 EE 95 03 INC OUTHDR +BKNOHI 1122 F4C6 60 WRTBL4 RTS 1123 F4C7 1124 F4C7 Acorn macro assembler Page 130 C.F.S Main Routines - FIND 1125 F4C7 1126 F4C7 1127 F4C7 1128 F4C7 1129 F4C7 1130 F4C7 1131 F4C7 TTL C.F.S. Main Routines - GETBYTE 1132 F4C7 OPT &01 1133 F4C7 1134 F4C7 1135 F4C7 ;****************** 1136 F4C7 ;* G E T B Y T E * 1137 F4C7 ;****************** 1138 F4C7 1139 F4C7 1140 F4C7 GETBYT 1141 F4C7 1142 F4C7 8A TXA 1143 F4C8 48 PHA 1144 F4C9 98 TYA 1145 F4CA 48 PHA 1146 F4CB A9 01 LDAIM INHAND 1147 F4CD 20 93 FB JSR CHKHND ;Is handle open ? 1148 F4D0 1149 F4D0 A5 E2 LDA CFSTAT 1150 F4D2 0A ASLA 1151 F4D3 B0 4F BCS GBEOF ;=> Going past end of file 1152 F4D5 0A ASLA 1153 F4D6 90 09 BCC GBLF ;=> Not getting last byte 1154 F4D8 1155 F4D8 ;Here indicate next GB call 1156 F4D8 ;goes off end of file 1157 F4D8 1158 F4D8 A9 80 LDAIM EOFBIT 1159 F4DA 20 47 F3 JSR ORSTAT 1160 F4DD 1161 F4DD ;Carry still set from above 1162 F4DD 1163 F4DD A9 FE LDAIM ENDBYT ;Byte after end of file 1164 F4DF B0 38 BCS GBEXY 1165 F4E1 1166 F4E1 AE 9E 03 GBLF LDX INPTR 1167 F4E4 E8 INX 1168 F4E5 EC EA 02 CPX INBSZE ;Is last byte of buffer ? 1169 F4E8 D0 2A BNE GBLDE ;Nope -> continue 1170 F4EA 1171 F4EA 1172 F4EA 2C EC 02 BIT BUFFLG ;Check if in last block. If so, are reading 1173 F4ED 30 22 BMI GBLH ;last byte of last block => exit 1174 F4EF 1175 F4EF ;Read last byte of block. NOTE this is kept in a location 1176 F4EF ;separate from the rest of the block buffer, so that if the 1177 F4EF ;next block being read aborts and corrupts the block buffer, 1178 F4EF ;a subsequent retry will still provide the last byte of the 1179 F4EF ;previous block. The variable FINBYT is updated in RDBFER after 1180 F4EF ;the background block read has succesfully completed. 1181 F4EF 1182 F4EF AD ED 02 LDA FINBYT 1183 F4F2 48 PHA ;Store final byte of this block 1184 F4F3 20 0F FB JSR SETSDF ;Set sequential defaults 1185 F4F6 08 PHP ;Store I'rupt status 1186 F4F7 20 E4 F6 JSR RDBFER ;Read buffer for next GETBYTE call 1187 F4FA 28 PLP ;Restore I'rupt status 1188 F4FB 68 PLA ;Restore final byte of previous buffer 1189 F4FC 85 BC STA TEMP ;Store for later use 1190 F4FE 1191 F4FE 18 CLC ;Prepare for non-end of file exit 1192 F4FF 2C EC 02 BIT BUFFLG 1193 F502 10 17 BPL GBEXIT ;Exit, result = TEMP, carry clear 1194 F504 1195 F504 AD EA 02 LDA INBSZE ;If here, is last block 1196 F507 0D EB 02 ORA INBSZE +&01 1197 F50A D0 0F BNE GBEXIT ;Last block, is not empty 1198 F50C 20 45 F3 JSR ORLST ;If is last block, and empty 1199 F50F D0 0A BNE GBEXIT ;then this is the last byte 1200 F511 ;So set last byte bit and exit, C = 0 1201 F511 1202 F511 GBLH 1203 F511 20 45 F3 JSR ORLST ;Otherwise, reading last byte. 1204 F514 1205 F514 ;So exit, carry clear 1206 F514 1207 F514 CA GBLDE DEX 1208 F515 18 CLC ;Carry clear unless byte AFTER last byte of file 1209 F516 BD 00 0A LDAAX INBUFR ;GET BYTE ! 1210 F519 85 BC GBEXY STA TEMP 1211 F51B EE 9E 03 GBEXIT INC INPTR ;Inc. buffer ptr. for next time 1212 F51E 4C 6F F4 JMP GBEXX ;Share exit with PUTBYT 1213 F521 1214 F521 [ MOS125 = &FF 1215 F521 | 1216 F521 COPYR ;here to save a byte 1217 F521 29 = ")" 1218 F522 43 = "C" 1219 F523 28 = "(" ;BRK forms terminator 1220 F524 ] 1221 F524 1222 F524 00 GBEOF BRK 1223 F525 DF = CFSERD 1224 F526 45 = "E" 1225 F527 4F = "O" 1226 F528 46 = "F" 1227 F529 00 = &00 1228 F52A 1229 F52A TTL C.F.S. Main Routines - PUTBYTE 1230 F52A OPT &01 1231 F52A 1232 F52A 1233 F52A ;****************** 1234 F52A ;* P U T B Y T E * 1235 F52A ;****************** 1236 F52A 1237 F52A 1238 F52A [ MOS125 = &FF 1269 F52A | 1270 F52A PUTBYT 1271 F52A 1272 F52A ;Note, IADDR not used in this 1273 F52A ;function coz RX interrupts are "disabled" 1274 F52A ;by TXFLAG (see IRUPT) 1275 F52A Acorn macro assembler Page 131 C.F.S. Main Routines - PUTBYTE 1276 F52A 85 BC STA TEMP 1277 F52C 8A TXA 1278 F52D 48 PHA 1279 F52E 98 TYA 1280 F52F 48 PHA 1281 F530 A9 02 LDAIM OUTHND 1282 F532 20 93 FB JSR CHKHND ;Check handle open 1283 F535 1284 F535 A5 BC LDA TEMP 1285 F537 AE 9D 03 LDX OUTPTR 1286 F53A 9D 00 09 STAAX OUTBFR 1287 F53D E8 INX 1288 F53E D0 06 BNE PBEXIT ;Test if last byte of buffer 1289 F540 20 94 F4 JSR WRTBFR ;Buffer full, write out. 1290 F543 20 E7 FA JSR CASMOF 1291 F546 1292 F546 EE 9D 03 PBEXIT INC OUTPTR 1293 F549 1294 F549 ;Increment pointer after writing block out so that 1295 F549 ;user can retry if block is interrupted 1296 F549 ;by ESCAPE. 1297 F549 1298 F549 4C 6F F4 JMP GBEXX ;restores A from TEMP 1299 F54C ;and now IADDR is not used at all. 1300 F54C ] 1301 F54C 1302 F54C 1303 F54C 1304 F54C 1305 F54C LNK MOS74 0001 F54C 0002 F54C ;File - MOS74 0003 F54C 0004 F54C TTL C.F.S Main Routines - OPT 0005 F54C OPT &01 0006 F54C 0007 F54C [ MOS125 = &FF 0037 F54C | 0038 F54C HELP ;*HELP command 0039 F54C A2 09 LDXIM SVHELP 0040 F54E 20 6F F1 JSR SVOP ;Y = offset within line of arguments 0041 F551 ; 0042 F551 ; Y preserved, therefore Y>=2 on return 0043 F551 ; 0044 F551 ;STROUT uses FTPTR, clobbered during OSASCI->OSBPUT 0045 F551 A9 0D LDAIM MCR ;start by printing CR 0046 F553 A8 TAY ;initialise offset 0047 F554 20 E3 FF HELOP JSR OSASCI 0048 F557 C8 INY 0049 F558 B9 A2 EA LDAAY PVER +&01 -MCR 0050 F55B D0 F7 BNE HELOP 0051 F55D F0 30 BEQ HELOO 0052 F55F 0053 F55F RECORD 0054 F55F 0055 F55F AD 47 02 LDA SROMSW 0056 F562 D0 2E BNE OPTERR ;OK if not in SFS 0057 F564 20 85 FB JSR MOTONW ;Motor ON for OUTPUT 0058 F567 20 D5 FB JSR BUGFIX 0059 F56A 20 59 EA JSR MSGON 0060 F56D F0 45 BEQ RECEXX 0061 F56F 0062 F56F 20 3B FA JSR MSGOUT ;If messages ON, prompt 0063 F572 52 45 43 = "RECORD then RETURN" 0064 F584 00 = &00 0065 F585 0066 F585 20 8B F9 GETCR1 JSR ESCAPE 0067 F588 20 E0 FF JSR OSRDCH 0068 F58B C9 0D CMPIM MCR 0069 F58D D0 F6 BNE GETCR1 0070 F58F 4C E7 FF HELOO JMP OSNEWL 0071 F592 0072 F592 0073 F592 4C 77 E3 OPTERR JMP MBDCMD 0074 F595 0075 F595 ;Entered with two args in X & Y decoded from 0076 F595 ;command line by MOS. 0077 F595 0078 F595 E0 03 CFSOPT CPXIM &03 0079 F597 F0 1C BEQ SETGAP 0080 F599 B0 F7 BCS OPTERR 0081 F59B A9 A1 LDAIM DEFLT 0082 F59D C0 03 CPYIM &03 0083 F59F CA DEX 0084 F5A0 30 10 BMI SETFL1 0085 F5A2 B0 EE BCS OPTERR 0086 F5A4 F0 05 BEQ MSGS 0087 F5A6 ERRS 0088 F5A6 C8 INY 0089 F5A7 C8 INY 0090 F5A8 C8 INY 0091 F5A9 49 FF EORIM MSGMSK:EOR:ERRMSK ;Mask out error and default bits 0092 F5AB 49 92 MSGS EORIM DEFLT:EOR:MSGMSK 0093 F5AD XSETFLG 0094 F5AD 25 E3 AND OPTS 0095 F5AF 19 B7 F6 ORAAY OPTTAB 0096 F5B2 SETFL1 0097 F5B2 85 E3 STA OPTS 0098 F5B4 RECEXX 0099 F5B4 60 RTS 0100 F5B5 ] 0101 F5B5 0102 F5B5 98 SETGAP TYA 0103 F5B6 30 02 BMI SETGP2 ; >127 => default 0104 F5B8 D0 02 BNE SETGP1 ; 0 < gap < 128 => OK 0105 F5BA A9 19 SETGP2 LDAIM DEFGAP 0106 F5BC 8D D1 03 SETGP1 STA SEQGAP 0107 F5BF 60 RTS 0108 F5C0 0109 F5C0 [ MOS125 = &FF 0120 F5C0 ] 0121 F5C0 0122 F5C0 TTL Main Routines - Interrupt routine 0123 F5C0 OPT &01 0124 F5C0 0125 F5C0 IRUPT 0126 F5C0 0127 F5C0 C6 C0 DEC IFLAG 0128 F5C2 AD 47 02 LDA SROMSW ;Is SFS active ? 0129 F5C5 F0 06 BEQ NOTSPK ;Nope 0130 F5C7 ;GoMMC tape patch has F58D NOP;NOP Acorn macro assembler Page 132 Main Routines - Interrupt routine 0131 F5C7 0132 F5C7 20 8B EE JSR RDSPCH ;Yes, get next byte from ROM 0133 F5CA [ MOS125 = &FF 0135 F5CA ] 0136 F5CA 18 CLC ;Clear carry => no DCD 0137 F5CB 90 1A BCC DOIRPT ;Do as per cassette irupt 0138 F5CD 0139 F5CD AD 08 FE NOTSPK LDA STATUS 0140 F5D0 48 PHA 0141 F5D1 29 02 ANDIM TXBIT 0142 F5D3 F0 0B BEQ ITXON ;No TX interrupt 0143 F5D5 A4 CA LDY TXFLAG 0144 F5D7 F0 07 BEQ ITXON ;0 => receiving 0145 F5D9 0146 F5D9 ;Here, transmiting byte .... 0147 F5D9 0148 F5D9 68 PLA ;Restore stack 0149 F5DA A5 BD LDA IBUF 0150 F5DC 8D 09 FE STA PORT 0151 F5DF 60 RTS 0152 F5E0 0153 F5E0 0154 F5E0 ITXON 0155 F5E0 0156 F5E0 ;If receiving byte, check IFLAG to see 0157 F5E0 ;where to put it. 0158 F5E0 0159 F5E0 AC 09 FE LDY PORT ;Cancel interrupt 0160 F5E3 68 PLA ;Pull status 0161 F5E4 4A LSRA 0162 F5E5 4A LSRA 0163 F5E6 4A LSRA ;C = 1 => DCD; C = 0 => no DCD 0164 F5E7 A6 C2 DOIRPT LDX ITYPE 0165 F5E9 F0 65 BEQ IEX ;0 => no task pending 0166 F5EB 0167 F5EB 0168 F5EB CA DEX 0169 F5EC D0 06 BNE FNDHDR ;X <> 1 => not DCD task 0170 F5EE 90 60 BCC IEX ;=> DCD Not yet found 0171 F5F0 A0 02 LDYIM &02 0172 F5F2 D0 5A BNE NEWINT ;Go on to look find hdr. 0173 F5F4 0174 F5F4 CA FNDHDR DEX 0175 F5F5 D0 13 BNE RDCHAR ;X <> 2 => not header task 0176 F5F7 B0 57 BCS IEX ;Ignore DCD if present 0177 F5F9 98 TYA ;Get stuff from port 0178 F5FA 20 6D FB JSR SETJOB ;Set CHKSUM etc. 0179 F5FD A0 03 LDYIM &03 ;New task 0180 F5FF 0181 F5FF [ GLYN=0 0185 F5FF ] 0186 F5FF 0187 F5FF C9 2A CMPIM "*" 0188 F601 F0 4B BEQ NEWINT ;Set read chars 0189 F603 20 45 FB JSR RXINIT ;Reset ULA (should be BLIP) 0190 F606 A0 01 LDYIM &01 0191 F608 D0 44 BNE NEWINT ;Otherwise, wait for DCD 0192 F60A 0193 F60A CA RDCHAR DEX 0194 F60B D0 0A BNE RDBLK ;X <> 3 => not RDCHAR task 0195 F60D B0 03 BCS GOTDCD ;DCD found, not char 0196 F60F 84 BD STY IBUF ;Store char read 0197 F611 [ MOS125 = &FF 0199 F611 | 0200 F611 60 RTS 0201 F612 ] 0202 F612 A9 80 GOTDCD LDAIM &80 0203 F614 85 C0 STA IFLAG ;Indicate DCD 0204 F616 [ MOS125 = &FF 0206 F616 | 0207 F616 60 RTS 0208 F617 ] 0209 F617 0210 F617 CA RDBLK DEX ;X <> 4=> not RDBLK 0211 F618 D0 27 BNE SUMIN 0212 F61A B0 2D BCS IFIN ;If DCD, finish immediately 0213 F61C 98 TYA 0214 F61D 20 E6 F7 JSR ADDCRC 0215 F620 A4 BC LDY TEMP ;(pointer) 0216 F622 E6 BC INC TEMP 0217 F624 24 BD BIT IBUF 0218 F626 30 0D BMI RDBLKA ;=> just verify, don't store 0219 F628 0220 F628 [ TUBESW=0 0221 F628 20 C6 FB JSR TUBCHK ;Check tube present and top bytes of address 0222 F62B F0 05 BEQ RDBLKB ;No need to tube. (NOTE TUBCHK DOES TAX to preserve A) 0223 F62D 0224 F62D 8E E5 FE STX TREG3 ;Otherwise, push to tube R3 0225 F630 D0 03 BNE RDBLKA ;And continue 0226 F632 0227 F632 8A RDBLKB TXA 0228 F633 91 B0 STAIY BKADDR ;Store in IO proc. 0229 F635 | 0231 F635 ] 0232 F635 0233 F635 C8 RDBLKA INY 0234 F636 CC C8 03 CPY INFO +BKSZEL ;** 1 BYTE SIZE ONLY ** 0235 F639 D0 15 BNE IEX ;Keep going 0236 F63B 0237 F63B ;Have here finished reading data, so 0238 F63B ;read two more bytes of CRC without storing 0239 F63B 0240 F63B [ MOS125 = &FF 0244 F63B | 0245 F63B A0 05 LDYIM &05 ;NB bit 1 <> bit 0 0246 F63D 84 BC STY TEMP ;Set counter 0247 F63F ] 0248 F63F D0 0D BNE NEWINT 0249 F641 0250 F641 0251 F641 SUMIN 0252 F641 0253 F641 ;Here, assumed X = 5 0254 F641 0255 F641 98 TYA 0256 F642 20 E6 F7 JSR ADDCRC 0257 F645 [ MOS125 = &FF 0260 F645 | 0261 F645 46 BC LSR TEMP ;NB alters returned C 0262 F647 B0 07 BCS IEX ;One more to go 0263 F649 ] Acorn macro assembler Page 133 Main Routines - Interrupt routine 0264 F649 0265 F649 ;If here, finished, so mark BG job finished 0266 F649 0267 F649 20 3B FB IFIN JSR CRESET 0268 F64C A0 00 LDYIM &00 0269 F64E 84 C2 NEWINT STY ITYPE 0270 F650 60 IEX RTS 0271 F651 0272 F651 TTL C.F.S. Main routines - EOF 0273 F651 OPT MOS74 Acorn macro assembler Page 134 C.F.S. Main routines - EOF 0274 F651 0275 F651 48 CFSEOF PHA ;First store Y and A 0276 F652 98 TYA 0277 F653 48 PHA 0278 F654 8A TXA ;Transfer handle to Y 0279 F655 A8 TAY ;for checking. 0280 F656 A9 03 LDAIM HNDS ;Both handles 0281 F658 20 93 FB JSR CHKHND ;NOTE - CORRUPTS Y 0282 F65B 0283 F65B A5 E2 LDA CFSTAT 0284 F65D 29 40 ANDIM LSTBYT 0285 F65F AA TAX ;Result (zero or non-zero) in X 0286 F660 68 PLA 0287 F661 A8 TAY 0288 F662 68 PLA ;Restore A and Y 0289 F663 60 RTS 0290 F664 0291 F664 TTL C.F.S. UTILITIES - MOS74 0292 F664 OPT &01 0293 F664 0294 F664 ;****** CASSETTE UTILITIES ****** 0295 F664 0296 F664 0297 F664 A9 00 SRCH0 LDAIM &00 0298 F666 85 B4 STA BLOKNO 0299 F668 85 B5 STA BLOKNO +&01 0300 F66A 0301 F66A SEARCH 0302 F66A 0303 F66A 0304 F66A ;File title pointed to by FTPTR. 0305 F66A ;Block number in BLOKNO. 0306 F66A 0307 F66A ;Tool through tape until found. If messages 0308 F66A ;on, print header info and checksum messages. 0309 F66A 0310 F66A A5 B4 LDA BLOKNO 0311 F66C 48 PHA 0312 F66D 85 B6 STA SRCHBK 0313 F66F A5 B5 LDA BLOKNO +&01 0314 F671 48 PHA 0315 F672 85 B7 STA SRCHBK +&01 ;Set block to search for 0316 F674 20 3B FA JSR MSGOUT 0317 F677 53 65 61 = "Searching",MCR,&00 0318 F682 A9 FF LDAIM &FF ;=> search and validate 0319 F684 20 4B F3 JSR LOOK 0320 F687 68 PLA 0321 F688 85 B5 STA BLOKNO +&01 0322 F68A 68 PLA 0323 F68B 85 B4 STA BLOKNO 0324 F68D A5 B6 LDA SRCHBK 0325 F68F 05 B7 ORA SRCHBK+&01 0326 F691 D0 0D BNE SRCHXX 0327 F693 0328 F693 ;If finding first block, set next expected 0329 F693 ;block to zero so that a load will not 0330 F693 ;fail because of a new file breaking into 0331 F693 ;a previous one thus causing non-sequential 0332 F693 ;blocks and therefore a block? error. 0333 F693 0334 F693 85 B4 STA BLOKNO ;If first block, no block error 0335 F695 85 B5 STA BLOKNO +&01 0336 F697 0337 F697 ;Check header CRC so that we only latch 0338 F697 ;onto non-corrupt file names 0339 F697 0340 F697 A5 C1 LDA HDRCRC 0341 F699 D0 05 BNE SRCHXX 0342 F69B A2 B1 LDXIM INFO -&01 ;Make sure looking for 0343 F69D 20 78 FB JSR MOVFN ;file name found in subsequent blocks 0344 F6A0 SRCHXX ;Check if run off the end of SROM system 0345 F6A0 0346 F6A0 AD 47 02 LDA SROMSW 0347 F6A3 F0 18 BEQ SRCHYY ;In CFS, carry on 0348 F6A5 70 16 BVS SRCHYY ;Not end of ROM => continue 0349 F6A7 FNF 0350 F6A7 00 BRK 0351 F6A8 D6 = SFSER1 0352 F6A9 [ MOS125 = &FF 0354 F6A9 | 0355 F6A9 46 69 6C = "File not found" 0356 F6B7 OPTTAB 0357 F6B7 00 = &00 ;Messages off 0358 F6B8 88 = MSGS1 ;Short messages 0359 F6B9 CC = MSGS2 ;Long messages 0360 F6BA 00 = IGBIT 0361 F6BB 22 = RETBIT 0362 F6BC 11 = ABTBIT 0363 F6BD ] 0364 F6BD 0365 F6BD A0 FF SRCHYY LDYIM &FF ;For LOAD and RDBFER 0366 F6BF 8C DF 03 STY OLDFLG ;Fool PRTHDR to print 0367 F6C2 ;extra blank line after "Loading" message 0368 F6C2 60 RTS 0369 F6C3 0370 F6C3 0371 F6C3 ECLOSE ;close EXEC file 0372 F6C3 0373 F6C3 A9 00 LDAIM ZERO 0374 F6C5 ; 0375 F6C5 EXEC ; EXEC 0376 F6C5 0377 F6C5 ; XY -> filename 0378 F6C5 ; A = $00 0379 F6C5 ; 0380 F6C5 ; does not corrupt Y if just closing file (used by SHUTES) 0381 F6C5 ; 0382 F6C5 08 PHP ;remember whether to just close exec file 0383 F6C6 84 E6 STY EXECY ;save Y 0384 F6C8 ; close any previous exec file 0385 F6C8 AC 56 02 LDY EXECH 0386 F6CB 8D 56 02 STA EXECH ;clear execing 0387 F6CE F0 03 BEQ EXEC2 ;[no current exec file, avoid closing all files] 0388 F6D0 ; A=0 0389 F6D0 20 CE FF JSR OSFIND ;close previous exec file (assumes X not corrupted) 0390 F6D3 EXEC2 0391 F6D3 A4 E6 LDY EXECY ;restore Y 0392 F6D5 28 PLP 0393 F6D6 F0 0B BEQ EXEC0 ;[just stop execing] 0394 F6D8 ; try opening specified file 0395 F6D8 A9 40 LDAIM &40 ;open file for input Acorn macro assembler Page 135 C.F.S. UTILITIES - MOS74 0396 F6DA 20 CE FF JSR OSFIND 0397 F6DD A8 TAY 0398 F6DE F0 C7 BEQ FNF ;[file not found] 0399 F6E0 8D 56 02 STA EXECH ;remember exec file handle 0400 F6E3 EXEC0 ;Z=1 0401 F6E3 60 RTS 0402 F6E4 0403 F6E4 0404 F6E4 RDBFER 0405 F6E4 0406 F6E4 0407 F6E4 ;Read a block into input buffer. Used in GETBYTE 0408 F6E4 0409 F6E4 A2 A6 LDXIM INFILE -&01 0410 F6E6 20 78 FB JSR MOVFN ;Set file searching for 0411 F6E9 20 B1 F7 JSR RDHEAD 0412 F6EC 0413 F6EC RDBFRS 0414 F6EC 0415 F6EC AD CA 03 LDA INFO +BKFLAG ;Check protection bit 0416 F6EF 4A LSRA 0417 F6F0 90 03 BCC RDBFLL ;Not protected -> continue 0418 F6F2 4C 8D F2 JMP PROTER ;Protected -> error 0419 F6F5 0420 F6F5 AD DD 03 RDBFLL LDA NEXTIN 0421 F6F8 85 B4 STA BLOKNO 0422 F6FA AD DE 03 LDA NEXTIN +&01 0423 F6FD 85 B5 STA BLOKNO +&01 ;Set block no. to check 0424 F6FF 0425 F6FF A9 00 LDAIM INBUFR 0426 F701 85 B0 STA BKADDR 0427 F703 A9 0A LDAIM /(INBUFR ) 0428 F705 85 B1 STA BKADDR +&01 0429 F707 A9 FF LDAIM &FF 0430 F709 85 B2 STA BKADDR +&02 0431 F70B 85 B3 STA BKADDR +&03 ;Input buffer is in IO proc. 0432 F70D 20 05 F8 JSR READBK ;Read data into buffer 0433 F710 20 AA F9 JSR LODHDR 0434 F713 D0 25 BNE RDBERR 0435 F715 0436 F715 ;Data read ok, inc. next expected block. 0437 F715 0438 F715 AD FF 0A LDA INBUFR +&FF 0439 F718 8D ED 02 STA FINBYT ;Store final byte of this buffer in safe place 0440 F71B 0441 F71B 20 5E FB JSR NXTBLK ;Next block = current block + 1 0442 F71E ;NOTE - corrupts BLOKNO 0443 F71E 0444 F71E 8E DD 03 STX NEXTIN 0445 F721 8C DE 03 STY NEXTIN +&01 0446 F724 0447 F724 A2 02 LDXIM &02 0448 F726 0449 F726 ;Set block size and flag byte 0450 F726 0451 F726 BD C8 03 RDBFL1 LDAAX INFO +BKSZEL 0452 F729 9D EA 02 STAAX INBSZE 0453 F72C CA DEX 0454 F72D 10 F7 BPL RDBFL1 0455 F72F 2C EC 02 BIT BUFFLG 0456 F732 10 03 BPL RDBFL8 0457 F734 20 E3 F2 JSR NOOLN1 ;If last block, new line 0458 F737 0459 F737 4C E7 FA RDBFL8 JMP CASMOF ;Motor off, exit 0460 F73A 0461 F73A ;From here down, dealing with errors 0462 F73A 0463 F73A RDBERR 0464 F73A 0465 F73A ;Retry - search for block number, and 0466 F73A ;then go back to RDBFRS. 0467 F73A 0468 F73A 20 6A F6 JSR SEARCH ;FTPTR already set by RDHEAD. 0469 F73D D0 AD BNE RDBFRS ;Restart (always jump back) 0470 F73F 0471 F73F 0472 F73F 0473 F73F 0474 F73F 0475 F73F C9 2A RDHDLC CMPIM "*" 0476 F741 F0 37 BEQ RDHDLA ;Char OK, go on to rest of block 0477 F743 C9 23 CMPIM "#" ;Is this a short header ?? 0478 F745 D0 0F BNE ROMER ;No -> illegal char -> error 0479 F747 EE C6 03 INC INFO +BKNOLO ;Have "read" short block header, so 0480 F74A D0 03 BNE RDHDX2 ;increment block number as if we have read whole header 0481 F74C EE C7 03 INC INFO +BKNOHI 0482 F74F A2 FF RDHDX2 LDXIM &FF ;Prepare for non-DCD exit 0483 F751 2C 47 D9 BIT FFBYT ;Set the V flag => not end of SFS 0484 F754 D0 53 BNE RDHDX1 ;Assumed always +ve 0485 F756 0486 F756 A9 F7 ROMER LDAIM NCTBIT 0487 F758 0488 F758 ;Switch CAT bit off so messages not in a funny 0489 F758 ;state if error occurs in *CAT 0490 F758 0491 F758 20 40 F3 JSR ANDSTA 0492 F75B 00 BRK 0493 F75C D7 = SFSERR 0494 F75D 42 61 64 = "Bad ROM" 0495 F764 00 = &00 0496 F765 0497 F765 RDHDL2 0498 F765 0499 F765 ;Here, set motor on and 6850 init etc. 0500 F765 0501 F765 A0 FF LDYIM READFX ;Indicate read 0502 F767 20 87 FB JSR MOTON ;Motor ON and drive select 0503 F76A A9 01 LDAIM &01 0504 F76C 85 C2 STA ITYPE 0505 F76E 20 45 FB JSR RXINIT ;Init 6850 and blip motor 0506 F771 0507 F771 ;Wait for DCD and '* character indicating 0508 F771 ;start of block. 0509 F771 0510 F771 20 8B F9 GETHLP JSR ESCAPE 0511 F774 A9 03 LDAIM &03 0512 F776 C5 C2 CMP ITYPE 0513 F778 D0 F7 BNE GETHLP 0514 F77A 0515 F77A [ MOS125 = &FF 0517 F77A | Acorn macro assembler Page 136 C.F.S. UTILITIES - MOS74 0518 F77A RDHDLA 0519 F77A ] 0520 F77A 20 71 FB JSR SETJB1 ;Set cheksum etc. 0521 F77D 0522 F77D 20 CD F7 RDHDL1 JSR CASIN ;Read and add to checksum 0523 F780 50 1A BVC RDHDEX ;Header interrupted by DCD 0524 F782 99 B2 03 STAAY INFO ;Store in INFO 0525 F785 F0 06 BEQ RDHDL3 ;End of file title (Z set in CASIN) 0526 F787 C8 INY 0527 F788 C0 0B CPYIM FTSIZE ;Attempting to read over f.t. end 0528 F78A D0 F1 BNE RDHDL1 ;No, => continue 0529 F78C 88 DEY 0530 F78D 0531 F78D A2 0C RDHDL3 LDXIM BKINFO ;Now read all info. 0532 F78F 20 CD F7 RDHDL4 JSR CASIN 0533 F792 50 08 BVC RDHDEX ;Header interrupted by DCD 0534 F794 9D B2 03 STAAX INFO 0535 F797 E8 INX 0536 F798 E0 1F CPXIM BKLAST +&02 0537 F79A D0 F3 BNE RDHDL4 0538 F79C 0539 F79C 98 RDHDEX TYA 0540 F79D AA TAX ;Preserve Y for exit 0541 F79E A9 00 LDAIM &00 0542 F7A0 99 B2 03 STAAY INFO ;Terminate f.t. 0543 F7A3 A5 BE LDA CHKSUM 0544 F7A5 05 BF ORA CHKSUM +&01 0545 F7A7 85 C1 STA HDRCRC ;Store CRC indication 0546 F7A9 20 6D FB RDHDX1 JSR SETJOB 0547 F7AC 84 C2 STY ITYPE ;If header interrupted => block fin. 0548 F7AE 0549 F7AE 8A TXA 0550 F7AF D0 1B BNE RDHDXX 0551 F7B1 0552 F7B1 RDHEAD 0553 F7B1 0554 F7B1 ;Read header info into INFO. Check file title 0555 F7B1 ;against FTPTR, and print header info. 0556 F7B1 0557 F7B1 ;First, wait for DCD followed by "*" 0558 F7B1 0559 F7B1 AD 47 02 LDA SROMSW 0560 F7B4 F0 AF BEQ RDHDL2 ;SFS not enabled, carry on 0561 F7B6 ;GoMMC tape patch has F77E NOP;NOP 0562 F7B6 0563 F7B6 ;Here, SFS enabled, so read first char 0564 F7B6 ;(assumed to be "*") and go on to read 0565 F7B6 ;rest of block. 0566 F7B6 0567 F7B6 RDHDLD 0568 F7B6 20 8B EE JSR RDSPCH 0569 F7B9 C9 2B CMPIM SFSEND ;Is "end of ROM" char ? 0570 F7BB D0 82 BNE RDHDLC 0571 F7BD A9 08 LDAIM CATBIT 0572 F7BF 25 E2 AND CFSTAT 0573 F7C1 F0 03 BEQ RDHDL5 ;If not in CAT, don't do new line 0574 F7C3 0575 F7C3 20 E7 F2 JSR NOOLIN ;New line between ROMs 0576 F7C6 20 4E EE RDHDL5 JSR SRNEXT 0577 F7C9 0578 F7C9 ;Carry clear => not at end of filing system, so 0579 F7C9 ;read next character, assumed still to be start 0580 F7C9 ;of header although in new rom. 0581 F7C9 0582 F7C9 90 EB BCC RDHDLD 0583 F7CB 0584 F7CB ;Carry set => end of filing system, so 0585 F7CB ;indicate to outside world in V flag 0586 F7CB B8 CLV 0587 F7CC [ MOS125 = &FF 0588 F7CC | 0589 F7CC RDHDXX 0590 F7CC ] 0591 F7CC 60 RTS 0592 F7CD 0593 F7CD ;Note assumed exit with Y = 0 0594 F7CD ;for LOAD and RDBFRS 0595 F7CD 0596 F7CD 0597 F7CD 0598 F7CD 0599 F7CD 0600 F7CD CASIN 0601 F7CD AD 47 02 LDA SROMSW ;is SFS on ? 0602 F7D0 F0 11 BEQ CASIN1 ;Nope, read from tape 0603 F7D2 ;GoMMC tape patch has F79A NOP;NOP 0604 F7D2 0605 F7D2 ;Force a read from ROM & set IRUPT flag 0606 F7D2 0607 F7D2 8A TXA 0608 F7D3 48 PHA 0609 F7D4 98 TYA 0610 F7D5 48 PHA 0611 F7D6 20 8B EE JSR RDSPCH 0612 F7D9 85 BD STA IBUF 0613 F7DB A9 FF LDAIM &FF 0614 F7DD 85 C0 STA IFLAG ;=> irupt occurred, no DCD 0615 F7DF 68 PLA 0616 F7E0 A8 TAY 0617 F7E1 68 PLA 0618 F7E2 AA TAX 0619 F7E3 0620 F7E3 20 AD F8 CASIN1 JSR IWAIT 0621 F7E6 0622 F7E6 ;Note A=IBUF after IWAIT 0623 F7E6 0624 F7E6 [ DEBUG=0 0630 F7E6 ] 0631 F7E6 0632 F7E6 [ MOS125 = &FF 0662 F7E6 | 0663 F7E6 ;Can't move to MOS05 to branch to OCSREX, fallthrough from CASIN1! 0664 F7E6 08 ADDCRC PHP 0665 F7E7 48 PHA 0666 F7E8 0667 F7E8 0021 CCITTL * &21 0668 F7E8 0010 CCITTH * &10 0669 F7E8 0670 F7E8 45 BF EOR CHKSUM +&01 0671 F7EA 38 SEC 0672 F7EB 66 BF ROR CHKSUM +&01 Acorn macro assembler Page 137 C.F.S. UTILITIES - MOS74 0673 F7ED 06 BE CRC1 ASL CHKSUM 0674 F7EF 2A ROLA 0675 F7F0 90 0A BCC CRC2 0676 F7F2 48 PHA 0677 F7F3 A5 BE LDA CHKSUM 0678 F7F5 49 21 EORIM CCITTL 0679 F7F7 85 BE STA CHKSUM 0680 F7F9 68 PLA 0681 F7FA 49 10 EORIM CCITTH 0682 F7FC 46 BF CRC2 LSR CHKSUM +&01 0683 F7FE D0 ED BNE CRC1 0684 F800 85 BF STA CHKSUM +&01 0685 F802 68 PLA 0686 F803 28 PLP 0687 F804 60 RTS 0688 F805 ] 0689 F805 0690 F805 0691 F805 0692 F805 0693 F805 RDBLOK 0694 F805 0695 F805 READBK 0696 F805 0697 F805 ;Sets up BG job to read data into BKADDR 0698 F805 ;and read CRC. 0699 F805 0700 F805 ;Note: must not corrupt Y ! 0701 F805 0702 F805 A9 00 LDAIM &00 0703 F807 85 BD CHKBIN STA IBUF ;Indicate read to memory 0704 F809 A2 00 LDXIM &00 0705 F80B 86 BC STX TEMP ;Pointer into data 0706 F80D ;If empty, data read finished, X=$00 0707 F80D 50 0A BVC RDBKEM ;If V clear from header read 0708 F80F ;just ignore all data (since hdr. 0709 F80F ;interrupted by DCD). 0710 F80F 0711 F80F AD C8 03 LDA INFO +BKSZEL 0712 F812 0D C9 03 ORA INFO +BKSZEH 0713 F815 F0 02 BEQ RDBKEM ;Empty block => no BG job 0714 F817 0715 F817 A2 04 LDXIM &04 0716 F819 86 C2 RDBKEM STX ITYPE 0717 F81B 0718 F81B ;V not important from here on 0719 F81B 0720 F81B 60 RTS 0721 F81C 0722 F81C 0723 F81C 0724 F81C 0725 F81C WRBLOK 0726 F81C 0727 F81C WBLOCK 0728 F81C 0729 F81C ;Write block pointed to by BKADDR. Expects header info 0730 F81C ;to be in INFO and file name in FILNAM. 0731 F81C 0732 F81C ;Assumes 6850 is in reset state, and SERPROC 0733 F81C ;is set with motor on. 0734 F81C 0735 F81C 08 PHP ;Save I'rupt state 0736 F81D A2 03 LDXIM &03 ;Set spare bytes 0737 F81F A9 00 LDAIM &00 0738 F821 9D CB 03 SETSPR STAAX INFO +BKSPAR 0739 F824 CA DEX 0740 F825 10 FA BPL SETSPR 0741 F827 0742 F827 AD C6 03 LDA INFO +BKNOLO 0743 F82A 0D C7 03 ORA INFO +BKNOHI 0744 F82D D0 05 BNE WRBKL5 ;Not first block, continue 0745 F82F 20 BB F8 JSR LEADER 0746 F832 F0 03 BEQ WRBKL4 ;Always Z exit 0747 F834 0748 F834 20 BF F8 WRBKL5 JSR PUTGAP ;Put out inter-block gap 0749 F837 0750 F837 A9 2A WRBKL4 LDAIM "*" 0751 F839 85 BD STA IBUF ;Start of block char is output IMMEDIATELY 0752 F83B ;on TXINIT. 0753 F83B 0754 F83B 20 6D FB JSR SETJOB 0755 F83E 0756 F83E 20 3F FB JSR TXINIT ;Get 6850 ready 0757 F841 20 AD F8 JSR IWAIT ;Wait for * to go out 0758 F844 0759 F844 88 DEY ;Set zero by SETJOB 0760 F845 C8 WRBKL1 INY 0761 F846 B9 D2 03 LDAAY FILNAM ;Set Z flag if file terminator 0762 F849 99 B2 03 STAAY INFO ;PRTHDR expects INFO to have f.t. in it 0763 F84C 20 72 F0 JSR PUTCHK 0764 F84F 0765 F84F ;Note Z flag kept over PUTCHK 0766 F84F 0767 F84F D0 F4 BNE WRBKL1 ;File title out. 0768 F851 0769 F851 A2 0C LDXIM BKINFO 0770 F853 BD B2 03 WRBKL2 LDAAX INFO ;Rest of header to tape 0771 F856 20 72 F0 JSR PUTCHK 0772 F859 E8 INX 0773 F85A E0 1D CPXIM BKLAST 0774 F85C D0 F5 BNE WRBKL2 0775 F85E 0776 F85E 20 A4 F8 JSR PUTCRC 0777 F861 0778 F861 AD C8 03 LDA INFO +BKSZEL 0779 F864 0D C9 03 ORA INFO +BKSZEH 0780 F867 F0 1B BEQ WRBKEM ;Empty block 0781 F869 0782 F869 [ MOS125 = &FF 0784 F869 ] 0785 F869 20 71 FB JSR SETJB1 0786 F86C WRBKL3 0787 F86C [ MOS125 = &FF 0799 F86C | 0800 F86C [ TUBESW=0 0801 F86C 20 C6 FB JSR TUBCHK ;Check tube present and top two bytes of address 0802 F86F F0 05 BEQ WRBKL6 ;Yes, continue. (Note TAX done in TUBCHK) 0803 F871 AD E5 FE LDA TREG3 ;No, get from tube 0804 F874 90 02 BCC WRBKL7 ;skip IO read (always; TUBCHK returns CC if Tube) 0805 F876 Acorn macro assembler Page 138 C.F.S. UTILITIES - MOS74 0806 F876 WRBKL6 0807 F876 B1 B0 LDAIY BKADDR ;Load byte from IO proc. 0808 F878 WRBKL7 0809 F878 | 0811 F878 ] 0812 F878 ] 0813 F878 0814 F878 20 72 F0 JSR PUTCHK ;Output data 0815 F87B C8 INY 0816 F87C CC C8 03 CPY INFO +BKSZEL 0817 F87F D0 EB BNE WRBKL3 0818 F881 0819 F881 20 A4 F8 JSR PUTCRC 0820 F884 20 AD F8 WRBKEM JSR IWAIT ;Wait for irupt => char on tape 0821 F887 20 AD F8 JSR IWAIT 0822 F88A 20 3B FB JSR CRESET ;Reset for interblock gap 0823 F88D A9 01 LDAIM &01 0824 F88F 20 C1 F8 JSR PAUSE ;1/10 sec delay to clear heads 0825 F892 28 PLP ;Restore I'rupt status 0826 F893 0827 F893 20 E2 F8 JSR SAVHDR ;Finally, print info 0828 F896 2C CA 03 BIT INFO +BKFLAG 0829 F899 10 08 BPL WRBKEX ;Not last block 0830 F89B 08 PHP 0831 F89C 20 BB F8 JSR TAIL 0832 F89F 20 E0 F2 JSR FINOP 0833 F8A2 28 PLP 0834 F8A3 0835 F8A3 ;Exit MI if last block, PL otherwise 0836 F8A3 60 WRBKEX RTS 0837 F8A4 0838 F8A4 0839 F8A4 0840 F8A4 0841 F8A4 0842 F8A4 0843 F8A4 [ MOS125 = &FF 0850 F8A4 ] 0851 F8A4 0852 F8A4 0853 F8A4 0854 F8A4 0855 F8A4 A5 BF PUTCRC LDA CHKSUM +&01 0856 F8A6 20 AB F8 JSR PUTCAS 0857 F8A9 A5 BE LDA CHKSUM 0858 F8AB 0859 F8AB 0860 F8AB PUTCAS 0861 F8AB 0862 F8AB ;Put byte to cassette 0863 F8AB 0864 F8AB 85 BD STA IBUF 0865 F8AD 0866 F8AD 20 8B F9 IWAIT JSR ESCAPE 0867 F8B0 24 C0 BIT IFLAG 0868 F8B2 10 F9 BPL IWAIT 0869 F8B4 0870 F8B4 A9 00 LDAIM &00 0871 F8B6 85 C0 STA IFLAG ;Zero IFLAG 0872 F8B8 A5 BD LDA IBUF ;Restore A 0873 F8BA 60 RTS ;Note V preserved 0874 F8BB 0875 F8BB 0876 F8BB 0877 F8BB LEADER 0878 F8BB 0879 F8BB TAIL 0880 F8BB 0881 F8BB ;Assumes RESET done by WRBLOK 0882 F8BB 0883 F8BB A9 32 LDAIM &32 0884 F8BD D0 02 BNE PAUSE ;5 secs hitone altogether. 0885 F8BF 0886 F8BF 0887 F8BF 0888 F8BF PUTGAP 0889 F8BF 0890 F8BF ;Note is assumed indivisible by PUTBYT 0891 F8BF 0892 F8BF A5 C7 LDA GAPTIM 0893 F8C1 0894 F8C1 PAUSE 0895 F8C1 0896 F8C1 ;Pause for A/10 secs (while putting out 0897 F8C1 ;leaders and gaps mainly). 0898 F8C1 0899 F8C1 A2 05 LDXIM &05 0900 F8C3 8D 40 02 PSLOP1 STA CYCLE 0901 F8C6 20 8B F9 PSLOOP JSR ESCAPE 0902 F8C9 2C 40 02 BIT CYCLE 0903 F8CC 10 F8 BPL PSLOOP 0904 F8CE CA DEX 0905 F8CF D0 F2 BNE PSLOP1 0906 F8D1 60 RTS 0907 F8D2 0908 F8D2 0909 F8D2 0910 F8D2 PRTHDR 0911 F8D2 0912 F8D2 ;Print header details. 0913 F8D2 ;Keeps count of file size and prints 0914 F8D2 ;total file length when last block is indicated. 0915 F8D2 ;Expects block info to be in INFO. 0916 F8D2 0917 F8D2 0918 F8D2 AD C6 03 LDA INFO +BKNOLO 0919 F8D5 0D C7 03 ORA INFO +BKNOHI 0920 F8D8 F0 05 BEQ PRTHL8 ;If first block, is new file 0921 F8DA 2C DF 03 BIT OLDFLG ;If previous block = last block 0922 F8DD 10 03 BPL PRTHL3 ;then new line 0923 F8DF 0924 F8DF PRTHDL 0925 F8DF 20 E3 F2 PRTHL8 JSR NOOLN1 ;New line if messages on and no error 0926 F8E2 0927 F8E2 SAVHDR 0928 F8E2 0929 F8E2 ;Entry from WRBLOK 0930 F8E2 0931 F8E2 [ MOS125 = &7F 0932 F8E2 ;Set FSIZE here for correct OSFILE block whether messages on/off 0933 F8E2 PRTHL3 Acorn macro assembler Page 139 C.F.S. UTILITIES - MOS74 0934 F8E2 AD C8 03 LDA INFO +BKSZEL 0935 F8E5 85 CC STA FSIZE 0936 F8E7 AD C6 03 LDA INFO +BKNOLO 0937 F8EA 18 CLC 0938 F8EB 6D C9 03 ADC INFO +BKSZEH 0939 F8EE 85 CD STA FSIZE + 1 0940 F8F0 A0 00 LDYIM &00 0941 F8F2 | 0943 F8F2 ] 0944 F8F2 84 BA STY ERRSW 0945 F8F4 AD CA 03 LDA INFO +BKFLAG 0946 F8F7 8D DF 03 STA OLDFLG ;Set prev. flag 0947 F8FA 0948 F8FA 0949 F8FA 20 59 EA JSR MSGON 0950 F8FD F0 61 BEQ PRTHLX ;Messages off => exit 0951 F8FF 0952 F8FF [ MOS125 = &FF 0955 F8FF | 0956 F8FF 20 EC FF JSR WRCR 0957 F902 ] 0958 F902 0959 F902 ; Note assumed here Y is preserved over 0960 F902 ;calls to MSGON and OSWRCH. 0961 F902 0962 F902 B9 B2 03 PRTHL1 LDAAY INFO 0963 F905 F0 10 BEQ PRTHL2 ;Zero terminator for filename 0964 F907 0965 F907 C9 20 CMPIM &20 0966 F909 90 04 BCC PRTHLD ;A<$20 => control char => invalid 0967 F90B C9 7F CMPIM &7F 0968 F90D 90 02 BCC PRTHLC ;$20<=A<$7F => Valid 0969 F90F 0970 F90F A9 3F PRTHLD LDAIM "?" ;Otherwise, print ?? 0971 F911 20 EE FF PRTHLC JSR OSWRCH ;Write file title 0972 F914 C8 INY 0973 F915 D0 EB BNE PRTHL1 0974 F917 0975 F917 AD 47 02 PRTHL2 LDA SROMSW 0976 F91A F0 04 BEQ PRTHLF ;In CFS -> continue 0977 F91C 24 BB BIT USFLGS 0978 F91E 50 40 BVC PRTHLX ;SFS short msgs => file name only 0979 F920 0980 F920 20 87 F9 PRTHLF JSR PRTSP 0981 F923 C8 INY 0982 F924 C0 0B CPYIM FTSIZE 0983 F926 90 EF BCC PRTHL2 0984 F928 0985 F928 AD C6 03 LDA INFO +BKNOLO 0986 F92B AA TAX ;Store for final length 0987 F92C 20 71 F9 JSR WHEX ;Write block no. lo 0988 F92F 0989 F92F 2C CA 03 BIT INFO +BKFLAG 0990 F932 10 2C BPL PRTHLX ;Not last block -> finish 0991 F934 0992 F934 ;Here, is last block -> print total length 0993 F934 0994 F934 [ MOS125 = &7F 0995 F934 A5 CD LDA FSIZE + 1 0996 F936 20 6C F9 JSR WSPHEX 0997 F939 A5 CC LDA FSIZE 0998 F93B | 1010 F93B ] 1011 F93B 20 71 F9 JSR WHEX 1012 F93E 1013 F93E 24 BB BIT USFLGS 1014 F940 50 1E BVC PRTHLX ;=> Short messages => exit 1015 F942 1016 F942 ;Here doing long messages 1017 F942 1018 F942 A2 04 LDXIM &04 1019 F944 20 87 F9 PRTHLV JSR PRTSP 1020 F947 CA DEX 1021 F948 D0 FA BNE PRTHLV 1022 F94A 1023 F94A A2 0F LDXIM BKLOAD +&03 1024 F94C 20 54 F9 JSR PRTHLT 1025 F94F 20 87 F9 JSR PRTSP 1026 F952 A2 13 LDXIM BKEXEC +&03 1027 F954 1028 F954 A0 04 PRTHLT LDYIM &04 1029 F956 BD B2 03 PRTHLU LDAAX INFO 1030 F959 20 71 F9 JSR WHEX 1031 F95C CA DEX 1032 F95D 88 DEY 1033 F95E D0 F6 BNE PRTHLU 1034 F960 1035 F960 [ MOS125 = &FF 1037 F960 ] 1038 F960 60 PRTHLX RTS 1039 F961 1040 F961 1041 F961 1042 F961 1043 F961 [ MOS125 = &FF 1065 F961 ] 1066 F961 1067 F961 1068 F961 LNK MOS76 0001 F961 0002 F961 TTL C.F.S. - I/O Utilities -> MOS76 0003 F961 OPT MOS76 Acorn macro assembler Page 140 C.F.S. - I/O Utilities -> MOS76 0004 F961 0005 F961 0006 F961 ;****** UTILITIES II ****** 0007 F961 0008 F961 ADDBKA 0009 F961 0010 F961 ;Increment block pointer by 256 bytes, assuming that 0011 F961 ;block received is 256 bytes long. Note BKADDR is 4 bytes 0012 F961 0013 F961 E6 B1 INC BKADDR +&01 0014 F963 D0 06 BNE ADDBK1 0015 F965 E6 B2 INC BKADDR +&02 0016 F967 D0 02 BNE ADDBK1 0017 F969 E6 B3 INC BKADDR +&03 0018 F96B 60 ADDBK1 RTS 0019 F96C 0020 F96C 0021 F96C 0022 F96C 0023 F96C 48 WSPHEX PHA 0024 F96D 20 87 F9 JSR PRTSP 0025 F970 68 PLA 0026 F971 48 WHEX PHA 0027 F972 4A LSRA 0028 F973 4A LSRA 0029 F974 4A LSRA 0030 F975 4A LSRA 0031 F976 20 7A F9 JSR WDIGIT 0032 F979 68 PLA 0033 F97A [ MOS125 = &FF 0037 F97A | 0038 F97A 29 0F WDIGIT ANDIM &0F 0039 F97C 09 30 ORAIM "0" 0040 F97E ] 0041 F97E C9 3A CMPIM &3A 0042 F980 90 02 BCC HXDSKP 0043 F982 69 06 ADCIM &06 0044 F984 4C EE FF HXDSKP JMP OSWRCH 0045 F987 0046 F987 0047 F987 0048 F987 0049 F987 A9 20 PRTSP LDAIM SPACE 0050 F989 D0 F9 BNE HXDSKP 0051 F98B 0052 F98B 0053 F98B ESCAPE 0054 F98B 0055 F98B ;Checks ESCAPE happened. If so, does error 0056 F98B ;break with appropriate message after 0057 F98B ;acknowldging the ESCAPE. 0058 F98B 0059 F98B ;Also switches off various status bits 0060 F98B ;Motor switched OFF 0061 F98B 0062 F98B ;Note, no test is done if inside WRCH or RDCH 0063 F98B ;so that ESCAPE cannot occur inside EXEC/SPOOL 0064 F98B 0065 F98B 08 PHP 0066 F98C 24 EB BIT ESSEMA 0067 F98E 30 04 BMI ESCLL0 ;Inside WRCH or RDCH -> no ESCAPE 0068 F990 24 FF BIT ESCADD 0069 F992 30 02 BMI ESCERR 0070 F994 ESCLL0 0071 F994 28 PLP 0072 F995 60 RTS 0073 F996 0074 F996 ESCERR 0075 F996 0076 F996 20 3E F3 JSR CATOFF ;Switch CAT bit off 0077 F999 20 E7 FA JSR CASMOF ;Motor OFF/release 0078 F99C 0079 F99C A9 7E LDAIM &7E 0080 F99E 20 F4 FF JSR OSBYTE ;Acknowledge ESC to MOS 0081 F9A1 0082 F9A1 00 BRK ;Then error 0083 F9A2 11 45 73 = &11,"Escape",0 0084 F9AA 0085 F9AA 0086 F9AA 0087 F9AA 0088 F9AA 0089 F9AA 98 LODHDR TYA 0090 F9AB F0 0D BEQ LODHD1 ;Print message depending on Y 0091 F9AD 20 3B FA JSR MSGOUT 0092 F9B0 0D 4C 6F = MCR,"Loading",MCR,0 0093 F9BA 0094 F9BA 0095 F9BA 0096 F9BA LODHD1 0097 F9BA 0098 F9BA 85 BA STA ERRSW ;A always zero at this point 0099 F9BC ;Set ERRSW so always extra line after "Loading" 0100 F9BC ;and before file name. 0101 F9BC 0102 F9BC 0103 F9BC A2 FF LDXIM &FF ;Set "abort if nesc." flag 0104 F9BE A5 C1 LDA HDRCRC 0105 F9C0 D0 0D BNE HDRCHK ;Header CRC error takes precedence over 0106 F9C2 ;file and block errors, since a header error may 0107 F9C2 ;spuriously cause either or both of these. 0108 F9C2 0109 F9C2 20 67 FA JSR CMPFT 0110 F9C5 0111 F9C5 08 PHP ;Store EQ bit from CMPFT 0112 F9C6 A2 FF LDXIM &FF ;Set "abort if nesc." flag 0113 F9C8 A0 8E LDYIM FILEER 0114 F9CA A9 FA LDAIM /(FILEER ) ;Set error pointers 0115 F9CC 28 PLP 0116 F9CD 0117 F9CD D0 1C BNE TAPER0 ;Files don't match 0118 F9CF 0119 F9CF CATERR ;Entry from catalogue here 0120 F9CF HDRCHK 0121 F9CF A0 83 LDYIM DATAER ;Set lo byte of error pointer 0122 F9D1 A5 C1 LDA HDRCRC ;Was header CRC ok ? 0123 F9D3 F0 04 BEQ CHKBKN ;Yes, check block no. 0124 F9D5 A9 FA LDAIM /(DATAER ) ;No, do error 0125 F9D7 D0 12 BNE TAPER0 0126 F9D9 0127 F9D9 Acorn macro assembler Page 141 C.F.S. - I/O Utilities -> MOS76 0128 F9D9 AD C6 03 CHKBKN LDA INFO +BKNOLO ;Is expected block ?? 0129 F9DC C5 B4 CMP BLOKNO 0130 F9DE D0 07 BNE BLKERR 0131 F9E0 AD C7 03 LDA INFO +BKNOHI 0132 F9E3 C5 B5 CMP BLOKNO +&01 0133 F9E5 F0 13 BEQ CHEKSM ;No error -> go on 0134 F9E7 0135 F9E7 A0 99 BLKERR LDYIM BLOKER 0136 F9E9 A9 FA LDAIM /(BLOKER ) 0137 F9EB 0138 F9EB 48 TAPER0 PHA ;Store error ptr. 0139 F9EC 98 TYA 0140 F9ED 48 PHA 0141 F9EE 8A TXA ;Store "abort if nesc." flag 0142 F9EF 48 PHA 0143 F9F0 20 DF F8 JSR PRTHDL ;Print header ON NEW LINE 0144 F9F3 68 PLA 0145 F9F4 AA TAX 0146 F9F5 68 PLA 0147 F9F6 A8 TAY 0148 F9F7 68 PLA 0149 F9F8 D0 14 BNE TAPERR 0150 F9FA 0151 F9FA 8A CHEKSM TXA 0152 F9FB 48 PHA ;Store X over possible IRUPT call 0153 F9FC 20 D2 F8 JSR PRTHDR ; Print header info. 0154 F9FF 0155 F9FF 20 CB FA JSR CHEKLP ;Wait for end of BG job 0156 FA02 ;In SFS, CHEKLP reads next SFS block 0157 FA02 0158 FA02 ;Note X & Y corrupted by IRUPT, which 0159 FA02 ;is only called when SROM system active. 0160 FA02 ;Y is restored at ERREXT. 0161 FA02 ; 0162 FA02 68 PLA 0163 FA03 AA TAX ;Restore "abort if nesc." flag 0164 FA04 0165 FA04 A5 BE LDA CHKSUM 0166 FA06 05 BF ORA CHKSUM +&01 0167 FA08 F0 78 BEQ ERREXX ;No errors, tape ok, exit 0168 FA0A 0169 FA0A A0 83 LDYIM DATAER ;Set message ptr. 0170 FA0C A9 FA LDAIM /(DATAER ) 0171 FA0E 0172 FA0E C6 BA TAPERR DEC ERRSW 0173 FA10 48 PHA ;Store hi byte of error pointer 0174 FA11 0175 FA11 24 EB BIT ESSEMA 0176 FA13 30 0D BMI ERRABT ;During EXEC/SPOOL can ABORT ONLY ! 0177 FA15 0178 FA15 8A TXA ;If X = 0 => print only, X = $FF abort if nesc. 0179 FA16 2D 47 02 AND SROMSW ;If not cataloging, and SROM => abort 0180 FA19 D0 07 BNE ERRABT 0181 FA1B 8A TXA ;Otherwise, check if "abort on error" option set 0182 FA1C ;If so, do BRK 0183 FA1C 0184 FA1C 29 11 ANDIM ABTBIT 0185 FA1E 25 BB AND USFLGS 0186 FA20 F0 10 BEQ PRTERR ;Abort not set => print 0187 FA22 0188 FA22 68 ERRABT PLA 0189 FA23 85 B9 STA FTPTR +&01 ;Set error pointer 0190 FA25 84 B8 STY FTPTR 0191 FA27 20 C3 F6 JSR ECLOSE ;close EXEC file 0192 FA2A 46 EB LSR ESSEMA ;Switch off critical region 0193 FA2C 20 DD FA JSR BEEPOF ;Motor off/BEEP 0194 FA2F 6C B8 00 JMI FTPTR ;Abort = break with error msg. 0195 FA32 0196 FA32 68 PRTERR PLA ;Restore hi byte of pointer 0197 FA33 0198 FA33 ;Now must add ONE to pointer to get past BRK 0199 FA33 ;at front of message. Note MSGOUT does an INC 0200 FA33 ;before printing, so don't have to add 2. 0201 FA33 0202 FA33 [ MOS125 = &FF 0207 FA33 | 0208 FA33 C0 FF CPYIM &FF 0209 FA35 C8 INY ;Inc lo byte past BRK instruction 0210 FA36 69 00 ADCIM &00 0211 FA38 ] 0212 FA38 48 PRTEON PHA ;Set stack for MSGOUT 0213 FA39 98 TYA 0214 FA3A 48 PHA 0215 FA3B ; Print message and enter code 0216 FA3B ; directly AFTER message 0217 FA3B ; 0218 FA3B MSGOUT 0219 FA3B 0220 FA3B ;Enter here for messages printed if MSGON 0221 FA3B ;Note, X must be preserved 0222 FA3B 0223 FA3B 20 59 EA JSR MSGON 0224 FA3E A8 TAY ;Store for STROUT 0225 FA3F 0226 FA3F STROUT 0227 FA3F 0228 FA3F 0229 FA3F 68 PLA 0230 FA40 85 B8 STA FTPTR 0231 FA42 68 PLA 0232 FA43 85 B9 STA FTPTR +&01 0233 FA45 98 TYA 0234 FA46 08 PHP ;Z bit => print 0235 FA47 E6 B8 VSTRLP INC FTPTR 0236 FA49 D0 02 BNE VSTRL1 0237 FA4B E6 B9 INC FTPTR +&01 0238 FA4D A0 00 VSTRL1 LDYIM &00 0239 FA4F B1 B8 LDAIY FTPTR 0240 FA51 F0 0A BEQ VSTREX 0241 FA53 28 PLP 0242 FA54 08 PHP 0243 FA55 F0 F0 BEQ VSTRLP ;If Z set => don't print 0244 FA57 20 E3 FF JSR OSASCI 0245 FA5A 4C 47 FA JMP VSTRLP 0246 FA5D 28 VSTREX PLP ;Restore stack 0247 FA5E E6 B8 INC FTPTR 0248 FA60 D0 02 BNE VSTREZ 0249 FA62 E6 B9 INC FTPTR +&01 0250 FA64 0251 FA64 ;Exit always with Z CLEAR 0252 FA64 Acorn macro assembler Page 142 C.F.S. - I/O Utilities -> MOS76 0253 FA64 6C B8 00 VSTREZ JMI FTPTR 0254 FA67 0255 FA67 0256 FA67 CMPFT 0257 FA67 A2 FF LDXIM &FF 0258 FA69 CMPFT2 0259 FA69 E8 INX 0260 FA6A CMPFT1 ;match filename, equating cases 0261 FA6A BD D2 03 LDAAX FILNAM 0262 FA6D D0 07 BNE CMPFT3 ;[not at end of filename] 0263 FA6F ; 0264 FA6F ; at end of filename, either: 0265 FA6F ; X=0 => match on filename "" (null filename) 0266 FA6F ; X<>0 => INFO(X)=0 => match, <>0 => no match 0267 FA6F ; 0268 FA6F 8A TXA 0269 FA70 F0 03 BEQ CMPFT0 ;[match on filename "", return EQ status] 0270 FA72 BD B2 03 LDAAX INFO 0271 FA75 CMPFT0 ;EQ => match, NE => no match 0272 FA75 60 RTS 0273 FA76 0274 FA76 CMPFT3 ;not at end of filename 0275 FA76 20 49 E5 JSR CAPS 0276 FA79 5D B2 03 EORAX INFO 0277 FA7C B0 02 BCS NALPHA 0278 FA7E ; filename character is a letter 0279 FA7E 29 DF ANDIM &DF ;equate cases 0280 FA80 NALPHA 0281 FA80 F0 E7 BEQ CMPFT2 0282 FA82 ; filenames not equal 0283 FA82 ; return NE status 0284 FA82 ERREXX ;Called from around CSON1 0285 FA82 60 RTS 0286 FA83 0287 FA83 0288 FA83 0289 FA83 00 DATAER BRK 0290 FA84 D8 = CFSERJ 0291 FA85 0D 44 61 = MCR,"Data?",0 0292 FA8C 0293 FA8C D0 15 BNE REWIND ;Z always CLEAR after MSGOUT 0294 FA8E 00 FILEER BRK 0295 FA8F DB = CFSERF 0296 FA90 0D 46 69 = MCR,"File?",0 0297 FA97 0298 FA97 D0 0A BNE REWIND ;Z always CLEAR after MSGOUT 0299 FA99 00 BLOKER BRK 0300 FA9A DA = CFSERH 0301 FA9B 0D 42 6C = MCR,"Block?",0 0302 FAA3 0303 FAA3 0304 FAA3 A5 BA REWIND LDA ERRSW 0305 FAA5 F0 21 BEQ ERROEX ;If no error, leave 0306 FAA7 8A TXA 0307 FAA8 F0 1E BEQ ERROEX ;If only printing, no retry 0308 FAAA A9 22 LDAIM RETBIT ;Otherwise, see if RETRY set 0309 FAAC 24 BB BIT USFLGS 0310 FAAE F0 18 BEQ ERROEX 0311 FAB0 20 3B FB JSR CRESET 0312 FAB3 A8 TAY ;Assume A is non-zero from RESET 0313 FAB4 20 3F FA JSR STROUT 0314 FAB7 0D 07 52 = MCR,BEL,"Rewind tape",MCR,MCR,0 0315 FAC7 0316 FAC7 0317 FAC7 ;Note NZ set by VSTRIN here 0318 FAC7 60 CSON1 RTS 0319 FAC8 0320 FAC8 0321 FAC8 20 E7 F2 ERROEX JSR NOOLIN ;New line if msgs on 0322 FACB 0323 FACB ;Wait for BG job to finish since if IGNORE set, must 0324 FACB ;allow LOADs etc. to complete. 0325 FACB 0326 FACB A5 C2 CHEKLP LDA ITYPE 0327 FACD F0 F8 BEQ CSON1 ;If BG job finished exit with EQ status 0328 FACF 0329 FACF ;Note: loop must check ITYPE first, coz may be no 0330 FACF ;BG job in the case of zero length file. Therefore 0331 FACF ;don't want to read next SROM byte. 0332 FACF 0333 FACF 20 8B F9 JSR ESCAPE 0334 FAD2 AD 47 02 LDA SROMSW 0335 FAD5 F0 F4 BEQ CHEKLP ;If no speech, wait for end 0336 FAD7 ;GoMMC tape patch has FAE0 NOP;NOP 0337 FAD7 20 C0 F5 JSR IRUPT ;Otherwise, get next byte 0338 FADA 4C CB FA JMP CHEKLP ;And loop 0339 FADD 0340 FADD 0341 FADD 0342 FADD ;CHIP CONTROL 0343 FADD 0344 FADD 20 59 EA BEEPOF JSR MSGON 0345 FAE0 F0 05 BEQ CASMOF 0346 FAE2 A9 07 LDAIM &07 0347 FAE4 20 EE FF JSR OSWRCH ;Cannot use MSGOUT, coz called from inside it 0348 FAE7 A9 80 CASMOF LDAIM TUBERL ;Tube release number 0349 FAE9 20 B0 FB JSR TBINIT ;Release tube 0350 FAEC 0351 FAEC ;NOTE - TBINIT checks BKADDR. However, either at this point 0352 FAEC ;the tube has been claimed, in which case BKADDR is still a 0353 FAEC ;tube address and the release will go through; or the tube 0354 FAEC ;has not been claimed, in which case it don't matter if the 0355 FAEC ;release don't happen. NOTE also that a claim is done in 0356 FAEC ;TBINIT before the release, so that spurious claims may 0357 FAEC ;result depending on the values in BKADDR. These will, however 0358 FAEC ;be immediately released again. 0359 FAEC 0360 FAEC A2 00 LDXIM &00 0361 FAEE 20 8C FB JSR CMOTOR ;Motor off: drive set in MOTOR. 0362 FAF1 ; 0363 FAF1 RELEAS 0364 FAF1 ; called by CFS on exit from any cassette operation 0365 FAF1 ; N.B. RS423 might not have been claimed beforehand 0366 FAF1 ; 0367 FAF1 08 PHP 0368 FAF2 78 SEI ;must disable interrupts 0369 FAF3 ; 0370 FAF3 ; restore MOS 6850 and serproc byte 0371 FAF3 ; 0372 FAF3 AD 82 02 LDA SPREGA 0373 FAF6 8D 10 FE STA SERPRC Acorn macro assembler Page 143 C.F.S. - I/O Utilities -> MOS76 0374 FAF9 ; 0375 FAF9 A9 00 LDAIM ZERO 0376 FAFB 85 EA STA RSTUT 0377 FAFD F0 01 BEQ RELX ;[ALWAYS jump] 0378 FAFF ; 0379 FAFF MC6850 0380 FAFF 08 PHP 0381 FB00 ; 0382 FB00 RELX 0383 FB00 ; CORRUPTS A 0384 FB00 ; setup MC6850 0385 FB00 ; disable Rx/Tx interrupts 0386 FB00 ; divide by 64, 7 data bits + 1 stop bit, even parity 0387 FB00 ; or 8 bits, one stop bit, no parity!! 0388 FB00 ; 0389 FB00 20 3B FB JSR CRESET ;master reset 0390 FB03 ; 0391 FB03 ; reset data format bits 0392 FB03 ; 0393 FB03 AD 50 02 LDA RSCTFL 0394 FB06 ; 0395 FB06 4C 20 E2 JMP STARSC ;share code with 'RS423' 0396 FB09 0397 FB09 0398 FB09 RSWT1 0399 FB09 28 PLP 0400 FB0A 24 FF BIT ESCFLG 0401 FB0C 10 18 BPL CLAIM ;[no escape, ALWAYS jump] 0402 FB0E ; 0403 FB0E ; escape condition 0404 FB0E ; 0405 FB0E 60 RTS 0406 FB0F 0407 FB0F 0408 FB0F A5 E3 SETSDF LDA OPTS ;Set options for sequential access 0409 FB11 0A ASLA ;=> bottom nybble of OPTS 0410 FB12 0A ASLA 0411 FB13 0A ASLA 0412 FB14 0A ASLA 0413 FB15 85 BB STA USFLGS 0414 FB17 AD D1 03 LDA SEQGAP ;Set (variable) PUTBYTE gap time 0415 FB1A D0 08 BNE GAPOUT ;[ALWAYS JUMP] 0416 FB1C ; 0417 FB1C A5 E3 SETDEF LDA OPTS 0418 FB1E 29 F0 ANDIM &F0 ;Chop out seq. opts 0419 FB20 85 BB STA USFLGS ;Set options for load/save operation 0420 FB22 [ GLYN =0 ;If special system for glyn 0422 FB22 | 0423 FB22 A9 06 LDAIM GAP ;Set SAVE gap -> unchangeable 0424 FB24 ] 0425 FB24 85 C7 GAPOUT STA GAPTIM 0426 FB26 ; 0427 FB26 ; fall thru into CLAIM 0428 FB26 ; 0429 FB26 CLAIM 0430 FB26 ; Claim RS423 h/w interface 0431 FB26 ; Called by CFS 0432 FB26 58 CLI 0433 FB27 08 PHP 0434 FB28 78 SEI 0435 FB29 2C 4F 02 BIT RSFLAG 0436 FB2C 10 DB BPL RSWT1 ;[RS423 busy] 0437 FB2E A5 EA LDA RSTUT 0438 FB30 30 D7 BMI RSWT1 ;[RS423 dormant, but still timing out] 0439 FB32 ; RS423 dormant and timed out OR claimed => RS423 available 0440 FB32 ; RSTUT>=0 0441 FB32 ; headline: 'CFS Claims RS423' 0442 FB32 A9 01 LDAIM &01 ;allow for many call claims 0443 FB34 85 EA STA RSTUT ;RSTUT := 1 0444 FB36 0445 FB36 [ &00=0 0446 FB36 20 3B FB JSR CRESET 0447 FB39 28 PLP 0448 FB3A 60 RTS 0449 FB3B | 0452 FB3B ] 0453 FB3B 0454 FB3B 0455 FB3B A9 03 CRESET LDAIM &03 0456 FB3D D0 1B BNE SETCHP 0457 FB3F 0458 FB3F 0459 FB3F TXINIT 0460 FB3F A9 30 LDAIM TXSTAT 0461 FB41 85 CA STA TXFLAG 0462 FB43 D0 13 BNE CHPINT 0463 FB45 0464 FB45 A9 05 RXINIT LDAIM SEROFF 0465 FB47 0466 FB47 ;Switch motor off without going through OS 0467 FB47 ;coz don't want user to be bothered with each 0468 FB47 ;motor blip 0469 FB47 0470 FB47 8D 10 FE STA SERPRC 0471 FB4A 0472 FB4A A2 FF LDXIM &FF ;250 * 2.5 usecs = 1 millisec 0473 FB4C CA RXINL1 DEX 0474 FB4D D0 FD BNE RXINL1 0475 FB4F 86 CA STX TXFLAG 0476 FB51 0477 FB51 A9 85 LDAIM SERON 0478 FB53 8D 10 FE STA SERPRC ;Motor on again 0479 FB56 0480 FB56 A9 D0 LDAIM RXSTAT 0481 FB58 05 C6 CHPINT ORA SPEED ;Put in bottom bit, set in INIT from MOS 0482 FB5A 8D 08 FE SETCHP STA STATUS 0483 FB5D 60 RTS 0484 FB5E 0485 FB5E 0486 FB5E AE C6 03 NXTBLK LDX INFO +BKNOLO 0487 FB61 AC C7 03 LDY INFO +BKNOHI 0488 FB64 E8 INX 0489 FB65 86 B4 STX BLOKNO 0490 FB67 D0 01 BNE NXTBLX 0491 FB69 C8 INY 0492 FB6A 84 B5 NXTBLX STY BLOKNO +&01 0493 FB6C 60 RTS 0494 FB6D 0495 FB6D A0 00 SETJOB LDYIM &00 0496 FB6F 84 C0 STY IFLAG 0497 FB71 [ MOS125 = &FF Acorn macro assembler Page 144 C.F.S. - I/O Utilities -> MOS76 0499 FB71 | 0500 FB71 A0 00 SETJB1 LDYIM &00 0501 FB73 84 BE STY CHKSUM 0502 FB75 ] 0503 FB75 84 BF STY CHKSUM +&01 0504 FB77 60 RTS 0505 FB78 0506 FB78 0507 FB78 A0 FF MOVFN LDYIM &FF 0508 FB7A C8 MOVFNL INY 0509 FB7B E8 INX 0510 FB7C BD 00 03 LDAAX VARPGE 0511 FB7F 99 D2 03 STAAY FILNAM 0512 FB82 D0 F6 BNE MOVFNL 0513 FB84 60 RTS 0514 FB85 0515 FB85 0516 FB85 A0 00 MOTONW LDYIM WRITFX ;Motor on for output 0517 FB87 58 MOTON CLI ;Ensure can talk to tape 0518 FB88 A2 01 LDXIM &01 ;Motor on 0519 FB8A 84 C3 STY CURDRV ;Store current drive 0520 FB8C A9 89 CMOTOR LDAIM FXMOTR ;=> motor function 0521 FB8E 0522 FB8E ;Load drive number into Y, so switching motor 0523 FB8E ;off is always done with the drive most recently 0524 FB8E ;switched on (seems logical). 0525 FB8E 0526 FB8E A4 C3 LDY CURDRV 0527 FB90 4C F4 FF JMP OSBYTE 0528 FB93 0529 FB93 CHKHND 0530 FB93 0531 FB93 ;Check handle in Y is open 0532 FB93 ;and corresponds to mask in A 0533 FB93 0534 FB93 [ MOS125 = &FF 0548 FB93 | 0549 FB93 ;squash and bugfix: Y=0 not accepted by RFS when OUTHND open in CFS 0550 FB93 25 E2 AND CFSTAT 0551 FB95 C0 02 CPYIM OUTHND 0552 FB97 D0 02 BNE CHKHN1 0553 FB99 4A LSRA 0554 FB9A 88 DEY 0555 FB9B CHKHN1 0556 FB9B 88 DEY 0557 FB9C CC 47 02 CPY SROMSW 0558 FB9F D0 03 BNE HNDERR 0559 FBA1 4A LSRA 0560 FBA2 B0 4D BCS CHKHXX 0561 FBA4 ] 0562 FBA4 0563 FBA4 0564 FBA4 00 HNDERR BRK 0565 FBA5 DE = CFSERB 0566 FBA6 43 68 61 = "Channel",0 0567 FBAE 0568 FBAE 0569 FBAE 0570 FBAE TWINIT 0571 FBAE A9 01 LDAIM TUBEW ;Write init. for tube 0572 FBB0 TBINIT 0573 FBB0 ;Check the address at BKADDR is accross tube 0574 FBB0 ;and that tube is present. If so, claim tube, and call 0575 FBB0 ;address routine with value origionally in A on entry. 0576 FBB0 0577 FBB0 20 C6 FB JSR TUBCHK ;Check address + tube present. 0578 FBB3 F0 3C BEQ TINIT0 ;Don't tube. (NOTE TAX done in TUBCHK) 0579 FBB5 8A TXA ;Restore tube reason code 0580 FBB6 A2 B0 LDXIM BKADDR 0581 FBB8 A0 00 LDYIM /(BKADDR ) ;Address for tube routine 0582 FBBA 48 TBINT1 PHA ;Entry from RUN with non-BKADDR address 0583 FBBB A9 C0 LDAIM TUBECL ;"Claim" reason code 0584 FBBD 20 06 04 TUBELP JSR TBADDR ;Attempt claim 0585 FBC0 90 FB BCC TUBELP ;Continue to try and claim 0586 FBC2 68 PLA ;Restore address reason code 0587 FBC3 4C 06 04 JMP TBADDR 0588 FBC6 0589 FBC6 0590 FBC6 0591 FBC6 AA TUBCHK TAX ;Store A 0592 FBC7 A5 B2 LDA BKADDR +&02 0593 FBC9 25 B3 AND BKADDR +&03 0594 FBCB C9 FF CMPIM &FF ;If $FF, address is IO proc., so exit 0595 FBCD F0 05 BEQ TUBCHX 0596 FBCF AD 7A 02 LDA TUBE 0597 FBD2 29 80 ANDIM &80 ;Returns NZ if tube present, EQ if not 0598 FBD4 60 TUBCHX RTS 0599 FBD5 0600 FBD5 0601 FBD5 0602 FBD5 BUGFIX 0603 FBD5 0604 FBD5 ;When the 6850 counter divide bits are reset, it 0605 FBD5 ;is possible for the SERPROC to get out of synch. 0606 FBD5 ;for a few bits. This has the effect of corrupting 0607 FBD5 ;the first character of the first block of a SAVE, 0608 FBD5 ;or the first character of ANY block during sequential 0609 FBD5 ;access (since the 6850 is reset for every block 0610 FBD5 ;during putbytes). 0611 FBD5 ; The cure is to write a dummy byte to tape at the 0612 FBD5 ;start of a SAVE, and at the start of every block 0613 FBD5 ;during putbytes. This must be done by polling, 0614 FBD5 ;since there must be a period of high-tone after 0615 FBD5 ;the dummy byte, which is difficult to accomplish 0616 FBD5 ;if the 6850 is interrupting all the time. 0617 FBD5 ; BUGFIX is thus called after the SERPROC is set 0618 FBD5 ;and before the 6850 is set to interrupt during 0619 FBD5 ;a block write operation. 0620 FBD5 0621 FBD5 A9 85 LDAIM SERON 0622 FBD7 8D 10 FE STA SERPRC ;Set SERPROC on 0623 FBDA 20 3B FB JSR CRESET ;Reset 6850 to be on safe side 0624 FBDD A9 10 LDAIM &10 0625 FBDF 20 58 FB JSR CHPINT ;Set 6850 at appropriate clock rate 0626 FBE2 0627 FBE2 20 8B F9 BUGLP JSR ESCAPE 0628 FBE5 AD 08 FE LDA STATUS 0629 FBE8 29 02 ANDIM &02 ;Ready to TX ? 0630 FBEA F0 F6 BEQ BUGLP ;Nope -> loop 0631 FBEC A9 AA LDAIM &AA 0632 FBEE 8D 09 FE STA PORT ;Shove out the dummy byte Acorn macro assembler Page 145 C.F.S. - I/O Utilities -> MOS76 0633 FBF1 CHKHXX 0634 FBF1 TINIT0 0635 FBF1 60 RTS 0636 FBF2 0637 FBF2 [ MOS125 = &FF 0638 FBF2 | 0639 FBF2 ;FSC jump table moved to end of main section. 0640 FBF2 ;This displaces the free space into the middle 0641 FBF2 ;of the ROM where it can be used for any purpose 0642 FBF2 ;(an opcode or branch address at &FBFF would cause 0643 FBF2 ;a dummy read cycle in FRED.) 0644 FBF2 0645 FBF2 JMPTAB 0646 FBF2 94 = CFSOPT-&01 0647 FBF3 50 = CFSEOF-&01 0648 FBF4 EE = RUN-&01 ;"*." 0649 FBF5 76 = MBDCMD-&01 ;"*" = Bad command 0650 FBF6 EE = RUN-&01 ;"*RUN " 0651 FBF7 2D = CAT-&01 0652 FBF8 F2 = SHUTES-&01 ;die 0653 FBF9 0007 NOTAB * .-JMPTAB 0654 FBF9 F5 = /(CFSOPT-&01) 0655 FBFA F6 = /(CFSEOF-&01) 0656 FBFB F2 = /(RUN-&01) 0657 FBFC E3 = /(MBDCMD-&01) 0658 FBFD F2 = /(RUN-&01) 0659 FBFE F3 = /(CAT-&01) 0660 FBFF E2 = /(SHUTES-&01) 0661 FC00 0662 FC00 ;MOS 1.25: Adjust padding in MOS38 to hit &FC00 here 0663 FC00 ] 0664 FC00 0665 FC00 END 0666 FC00 0667 FC00 [ $Tutu 0669 FC00 ] 0670 FC00 0671 FC00 ; pad with zero bytes to ensure ROM CRCs consistent 0672 FC00 00 00 00 % &100 0673 FD00 0674 FD00 [ . > &FC00+&100 0676 FD00 ] 0677 FD00 0678 FD00 < 1 0679 FD00 0680 FD00 LNK MOS99 0001 FD00 ; MOS99 0002 FD00 TTL MOS99 Operating system ROM entry points and hardware vectors 0003 FD00 OPT MOS99 Acorn macro assembler Page 146 MOS99 Operating system ROM entry points and hardware vectors 0004 FD00 0005 FD00 ;(c) 1981 ACORN Computers Limited 0006 FD00 ;BBC Microcomputer Machine Operating System (MOS) 0007 FD00 0008 FD00 ;Change record: 0009 FD00 0010 FD00 ;Author(s): 0011 FD00 ;PB Paul Bond 0012 FD00 0013 FD00 ORG &FC00 0014 FC00 0015 FC00 28 43 29 = "(C) 1981 Acorn Computers Ltd." 0016 FC1D 54 68 61 = "Thanks are due to the following contributors to the development of the BBC Computer " 0017 FC71 28 61 6D = "(among others too numerous to mention):- " 0018 FC9A 44 61 76 = "David Allen," 0019 FCA6 42 6F 62 = "Bob Austin," 0020 FCB1 52 61 6D = "Ram Banerjee," 0021 FCBE 50 61 75 = "Paul Bond," 0022 FCC8 41 6C 6C = "Allen Boothroyd," 0023 FCD8 43 61 6D = "Cambridge," 0024 FCE2 43 6C 65 = "Cleartone," 0025 FCEC 4A 6F 68 = "John Coll," 0026 FCF6 4A 6F 68 = "John Cox," 0027 FCFF 41 6E 64 = "Andy Cripps," 0028 FD0B 43 68 72 = "Chris Curry," 0029 FD17 36 35 30 = "6502 designers," 0030 FD26 4A 65 72 = "Jeremy Dion," 0031 FD32 54 69 6D = "Tim Dobson," 0032 FD3D 4A 6F 65 = "Joe Dunn," 0033 FD46 50 61 75 = "Paul Farrell," 0034 FD53 46 65 72 = "Ferranti," 0035 FD5C 53 74 65 = "Steve Furber," 0036 FD69 4A 6F 6E = "Jon Gibbons," 0037 FD75 41 6E 64 = "Andrew Gordon," 0038 FD83 4C 61 77 = "Lawrence Hardwick," 0039 FD95 44 79 6C = "Dylan Harris," 0040 FDA2 48 65 72 = "Hermann Hauser," 0041 FDB1 48 69 74 = "Hitachi," 0042 FDB9 41 6E 64 = "Andy Hopper," 0043 FDC5 49 43 4C = "ICL," 0044 FDC9 4D 61 72 = "Martin Jackson," 0045 FDD8 42 72 69 = "Brian Jones," 0046 FDE4 43 68 72 = "Chris Jordan," 0047 FDF1 44 61 76 = "David King," 0048 FDFC 44 61 76 = "David Kitson," 0049 FE09 50 61 75 = "Paul Kriwaczek," 0050 FE18 43 6F 6D = "Computer Laboratory," 0051 FE2C 50 65 74 = "Peter Miller," 0052 FE39 41 72 74 = "Arthur Norman," 0053 FE47 47 6C 79 = "Glyn Phillips," 0054 FE55 4D 69 6B = "Mike Prees," 0055 FE60 4A 6F 68 = "John Radcliffe," 0056 FE6F 57 69 6C = "Wilberforce Road," 0057 FE80 50 65 74 = "Peter Robinson," 0058 FE8F 52 69 63 = "Richard Russell," 0059 FE9F 4B 69 6D = "Kim Spence-Jones," 0060 FEB0 47 72 61 = "Graham Tebby," 0061 FEBD 4A 6F 6E = "Jon Thackray," 0062 FECA 43 68 72 = "Chris Turner," 0063 FED7 41 64 72 = "Adrian Warner," 0064 FEE5 52 6F 67 = "Roger Wilson," 0065 FEF2 41 6C 61 = "Alan Wright." 0066 FEFE ; 0067 FEFE ; test ROM indirection 0068 FEFE 5D = MRESET 0069 FEFF D9 = /(MRESET ) 0070 FF00 0071 FF00 ; ORG $FF00 0072 FF00 ; Page $FF contains code which has to be located at a fixed 0073 FF00 ; place in memory. Two main types of code come into this 0074 FF00 ; category: 0075 FF00 ; (a) Code to call a routine located in a paged ROM 0076 FF00 ; (b) Fixed OS calls 0077 FF00 0078 FF00 ; Calls to the operating system are normally made by calling 0079 FF00 ; JMIs located at the top of the address space of the m/c. 0080 FF00 ; The indirection vectors are located in page 2 starting at 0081 FF00 ; $0200. To redirect an OS call which indirects thru location 0082 FF00 ; $0200+2*x: 0083 FF00 ; (a) Set up a 3-byte tuple at location ROMVEC+3*x to refer 0084 FF00 ; to the paged ROM entry point 0085 FF00 ; (b) Set the OS indirection at location $0200+2*x to value 0086 FF00 ; $FF00+3*x 0087 FF00 ; A JMI $0200+2*x will then result in the routine in paged ROM 0088 FF00 ; being called. The routine is entered with A, X, Y and P 0089 FF00 ; unaltered since the point of call. Similarly, no registers 0090 FF00 ; are corrupted on return from the routine. 0091 FF00 ; 0092 FF00 ; Locations $FF00 onwards contain JSRs to the same location (OSROM); 0093 FF00 ; thus when OSROM is entered the top entry on the stack determines 0094 FF00 ; which JSR OSROM was called, enabling the OS call made to be 0095 FF00 ; identified (by convention paged ROM routed indirections thru 0096 FF00 ; $0200+2*x jump to location $FF00+3*x). 0097 FF00 0098 FF00 ROMUSR 0099 FF00 20 92 FF JSR OSROM 0100 FF03 0101 FF03 ROMBRK 0102 FF03 20 92 FF JSR OSROM 0103 FF06 0104 FF06 ROMIRA 0105 FF06 20 92 FF JSR OSROM 0106 FF09 0107 FF09 ROMIRB 0108 FF09 20 92 FF JSR OSROM 0109 FF0C 0110 FF0C ROMCOM 0111 FF0C 20 92 FF JSR OSROM 0112 FF0F 0113 FF0F ROMBYT 0114 FF0F 20 92 FF JSR OSROM 0115 FF12 0116 FF12 ROMWRD 0117 FF12 20 92 FF JSR OSROM 0118 FF15 0119 FF15 ROMWRC 0120 FF15 20 92 FF JSR OSROM 0121 FF18 0122 FF18 ROMRDC 0123 FF18 20 92 FF JSR OSROM 0124 FF1B Acorn macro assembler Page 147 MOS99 Operating system ROM entry points and hardware vectors 0125 FF1B ROMFIL 0126 FF1B 20 92 FF JSR OSROM 0127 FF1E 0128 FF1E ROMARG 0129 FF1E 20 92 FF JSR OSROM 0130 FF21 0131 FF21 ROMBGT 0132 FF21 20 92 FF JSR OSROM 0133 FF24 0134 FF24 ROMBPT 0135 FF24 20 92 FF JSR OSROM 0136 FF27 0137 FF27 ROMGPB 0138 FF27 20 92 FF JSR OSROM 0139 FF2A 0140 FF2A ROMFND 0141 FF2A 20 92 FF JSR OSROM 0142 FF2D 0143 FF2D ROMFSC 0144 FF2D 20 92 FF JSR OSROM 0145 FF30 0146 FF30 ROMEVT 0147 FF30 20 92 FF JSR OSROM 0148 FF33 0149 FF33 ROMUPT 0150 FF33 20 92 FF JSR OSROM 0151 FF36 0152 FF36 ROMNET 0153 FF36 20 92 FF JSR OSROM 0154 FF39 0155 FF39 ROMVDU 0156 FF39 20 92 FF JSR OSROM 0157 FF3C 0158 FF3C ROMKEY 0159 FF3C 20 92 FF JSR OSROM 0160 FF3F 0161 FF3F ROMINS 0162 FF3F 20 92 FF JSR OSROM 0163 FF42 0164 FF42 ROMREM 0165 FF42 20 92 FF JSR OSROM 0166 FF45 0167 FF45 ROMCNP 0168 FF45 20 92 FF JSR OSROM 0169 FF48 0170 FF48 20 92 FF JSR OSROM 0171 FF4B 0172 FF4B 20 92 FF JSR OSROM 0173 FF4E 0174 FF4E 20 92 FF JSR OSROM 0175 FF51 0176 FF51 [ MOS125 = &FF 0276 FF51 ] 0277 FF51 0278 FF51 [ MOS125 = &7F 0279 FF51 [ STARGO = &00 0280 FF51 00 % 1 ;1 byte padding 0281 FF52 0282 FF52 ARGSW 0283 FF52 C9 01 CMPIM &01 0284 FF54 D0 0D BNE UPARGS 0285 FF56 C0 00 CPYIM &00 0286 FF58 D0 09 BNE UPARGS 0287 FF5A AC D1 02 LDY TAILHI ;OSARGS A=1, Y=0 return command line tail 0288 FF5D F0 04 BEQ UPARGS ;return *GO/CFS pointer if valid 0289 FF5F 88 DEY 0290 FF60 4C A1 DF JMP RETAIL 0291 FF63 UPARGS ;call upstream OSARGS 0292 FF63 6C 14 02 JMI ARGVEC 0293 FF66 | 0295 FF66 ] 0296 FF66 FXBPUT ;FX entry, C=1 0297 FF66 8A TXA ;A = character 0298 FF67 B0 6B BCS OSBPUT ;[ALWAYS jump] 0299 FF69 ] 0300 FF69 0301 FF69 [ MOS125 = &00 0303 FF69 ] 0304 FF69 0305 FF69 [ MOS125 = &FF 0306 FF69 | 0307 FF69 48 FUDGE PHA 0308 FF6A 48 PHA 0309 FF6B 08 PHP 0310 FF6C 48 PHA 0311 FF6D 8A TXA 0312 FF6E 48 PHA 0313 FF6F 98 TYA 0314 FF70 48 PHA 0315 FF71 BA TSX ;y x a p a a 88 FF el eh cl ch 0316 FF72 BC 09 01 LDYAX &0109 ;get vector offset+2 0317 FF75 B9 9D 0D LDAAY ROMVEC-&02+&00 0318 FF78 9D 05 01 STAAX &0105 ;copy LSB vector over placeholder 0319 FF7B B9 9E 0D LDAAY ROMVEC-&02+&01 0320 FF7E 9D 06 01 STAAX &0106 ;copy MSB vector over placeholder 0321 FF81 A5 F4 LDA ROMID ;copy ROM slot over MSB vector offset 0322 FF83 9D 0A 01 STAAX &010A ;y x a p vl vh 88 FF el r cl ch 0323 FF86 68 PLA ;Y in A ready to restore 0324 FF87 BE 9F 0D LDXAY ROMVEC-&02+&02 ;get vector ROM slot 0325 FF8A A8 TAY ;restore Y 0326 FF8B 68 PLA ;X in A ready to restore 0327 FF8C 20 D9 DB JSR STXROM ;set destination ROM slot 0328 FF8F AA TAX ;restore X 0329 FF90 68 PLA ;restore A 0330 FF91 40 RTI ;restore P and jump to vector 0331 FF92 0332 FF92 20 69 FF OSROM JSR FUDGE ;push restore address on stack, RTS returns below 0333 FF95 ;routine to restore ROM slot from indirection 0334 FF95 08 PHP 0335 FF96 48 PHA 0336 FF97 8A TXA 0337 FF98 48 PHA 0338 FF99 BA TSX ;x a p el r cl ch 0339 FF9A BD 05 01 LDAAX &0105 0340 FF9D 85 F4 STA ROMID 0341 FF9F 8D 30 FE STA ROM ;restore ROM slot 0342 FFA2 BD 03 01 LDAAX &0103 0343 FFA5 9D 04 01 STAAX &0104 0344 FFA8 9D 05 01 STAAX &0105 ;copy status over vec offset and ROM slot 0345 FFAB 68 PLA 0346 FFAC AA TAX ;restore X Acorn macro assembler Page 148 MOS99 Operating system ROM entry points and hardware vectors 0347 FFAD 68 PLA ;restore A 0348 FFAE 28 PLP 0349 FFAF 28 PLP 0350 FFB0 28 PLP ;restore status (and discard 2 copies) 0351 FFB1 VINUSE ;target of vectors in use by a client waiting for a server 0352 FFB1 EA NOP 0353 FFB2 DEFEVT ;default EVENT routine 0354 FFB2 DEFUPT ;default user print routine (simulate printer busy) 0355 FFB2 DEFNET ;default net routine (simulate printer busy) 0356 FFB2 RTS 0357 FFB2 60 RTS 0358 FFB3 ] 0359 FFB3 0360 FFB3 [ MOS125 = &7F 0361 FFB3 ;FXBPUT gives up its place to OSWRSC 0362 FFB3 ;to keep VINUSE and RTS in the same place 0363 FFB3 | 0367 FFB3 ] 0368 FFB3 0369 FFB3 [ MOS125 = &FF 0381 FFB3 ] 0382 FFB3 0383 FFB3 [ MOS125 = &7F 0384 FFB3 4C 1C D1 OSWRSC JMP WRSC 0385 FFB6 ] 0386 FFB6 0387 FFB6 ; security copy of indirection data 0388 FFB6 36 = VLEN 0389 FFB7 D0 = IPAGE2 0390 FFB8 D8 = /(IPAGE2 ) 0391 FFB9 ; 0392 FFB9 4C CE DB JMP RPROM ;read byte from paged ROM 0393 FFBC 4C C0 C4 JMP VDU ;raw VDU WRCH (corrupts A, X and Y) 0394 FFBF 4C FA E4 JMP EVENT ;signal event 0395 FFC2 4C 83 EA JMP GSINTS ;used by paged ROMs 0396 FFC5 4C 94 EA JMP GSREAD ;used by paged ROMs 0397 FFC8 4C 6F DE JMP RDCH ;used by tube 0398 FFCB 4C 03 E1 JMP WRCH ;used by tube 0399 FFCE 6C 1C 02 OSFIND JMI FNDVEC 0400 FFD1 0401 FFD1 6C 1A 02 OSBGPB JMI GPBVEC 0402 FFD4 6C 18 02 OSBPUT JMI BPTVEC 0403 FFD7 6C 16 02 OSBGET JMI BGTVEC 0404 FFDA [ MOS125 = &7F 0405 FFDA [ STARGO = &00 0406 FFDA 4C 52 FF OSARGS JMP ARGSW 0407 FFDD | 0409 FFDD ] 0410 FFDD | 0412 FFDD ] 0413 FFDD 6C 12 02 OSFILE JMI FILVEC 0414 FFE0 6C 10 02 OSRDCH JMI RDCVEC 0415 FFE3 C9 0D OSASCI CMPIM MCR 0416 FFE5 D0 07 BNE OSWRCH 0417 FFE7 A9 0A OSNEWL LDAIM MLF 0418 FFE9 20 EE FF JSR OSWRCH 0419 FFEC [ MOS125 = &FF 0420 FFEC | 0421 FFEC WRCR 0422 FFEC ] 0423 FFEC A9 0D LDAIM MCR 0424 FFEE 6C 0E 02 OSWRCH JMI WRCVEC 0425 FFF1 6C 0C 02 OSWORD JMI WORVEC 0426 FFF4 6C 0A 02 OSBYTE JMI BYTVEC 0427 FFF7 6C 08 02 OSCLI JMI COMVEC 0428 FFFA 0429 FFFA ; hardware vectors 0430 FFFA 00 = NMI ;non-maskable interrupt 0431 FFFB 0D = /(NMI ) 0432 FFFC 5D = MRESET ;hardware reset 0433 FFFD D9 = /(MRESET ) 0434 FFFE DF = IRQ ;interrupt 0435 FFFF DB = /(IRQ ) 0436 0000 ENDROM ;end of ROM 0437 0000 0438 0000 [ ENDROM=0 0439 0000 | 0441 0000 ] 0442 0000 0443 0000 TTL BBC Microcomputer Machine Operating System (MOS) 0444 0000 0445 0000 OPT OPPON 0446 0000 0447 0000 END Assembly finished, no errors Action : *spool This Perl script creates the slack columns from the raw listing. Copy the text between the cut lines. Paste it into a new file, slack.pl, and remove the first 30 characters from each line. Then call it with perl slack.pl stargo.asm.txt >stargo-slack.txt -------->8--- #!/usr/bin/perl $base=0xc000; @slack = (0x80) x 0x4001; open(ASM,'<'.shift(@ARGV))or die; while(){ y/ -~//cd; if(/^Action :\s*asm\s+([A-Z0-9._-]+)/i) { $file=sprintf("%-7s",$1); } elsif(/^[0-9A-F]{4} [0-9A-F]{4} ...... LNK\s+([A-Z0-9._-]+)\s*$/) { $file=sprintf("%-7s",$1); # Link filename not held over as LNK lines do not assemble instructions. } elsif(/^([0-9A-F]{4}) ([0-9A-F]{4}) .. .. .. /) { $line=$1; $pc=hex($2); $label[$pc-$base] = $file.' '.$line.' '.$2 if $pc >= $base; } if(/^([0-9A-F]{4}) ([0-9A-F]{4}) [13579BDF]0 ([0-9A-F]{2}) ...... B/){ $line=$1; $pc=hex($2); $op=hex($3); if($op & 0x80) { $dest = $pc + 2 - 0x100 + $op; $slack = $op - 0x80; for($i = $pc + 2 - $base + $op - 0xFF; $i <= $pc - $base; ++$i) { if($slack[$i] > $slack) { $slack[$i] = $slack; $source[$i] = $pc-$base; } } } else { $dest = $pc + 2 + $op; $slack = 0x7f - $op; for($i = $pc + 2 - $base; $i <= $pc + 2 - $base + $op; ++$i) { if($slack[$i] > $slack) { $slack[$i] = $slack; $source[$i] = $pc-$base; } } } } } undef $file; undef $link; seek(ASM,0,0); while(){ y/ -~//cd; if(/^Action :\s*asm\s+([A-Z0-9._-]+)/i) { $link=sprintf("%-7s",$1); } elsif(/^[0-9A-F]{4} [0-9A-F]{4} ...... LNK\s+([A-Z0-9._-]+)\s*$/) { $link=sprintf("%-7s",$1); } elsif(/^[0-9A-F]{4} [0-9A-F]{4} ...... END\s*$/) { $link=sprintf("%-7s",""); } if(/^([0-9A-F]{4}) ([0-9A-F]{4})(.*)$/) { $line=$1; $pc=hex($2); $source=$3; if($pc>=$base && $slack[$pc-$base] < 0x80) { printf("%-17s %s%02X %-7s %s\n", (($pc>=$base && defined($source[$pc-$base]) && defined($label[$source[$pc-$base]])) ? $label[$source[$pc-$base]] : ''), (($source[$pc-$base] < $pc-$base) ? 'v' : '^'), $slack[$pc-$base], $file, $_); } else { printf(" -- %-7s %s\n", $file, $_); } } else { printf(" %-7s %s\n", $file, $_); } if(defined($link)) { $file=$link; undef $link; } } -------->8--- End of stargo-slack.txt