BBC Operating System OS 1.20 ============================ Assembly listing generated by TurboMASM from the original Acorn source. Source: https://www.4corn.co.uk/articles/65hostandmos/ Source: https://github.com/stardot/AcornOS120 Branch slack calculated by Greg Cook with slack.pl (attached), 16 September 2023 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 MOSHdr Macro library : Acorn macro assembler Page 1 Pass 1 Pass 2 0001 0000 ; > MOSHdr 0002 0000 0003 0000 GBLL $Tutu 0004 0000 $Tutu SETL 1=0 0005 0000 0006 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 1D CB 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 11 JTBLO = ACK ;Points to an RTS 0136 C334 3B = SOH 0137 C335 96 = STX 0138 C336 A1 = ETX 0139 C337 AD = EOT 0140 C338 B9 = ENQ 0141 C339 11 = ACK 0142 C33A 6F = BELL 0143 C33B C5 = BS 0144 C33C 64 = HT 0145 C33D F0 = LF 0146 C33E 5B = VT 0147 C33F 59 = FF 0148 C340 AF = CR 0149 C341 8D = SO 0150 C342 A6 = SI 0151 C343 C0 = DLE 0152 C344 F9 = DCA 0153 C345 FD = DCB 0154 C346 92 = DCC 0155 C347 39 = DCD 0156 C348 9B = NAK 0157 C349 EB = SYN 0158 C34A F1 = ETB 0159 C34B 39 = CAN 0160 C34C 8C = EM 0161 C34D BD = SUB 0162 C34E 11 = ACK ;Points to an RTS 0163 C34F FA = FS 0164 C350 A2 = GS 0165 C351 79 = RS 0166 C352 87 = US 0167 C353 AC = 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 4F = DCA:SHR:&8-CODORG:SHL:&4+&10-&1 ;Queue 1 byte (DCA) 0192 C366 4E = 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 CA = /(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 02 CLSCTA = CLASCA ;(LSB) 0529 C455 32 = CLASCB 0530 C456 7A = CLASCC 0531 C457 92 = CLASCD 0532 C458 E6 = 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 86 D1JTB = EA 0663 C4AB D3 = /(EA ) 0664 C4AC 7E = NA 0665 C4AD D3 = /(NA ) 0666 C4AE 0667 C4AE 6A D2JTBL = EB 0668 C4AF 74 = WB 0669 C4B0 42 = NB 0670 C4B1 4B = 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 4D 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 68 C5 JSR CSWAP ;Yes?, then swap cursors 0021 C4CC 20 6A 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 18 D9 JSR CSEDEX ;Yes?, then exit C.E. mode 0026 C4D8 C9 7F NOTCEA CMPIM &7F ;No?, then form vector 0027 C4DA F0 11 BEQ ISDEL 0028 C4DC C9 20 CMPIM &20 0029 C4DE 90 0F 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 B7 CF JSR VDUPR ;No?, then print to VDU 0033 C4E7 20 64 C6 JSR HT 0034 C4EA 4C 5E C5 NOTC20 JMP CSWDEX ;& ditto 0035 C4ED 0036 C4ED A9 20 ISDEL LDAIM &20 ;(Form correct index for DEL) 0037 C4EF 0038 C4EF A8 NOTDEL TAY 0039 C4F0 B9 33 C3 LDAAY JTBLO ;Get LSByte of jump vector 0040 C4F3 8D 5D 03 STA JVEC 0041 C4F6 B9 54 C3 LDAAY JTBHI ;Get MSByte 0042 C4F9 30 4A BMI REXEC ;No Qing required, so execute routine 0043 C4FB AA TAX ;b7=0, so Q needed - set it up 0044 C4FC 09 F0 ORAIM &F0 ;2's comp. of no. of bytes to Q 0045 C4FE 8D 6A 02 STA QPOSN 0046 C501 8A TXA ;Generate MSByte of address - MSNybble, plus CODORG 0047 C502 4A LSRA 0048 C503 4A LSRA 0049 C504 4A LSRA 0050 C505 4A LSRA 0051 C506 18 CLC 0052 C507 69 C3 ADCIM CODORG ;Forms the high byte of the vector 0053 C509 8D 5E 03 STA JVEC +&01 0054 C50C 24 D0 BIT STATS ;Swap back again if C.E. 0055 C50E 70 1F BVS NOTC10 0056 C510 18 CLC 0057 C511 60 ACK RTS ;NUL points at this to save a byte 0058 C512 0059 C512 0060 C512 9D 24 02 QING STAAX QEND-&FF ;Q the byte 0061 C515 E8 INX 0062 C516 8E 6A 02 STX QPOSN ;(z preserved from INX) 0063 C519 D0 17 BNE CLCEX ;More to do?, then exit 0064 C51B 24 D0 BIT STATS ;Disabled?, then go away 0065 C51D 30 15 BMI DISABL 0066 C51F 70 05 BVS NOTCEB ;C.E. mode, then do swapping 0067 C521 20 F5 CC JSR RUNNER 0068 C524 18 CLC 0069 C525 60 RTS 0070 C526 0071 C526 20 68 C5 NOTCEB JSR CSWAP 0072 C529 20 6A CD JSR OCSRDL 0073 C52C 20 F5 CC JSR RUNNER 0074 C52F 20 65 C5 NOTC10 JSR REXE10 0075 C532 18 CLCEX CLC 0076 C533 60 RTS 0077 C534 0078 C534 AC 5E 03 DISABL LDY JVEC +&01 ;Was this an SOH ? 0079 C537 C0 C5 CPYIM /(SOH ) 0080 C539 D0 F7 BNE CLCEX ;No?, then go home 0081 C53B 0082 C53B AA SOH TAX ;Yes, then (A)=Byte to be printed 0083 C53C A5 D0 LDA STATS ;Is printing enabled ? 0084 C53E 4A LSRA 0085 C53F 90 D0 BCC ACK 0086 C541 8A TXA 0087 C542 4C 1E E1 JMP PRINT ;print character and return, setting c=0 (done by MOS) 0088 C545 0089 C545 REXEC 0090 C545 8D 5E 03 STA JVEC +&01 0091 C548 98 TYA ;Is it range $08 to $0D ? (no longer include bell) 0092 C549 C9 08 CMPIM &08 0093 C54B 90 06 BCC REXECZ ;Set c if so 0094 C54D 49 FF EORIM &FF 0095 C54F C9 F2 CMPIM &F2 0096 C551 49 FF EORIM &FF 0097 C553 REXECZ 0098 C553 ; 0099 C553 24 D0 BIT STATS ;Execute routine - are we disabled ? 0100 C555 30 29 BMI ACKQ ;Was it an ACK? (can't be an SOH cos she queues) 0101 C557 ; 0102 C557 08 PHP ;and push c 0103 C558 20 F5 CC JSR RUNNER ;Do the routine 0104 C55B 28 PLP 0105 C55C 90 03 BCC REXECB ;Not in range 8 to $D, so not don't print it 0106 C55E A5 D0 CSWDEX LDA STATS ;Is printer module on? 0107 C560 4A LSRA ;c=1 if so 0108 C561 24 D0 REXECB BIT STATS ;Following preserves c 0109 C563 50 AC BVC ACK ;Not C.E. so exit 0110 C565 20 7A CD REXE10 JSR OCSRWR ;Write output cursor 0111 C568 0112 C568 ;CSWAP - swap input and output text cursors 0113 C568 ; invert b1 of STATS 0114 C568 0115 C568 08 CSWAP PHP ;Preserve carry 0116 C569 48 PHA 0117 C56A A2 18 LDXIM CSX-V 0118 C56C A0 64 LDYIM PCSX-V 0119 C56E 20 DE CD JSR SWAP2 0120 C571 20 06 CF JSR TADDRY ;Address this point 0121 C574 20 02 CA JSR CSDSP 0122 C577 A5 D0 LDA STATS 0123 C579 49 02 EORIM &02 ;Invert bit 1 of STATS 0124 C57B 85 D0 STA STATS Acorn macro assembler Page 11 VDU File - MOS02 0125 C57D 68 PLA 0126 C57E 28 PLP ;Restore c 0127 C57F 60 RTS 0128 C580 0129 C580 ACKQ 0130 C580 ; C=0 => character not printable, C=1 => printable 0131 C580 49 06 EORIM ACKASC ;Was it an ACK ? 0132 C582 D0 08 BNE VDURTS ;[not ACK] 0133 C584 ; 0134 C584 ; C=0 cos ACK not printable 0135 C584 A9 7F LDAIM &7F ;Yes?, then clear b7 of STATS 0136 C586 90 20 BCC STTAND ;always jump 0137 C588 0138 C588 0139 C588 0140 C588 ;Test to see if printable ($20-$7E or $80-$FF) 0141 C588 ;Returns c=1 iff printable, c=0 otherwise 0142 C588 0143 C588 0144 C588 ;ANOMQ Returns z=0 iff cursors joined 0145 C588 0146 C588 A5 D0 ANOMQ LDA STATS 0147 C58A 29 20 ANDIM &20 ;Is b5 set ? (Answer to z) 0148 C58C VDURTS 0149 C58C 60 RTS ;Returns(A)=0 if b5 clear 0150 C58D 0151 C58D ;INDIVIDUAL ROUTINES 0152 C58D 0153 C58D ;NUL ($00) - do nothing 0154 C58D 0155 C58D ;Jump table points to ACK, an RTS, to save a byte 0156 C58D 0157 C58D ;SOH ($01) - Next char to printer 0158 C58D 0159 C58D ;This is taken care of above 0160 C58D 0161 C58D 0162 C58D ;SO ($0E) - Page mode on 0163 C58D 0164 C58D A0 00 SO LDYIM &00 ;Initialise LINES 0165 C58F 8C 69 02 STY LINES 0166 C592 A9 04 LDAIM &04 ;Set b2 of STATS 0167 C594 D0 07 BNE STTOR 0168 C596 0169 C596 ;SI ($0F) - Page mode OFF 0170 C596 ; This is frigged below 0171 C596 0172 C596 ;STX ($02) - Start printer 0173 C596 0174 C596 20 A2 E1 STX JSR mUPT ;inform network (A assumed to contain $02) 0175 C599 A9 94 LDAIM &94 ;Set bit 0 of STATS. This maps to $01 0176 C59B 0177 C59B ;NAK ($15) - Turn VDU off 0178 C59B 0179 C59B 49 95 NAK EORIM &95 ;Set b7 of STATS. Map $15 to $80 0180 C59D 0181 C59D 05 D0 STTOR ORA STATS 0182 C59F D0 09 BNE STTEXT ;(branch always taken unless ORed with 0) 0183 C5A1 0184 C5A1 0185 C5A1 ;ETX ($03) - Stop printer 0186 C5A1 0187 C5A1 20 A2 E1 ETX JSR mUPT ;inform network (A assumed to contain $03) 0188 C5A4 A9 0A LDAIM &0A ;clear bit 0 of STATS. Maps $0A on to $FE 0189 C5A6 0190 C5A6 49 F4 SI EORIM &F4 ;Clears b2 of STATS. Maps $0F on to $FB 0191 C5A8 0192 C5A8 25 D0 STTAND AND STATS 0193 C5AA 85 D0 STTEXT STA STATS 0194 C5AC 60 EOTEXT RTS 0195 C5AD 0196 C5AD 0197 C5AD ;EOT ($04) - Separate cursors 0198 C5AD 0199 C5AD AD 61 03 EOT LDA NPIX ;Is this a graphics mode ? 0200 C5B0 F0 FA BEQ EOTEXT ;NO, then return 0201 C5B2 20 51 C9 JSR ETCA ;Redisplay old cursor 0202 C5B5 A9 DF LDAIM &DF ;Clear b5 of STATS 0203 C5B7 D0 EF BNE STTAND ;(branch always taken) 0204 C5B9 0205 C5B9 ;ENQ ($05) - Join cursors 0206 C5B9 ;Store & hide current cursor 0207 C5B9 ;Set bit 5 of STATS 0208 C5B9 0209 C5B9 AD 61 03 ENQ LDA NPIX ;Is this a graphics mode ? 0210 C5BC F0 EE BEQ EOTEXT ;NO, then return 0211 C5BE ;Access R10 OF 6845. NB cannot do this through CRTCP. 0212 C5BE A9 20 LDAIM &20 ;Hide cursor 0213 C5C0 20 54 C9 JSR ETCB ; Preserves flags 0214 C5C3 D0 D8 BNE STTOR ;Set bit 5 of STATS, (A) preserved by ETCB 0215 C5C5 0216 C5C5 ;ACK ($06) - Turn VDU drivers on again 0217 C5C5 ;Clear bit 7 of STATS 0218 C5C5 0219 C5C5 ;Taken care of above 0220 C5C5 0221 C5C5 ;BELL ($07) - Ring BELL 0222 C5C5 0223 C5C5 ;The routine BELL is externally declared in file UADE90 0224 C5C5 0225 C5C5 ;Cursor primitives 0226 C5C5 0227 C5C5 ;BS ($08) - Cursor left 1 character position 0228 C5C5 0229 C5C5 20 88 C5 BS JSR ANOMQ 0230 C5C8 D0 55 BNE CSAL 0231 C5CA 0232 C5CA ;Cursor left 0233 C5CA 0234 C5CA CE 18 03 CSL DEC CSX 0235 C5CD AE 18 03 LDX CSX ;Over LH margin ? 0236 C5D0 EC 08 03 CPX TWLCOL 0237 C5D3 30 19 BMI CSLC ;Yes, then up (see below) a line 0238 C5D5 AD 4A 03 LDA CSPOSN ;Move cursor left 0239 C5D8 38 SEC 0240 C5D9 ED 4F 03 SBC BYTCH 0241 C5DC AA TAX 0242 C5DD AD 4B 03 LDA CSPOSN +&01 0243 C5E0 E9 00 SBCIM &00 0244 C5E2 CD 4E 03 CMP BEGSCN ;Wraparound ? 0245 C5E5 B0 03 BCS CSLA Acorn macro assembler Page 12 VDU File - MOS02 0246 C5E7 6D 54 03 ADC BYTSCN ;Yes, then add screen 0247 C5EA A8 CSLA TAY 0248 C5EB 4C F6 C9 JMP CSDSPA 0249 C5EE 0250 C5EE AD 0A 03 CSLC LDA TWRCOL ;Put csr = RH edge 0251 C5F1 8D 18 03 STA CSX ;& fall through to ... 0252 C5F4 0253 C5F4 ;Cursor up 0254 C5F4 0255 C5F4 CE 69 02 CSU DEC LINES ;One more line to print before page mode occurs 0256 C5F7 10 03 BPL CSUC 0257 C5F9 EE 69 02 INC LINES ;At top of page, so don't go -ve! 0258 C5FC AE 19 03 CSUC LDX CSY ;Cursor on top row ? 0259 C5FF EC 0B 03 CPX TWTROW 0260 C602 F0 06 BEQ CSUA ;Yes, then scroll 0261 C604 CE 19 03 DEC CSY 0262 C607 4C AF C6 JMP CSDA 0263 C60A 0264 C60A 18 CSUA CLC 0265 C60B 20 3F CD JSR ENSCRL ;Account for scroll disable 0266 C60E A9 08 LDAIM &08 ;Test hard/soft flag 0267 C610 24 D0 BIT STATS 0268 C612 D0 05 BNE CSUB ;S3 set, soft scroll 0269 C614 20 94 C9 JSR HSCRDN ;S3 clear, hard scroll 0270 C617 D0 03 BNE CSUD ; HSCRDN returns zero false 0271 C619 20 A4 CD CSUB JSR SSCRDN 0272 C61C 4C AC C6 CSUD JMP CSDC 0273 C61F A2 00 CSAL LDXIM &00 0274 C621 ; And fall through to 0275 C621 0276 C621 ;Move graphics cursor 1 character - primitives. 0277 C621 ;(X) = 0 if X cursor to be moved 0278 C621 ; 2 if Y cursor to be moved 0279 C621 ;Iff (X)=0, then if off window, LF/VT occurs 0280 C621 ;If cursor crosses margin, then goes to opposite margin. 0281 C621 ;Go down 1 character location 0282 C621 0283 C621 86 DB GCSCHD STX ZTEMP +&01 ;Store offset 0284 C623 20 0D D1 JSR WINDCS ;Window current cursor (result to ZTEMP) 0285 C626 A6 DB LDX ZTEMP +&01 ;Subtract 8 from cursor 0286 C628 38 SEC 0287 C629 BD 24 03 LDAAX GCSIR 0288 C62C E9 08 SBCIM &08 0289 C62E 9D 24 03 STAAX GCSIR 0290 C631 B0 03 BCS GCSHDA 0291 C633 DE 25 03 DECAX GCSIR+&01 0292 C636 A5 DA GCSHDA LDA ZTEMP ;Get window 0293 C638 D0 1E BNE GCSHDB ;Out of window to begin with?, then skip 0294 C63A 20 0D D1 JSR WINDCS ;Window current point 0295 C63D F0 19 BEQ GCSHDB ;Still inside? , then return 0296 C63F A6 DB LDX ZTEMP +&01 ;Gone outside?, then go to high margin 0297 C641 BD 04 03 LDAAX GWRCOL 0298 C644 E0 01 CPXIM &01 ;Plot by X?, then back up 1 character 0299 C646 B0 02 BCS GCSHDC 0300 C648 E9 06 SBCIM &06 ;c=0. so subt. 7 to get char. just on screen 0301 C64A 9D 24 03 GCSHDC STAAX GCSIR 0302 C64D BD 05 03 LDAAX GWRCOL+&01 0303 C650 E9 00 SBCIM &00 0304 C652 9D 25 03 STAAX GCSIR+&01 0305 C655 8A TXA ;Plot by X?, then go up a line as well 0306 C656 F0 08 BEQ CSAU 0307 C658 4C B8 D1 GCSHDB JMP IEG 0308 C65B 0309 C65B 0310 C65B ;VT ($0B) - Cursor up 1 character line 0311 C65B 0312 C65B 20 88 C5 VT JSR ANOMQ 0313 C65E F0 94 BEQ CSU 0314 C660 A2 02 CSAU LDXIM &02 0315 C662 D0 52 BNE GCSCHU ;(branch always taken) 0316 C664 0317 C664 ;HT ($09) - Cursor right 1 character position 0318 C664 0319 C664 A5 D0 HT LDA STATS ;Encode ANOMQ because this routine often referenced 0320 C666 29 20 ANDIM &20 0321 C668 D0 4A BNE CSAR 0322 C66A 0323 C66A ;Cursor right 0324 C66A 0325 C66A AE 18 03 CSR LDX CSX ;Cursor over RH col ? 0326 C66D EC 0A 03 CPX TWRCOL 0327 C670 B0 12 BCS CSRC 0328 C672 EE 18 03 INC CSX 0329 C675 AD 4A 03 LDA CSPOSN 0330 C678 6D 4F 03 ADC BYTCH ;Add no. bytes per char 0331 C67B AA TAX 0332 C67C AD 4B 03 LDA CSPOSN +&01 ;to posn. of csr. 0333 C67F 69 00 ADCIM &00 ;sets n for test in CSDSPA 0334 C681 4C F6 C9 JMP CSDSPA 0335 C684 AD 08 03 CSRC LDA TWLCOL ;Put csr = LH edge 0336 C687 8D 18 03 STA CSX ;& fall through to ... 0337 C68A 0338 C68A ;Cursor down 0339 C68A 0340 C68A 18 CSD CLC ;do not set LEDs on first test for page wait (MOS requirement) 0341 C68B 20 E3 CA JSR PAGE ;Account for page mode 0342 C68E AE 19 03 LDX CSY ;Is cursor off bottom? 0343 C691 EC 09 03 CPX TWBROW 0344 C694 B0 05 BCS CSDD ;Yes, then scroll 0345 C696 EE 19 03 INC CSY ;No, then move down line 0346 C699 90 14 BCC CSDA ;(branch always taken) 0347 C69B 0348 C69B 20 3F CD CSDD JSR ENSCRL ;Account for scroll disable 0349 C69E A9 08 LDAIM &08 ;Test hard/soft flag 0350 C6A0 24 D0 BIT STATS 0351 C6A2 D0 05 BNE CSDB 0352 C6A4 20 A4 C9 JSR HSCRUP ;No windows set, so use hard scroll 0353 C6A7 D0 03 BNE CSDC ; HSCRUP unsets zero 0354 C6A9 20 FF CD CSDB JSR SSCRUP ;Windows set, so use soft scroll 0355 C6AC 20 AC CE CSDC JSR CLTLIN ;Clear the line on which CSY lies 0356 C6AF 20 06 CF CSDA JSR TADDRY ;address the cursor, point guaranteed in window 0357 C6B2 90 7E BCC FSD ;and display it (TADDRY returns carry clear) 0358 C6B4 A2 00 CSAR LDXIM &00 0359 C6B6 ; And fall through to 0360 C6B6 0361 C6B6 ;Move graphics cursor 1 character - primitives. 0362 C6B6 ;(X) = 0 if Y cursor to be moved 0363 C6B6 ; 2 if X cursor to be moved 0364 C6B6 ;Iff (X)=0, then if off window, LF/VT occurs 0365 C6B6 ;If cursor crosses margin, then goes to opposite margin. 0366 C6B6 Acorn macro assembler Page 13 VDU File - MOS02 0367 C6B6 86 DB GCSCHU STX ZTEMP +&01 ;Store offset 0368 C6B8 20 0D D1 JSR WINDCS ;Window current cursor (result to ZTEMP) 0369 C6BB A6 DB LDX ZTEMP +&01 ;Add 8 to cursor 0370 C6BD 18 CLC 0371 C6BE BD 24 03 LDAAX GCSIR 0372 C6C1 69 08 ADCIM &08 0373 C6C3 9D 24 03 STAAX GCSIR 0374 C6C6 90 03 BCC GCSHUA 0375 C6C8 FE 25 03 INCAX GCSIR+&01 0376 C6CB A5 DA GCSHUA LDA ZTEMP ;Get window 0377 C6CD D0 89 BNE GCSHDB ;Out of window to begin with?, then skip 0378 C6CF 20 0D D1 JSR WINDCS ;Window current point 0379 C6D2 F0 84 BEQ GCSHDB ;Still inside? , then return 0380 C6D4 A6 DB LDX ZTEMP +&01 ;Gone outside?, then go to low margin 0381 C6D6 BD 00 03 LDAAX GWLCOL 0382 C6D9 E0 01 CPXIM &01 ;Plot by Y?, then go up a line 0383 C6DB 90 02 BCC GCSHUC 0384 C6DD 69 06 ADCIM &06 ;c=1, so add 7 to get char. just on screen 0385 C6DF 9D 24 03 GCSHUC STAAX GCSIR 0386 C6E2 BD 01 03 LDAAX GWLCOL+&01 0387 C6E5 69 00 ADCIM &00 0388 C6E7 9D 25 03 STAAX GCSIR+&01 0389 C6EA 8A TXA ;Plot by X? 0390 C6EB F0 08 BEQ CSAD ;Yes?, then go down a line as well 0391 C6ED 4C B8 D1 JMP IEG ;No?, then exit 0392 C6F0 0393 C6F0 0394 C6F0 ;LF ($0A) - Cursor down 1 character line 0395 C6F0 0396 C6F0 20 88 C5 LF JSR ANOMQ 0397 C6F3 F0 95 BEQ CSD 0398 C6F5 A2 02 CSAD LDXIM &02 0399 C6F7 4C 21 C6 JMP GCSCHD 0400 C6FA 0401 C6FA ;FS ($1C) Define text area 0402 C6FA 0403 C6FA ;QEND-3 = L.H. margin = TWLCOL 0404 C6FA ;QEND-2 = Bottom row = TWBROW 0405 C6FA ;QEND-1 = R.H. margin = TWRCOL 0406 C6FA ;QEND = Top row = TWTROW 0407 C6FA 0408 C6FA AE 55 03 FS LDX MODE 0409 C6FD AD 21 03 LDA QEND-&02 ;Do y co-ordinates. Get bottom (higher numbered) row 0410 C700 CD 23 03 CMP QEND ;Top row above bottom ? 0411 C703 90 53 BCC PRACX ;No?, then fail 0412 C705 DD E7 C3 CMPAX PROWS ;Is > max. no. rows? 0413 C708 F0 02 BEQ FSC 0414 C70A B0 4C BCS PRACX ;Yes, then fail 0415 C70C AD 22 03 FSC LDA QEND-&01 ;Do x co-ordinates. Get RH margin 0416 C70F A8 TAY 0417 C710 DD EF C3 CMPAX PCOLS ;Is > than max. cols? 0418 C713 F0 02 BEQ FSB 0419 C715 B0 41 BCS PRACX ;Yes, then fail 0420 C717 38 FSB SEC 0421 C718 ED 20 03 SBC QEND-&03 ;How many cols. wide ? 0422 C71B 30 3B BMI PRACX ;Fail if -ve no. cols. 0423 C71D A8 TAY 0424 C71E 20 88 CA JSR SETPWW ;Set PWWDTH 0425 C721 A9 08 LDAIM &08 ;Set bit 3 for soft scrolling 0426 C723 20 9D C5 JSR STTOR 0427 C726 A2 20 LDXIM QEND-&03-V ;copy Q to TWxxxx 0428 C728 A0 08 LDYIM TWLCOL-V 0429 C72A 20 8A D4 JSR COPYF 0430 C72D 20 E8 CE JSR TADDR ;Is cursor still inside 0431 C730 B0 47 BCS RS ;No, then home cursor 0432 C732 4C 02 CA FSD JMP CSDSP 0433 C735 0434 C735 RPXLXY 0435 C735 A0 03 LDYIM &03 ;~~~ Read pixel at (x,y) ~~~ 0436 C737 B1 F0 PRAAA LDAIY WARGS ;Copy (x,y) to RPXLWS ... 0437 C739 99 28 03 STAAY RPXLWS 0438 C73C 88 DEY 0439 C73D 10 F8 BPL PRAAA 0440 C73F A9 28 LDAIM RPXLWS-V ;Convert in internal co-ordinates 0441 C741 20 39 D8 JSR RPXLD ;Read pixel if extant 0442 C744 A0 04 LDYIM &04 ;Store in (XY) +4 0443 C746 D0 08 BNE PRACB ;(branch always taken) 0444 C748 0445 C748 RPALET 0446 C748 2D 60 03 AND NCOLOR ;Read parrot 0447 C74B AA TAX 0448 C74C BD 6F 03 LDAAX PARROT 0449 C74F C8 PRACA INY 0450 C750 91 F0 PRACB STAIY WARGS 0451 C752 A9 00 LDAIM &00 0452 C754 C0 04 CPYIM &04 0453 C756 D0 F7 BNE PRACA 0454 C758 60 PRACX RTS 0455 C759 0456 C759 ;FF ($0C) Form feed 0457 C759 0458 C759 20 88 C5 FF JSR ANOMQ ;Cursors joined ? 0459 C75C D0 5F BNE FFANOM ;Yes, then clear graphics area 0460 C75E A5 D0 LDA STATS ;Window set ? 0461 C760 29 08 ANDIM &08 ;Test bit 3 of STATS 0462 C762 D0 03 BNE FFA ;Set?, then window clear 0463 C764 4C C1 CB JMP CLATXT ;Clear?, then fast clear 0464 C767 AE 0B 03 FFA LDX TWTROW ;Initialise cursor to top row 0465 C76A 8E 19 03 FFB STX CSY ;Clear this line 0466 C76D 20 AC CE JSR CLTLIN 0467 C770 AE 19 03 LDX CSY ;Move down a line 0468 C773 EC 09 03 CPX TWBROW ;On the bottom ? 0469 C776 E8 INX 0470 C777 90 F1 BCC FFB ;(INX preserves c) 0471 C779 0472 C779 ;& fall through to 0473 C779 0474 C779 0475 C779 ;RS ($1E) Home character cursor 0476 C779 0477 C779 20 88 C5 RS JSR ANOMQ 0478 C77C F0 03 BEQ RSA 0479 C77E 4C A6 CF JMP RSAN 0480 C781 8D 23 03 RSA STA QEND 0481 C784 8D 22 03 STA QEND-&01 0482 C787 0483 C787 ;& fall through to .... 0484 C787 0485 C787 ;US ($1F) Move text csr to x,y 0486 C787 0487 C787 ;Put cursor to (x,y), where Acorn macro assembler Page 14 VDU File - MOS02 0488 C787 ;x in QEND-1 & y in QEND 0489 C787 ;If illegal, leave cursor alone 0490 C787 0491 C787 20 88 C5 US JSR ANOMQ ;Cursors joined ? 0492 C78A D0 CC BNE PRACX ;Yes, then skip 0493 C78C 20 A8 C7 JSR USAF ;Remember current cursor 0494 C78F 18 CLC 0495 C790 AD 22 03 LDA QEND-&01 ;Add offset to x posn 0496 C793 6D 08 03 ADC TWLCOL 0497 C796 8D 18 03 STA CSX 0498 C799 AD 23 03 LDA QEND ;Add offset to y posn 0499 C79C 18 CLC 0500 C79D 6D 0B 03 ADC TWTROW 0501 C7A0 8D 19 03 STA CSY 0502 C7A3 20 E8 CE JSR TADDR ;Attempt to posn. csr 0503 C7A6 90 8A BCC FSD ;to a JMP CSDSP 0504 C7A8 0505 C7A8 A2 18 USAF LDXIM CSX-V 0506 C7AA A0 28 LDYIM USWS-V 0507 C7AC 4C DE CD JMP SWAP2 0508 C7AF 0509 C7AF ;CR ($0D) Carriage return 0510 C7AF 0511 C7AF 20 88 C5 CR JSR ANOMQ 0512 C7B2 F0 03 BEQ CRA 0513 C7B4 4C AD CF JMP CRAN 0514 C7B7 20 6E CE CRA JSR SSCRIM ;Position cursor to LH edge of window 0515 C7BA 4C AF C6 JMP CSDA ;Display cursor & TADDR 0516 C7BD LNK MOS03 0001 C7BD 0002 C7BD TTL VDU File - MOS03 0003 C7BD OPT MOS03 Acorn macro assembler Page 15 VDU File - MOS03 0004 C7BD 0005 C7BD ;Last revision 15/06/82 0006 C7BD 0007 C7BD ;15/06/82 Route ALL unknown plot commands thru VDUVEC, even in text modes 0008 C7BD ;02/06/82 ETB mod to redef of ASCII 0009 C7BD ;27/05/82 DCC (programme palette) recoded 0010 C7BD ;05/05/82 Delete anomalous TAB 0011 C7BD ; Move NAK to MOS02 0012 C7BD ;01/05/82 Recoded to allow for forward queueing & change in variable order 0013 C7BD ;24/04/82 ETB Function 1 (hide/display cursor) coded 0014 C7BD ;19/04/82 DCC & DCCB moved for byte saving 0015 C7BD ;15/04/82 NPCOL used to fix VDU 19,0,20,0,0,0 bug 0016 C7BD ;24/03/82 DLE leaves graphics cursor alone 0017 C7BD ; ETB to check if font exploded before reprogramming fonts 1-3 0018 C7BD ;21/03/82 DLE to account for non-zero origins 0019 C7BD ;22/01/82 EIG to EIGABS in graphics window definition 0020 C7BD ;07/01/82 Catch illegal VDU 23,n,.... commands 0021 C7BD ;15/11/81 Vertical sync user adjustment (Paul) 0022 C7BD 0023 C7BD ;INDIVIDUAL ROUTINES 0024 C7BD 0025 C7BD 0026 C7BD ;DLE ($10) Clear graphics area 0027 C7BD 0028 C7BD 20 A6 CF FFANOM JSR RSAN 0029 C7C0 AD 61 03 DLE LDA NPIX ;Non-graphics ? 0030 C7C3 F0 33 BEQ DLEX 0031 C7C5 AE 5A 03 LDX BGCOLF ;Clear to the background colour 0032 C7C8 AC 5C 03 LDY GPLBMD ;Use the background colour mode 0033 C7CB 20 B3 D0 JSR SETZG ;Set this up 0034 C7CE A2 00 LDXIM GWLCOL-V ;Copy window params from GWTROW ... 0035 C7D0 A0 28 LDYIM DLEWS-V ;Copy window parameters to DLEWS 0036 C7D2 20 7C D4 JSR COPY8 0037 C7D5 38 SEC ;How many lines to do ? 0038 C7D6 AD 06 03 LDA GWTROW 0039 C7D9 ED 02 03 SBC GWBROW 0040 C7DC A8 TAY 0041 C7DD C8 INY ;Increment this to distinguish between 0 & 255 0042 C7DE 8C 30 03 STY DLENLN ;Line counter 0043 C7E1 A2 2C DLEA LDXIM DLEWS+&04-V ;Point to R.H. point, containing valid Y address 0044 C7E3 A0 28 LDYIM DLEWS-V ;Point to L.H. point, with irrelevant Y address 0045 C7E5 20 A6 D6 JSR HPLOTA ;Clear the current line 0046 C7E8 AD 2E 03 LDA DLEWS+&06 ;Decrement the current line number 0047 C7EB D0 03 BNE DLEB 0048 C7ED CE 2F 03 DEC DLEWS+&07 0049 C7F0 CE 2E 03 DLEB DEC DLEWS+&06 0050 C7F3 CE 30 03 DEC DLENLN 0051 C7F6 D0 E9 BNE DLEA 0052 C7F8 60 DLEX RTS 0053 C7F9 0054 C7F9 ;DC1 ($11) Programme foreground 0055 C7F9 ;or background colours for text 0056 C7F9 0057 C7F9 A0 00 DCA LDYIM &00 ;Used for storing 0058 C7FB F0 02 BEQ DCABA ;(branch always taken) 0059 C7FD 0060 C7FD ;DC2 ($12) Programme foreground 0061 C7FD ;or background colours for graphics 0062 C7FD ;QEND-1=mode 0063 C7FD ;QEND =logical colour 0064 C7FD 0065 C7FD A0 02 DCB LDYIM &02 0066 C7FF AD 23 03 DCABA LDA QEND ;Get logical colour 0067 C802 10 01 BPL DCABB ;Foreground ? 0068 C804 C8 INY ;No, then point to background locations 0069 C805 2D 60 03 DCABB AND NCOLOR 0070 C808 85 DA STA ZTEMP 0071 C80A AD 60 03 LDA NCOLOR ;Sneaky offset method 0072 C80D F0 1C BEQ DCABX ;Branch for TTX 0073 C80F 29 07 ANDIM &07 ;to FCOLTB. A=table base 0074 C811 18 CLC 0075 C812 65 DA ADC ZTEMP ;(A) = offset +1 0076 C814 AA TAX 0077 C815 BD 23 C4 LDAAX FCOLTB -&01 0078 C818 99 57 03 STAAY FTCOLF ;(Y) set above to 0..3 0079 C81B C0 02 CPYIM &02 ;Graphics ? 0080 C81D B0 0D BCS DCBAC ;Yes, then set up GPLMDE 0081 C81F AD 57 03 LDA FTCOLF ;No, then set ZORA & 0082 C822 49 FF EORIM &FF ;ZEOR 0083 C824 85 D3 STA ZEOR ;ZEOR = NOT foreground 0084 C826 4D 58 03 EOR BTCOLF ;ZORA = ZEOR EOR back 0085 C829 85 D2 STA ZORA 0086 C82B 60 DCABX RTS 0087 C82C AD 22 03 DCBAC LDA QEND-&01 0088 C82F 99 59 03 STAAY GPLFMD -&02 ;Y=2 or 3 (for fore or background) mode 0089 C832 60 RTS 0090 C833 0091 C833 A9 20 DCTTX LDAIM TTXBCL ;TTX load with a particular byte ($20) 0092 C835 8D 58 03 STA BTCOLF ;Used only for screen clears 0093 C838 60 RTS 0094 C839 0095 C839 ;DC3 ($13) is below this routine 0096 C839 0097 C839 0098 C839 ;DC4 ($14) Set default physical 0099 C839 ;- logical relations 0100 C839 ;Default back & foreground clrs 0101 C839 0102 C839 A2 05 DCD LDXIM &05 ;Programme all full colours & modes to zero 0103 C83B A9 00 LDAIM &00 0104 C83D 9D 57 03 DCDA STAAX FTCOLF 0105 C840 CA DEX 0106 C841 10 FA BPL DCDA 0107 C843 AE 60 03 LDX NCOLOR ;Set foreground colours & ZORA & ZEOR 0108 C846 F0 EB BEQ DCTTX ;Branch for TTX 0109 C848 A9 FF LDAIM &FF 0110 C84A E0 0F CPXIM &0F 0111 C84C D0 02 BNE DCDB 0112 C84E A9 3F LDAIM INVSXT ;Don't invert flashing bit 0113 C850 8D 57 03 DCDB STA FTCOLF 0114 C853 8D 59 03 STA FGCOLF 0115 C856 49 FF EORIM &FF 0116 C858 85 D2 STA ZORA 0117 C85A 85 D3 STA ZEOR 0118 C85C 8E 1F 03 STX QEND-&04 ;set logical colour := NCOLOR 0119 C85F E0 03 CPXIM &03 ;How many colours? 0120 C861 F0 11 BEQ DCDLA 0121 C863 90 20 BCC DCDLI 0122 C865 0123 C865 ;16 colours - one to one 0124 C865 Acorn macro assembler Page 16 VDU File - MOS03 0125 C865 8E 20 03 STX QEND-&03 0126 C868 20 92 C8 DCDLF JSR DCC 0127 C86B CE 20 03 DEC QEND-&03 0128 C86E CE 1F 03 DEC QEND-&04 0129 C871 10 F5 BPL DCDLF 0130 C873 60 RTS 0131 C874 0132 C874 0133 C874 ;4 colour, use shift right of $07 0134 C874 0135 C874 A2 07 DCDLA LDXIM &07 0136 C876 8E 20 03 STX QEND-&03 0137 C879 20 92 C8 DCDLH JSR DCC 0138 C87C 4E 20 03 LSR QEND-&03 0139 C87F CE 1F 03 DEC QEND-&04 0140 C882 10 F5 BPL DCDLH 0141 C884 60 RTS 0142 C885 0143 C885 ;2 colour (TTX also executes this rouine) 0144 C885 0145 C885 A2 07 DCDLI LDXIM &07 ;Programme log.=1, phys.=7 0146 C887 20 8F C8 JSR DCDLJ 0147 C88A A2 00 LDXIM &00 ;Programme log.=0, phys.=0 0148 C88C 8E 1F 03 STX QEND-&04 0149 C88F 0150 C88F 8E 20 03 DCDLJ STX QEND-&03 ;& fall through to .... 0151 C892 0152 C892 ;DC3 ($13) - Programme logical/ 0153 C892 ;physical colour relation 0154 C892 0155 C892 ;Logical colour in QEND-4 0156 C892 ;Physical colour in QEND-3 0157 C892 0158 C892 08 DCC PHP 0159 C893 78 SEI 0160 C894 AD 1F 03 LDA QEND-&04 ;Determine logical colour 0161 C897 2D 60 03 AND NCOLOR 0162 C89A AA TAX 0163 C89B AD 20 03 LDA QEND-&03 ;Get physical colour 0164 C89E 29 0F DCC1 ANDIM NPCOL ;mask off confusing bits 0165 C8A0 9D 6F 03 STAAX PARROT ;Write to list 0166 C8A3 A8 TAY 0167 C8A4 AD 60 03 LDA NCOLOR 0168 C8A7 85 FA STA SEIWKA 0169 C8A9 C9 03 CMPIM &03 0170 C8AB 08 PHP ;Needed later 0171 C8AC 8A TXA ;(A)=logical colour 0172 C8AD 6A DCCALA RORA ;determine start position =Logi*16/(ncolor+1)*16 0173 C8AE 66 FA ROR SEIWKA 0174 C8B0 B0 FB BCS DCCALA 0175 C8B2 06 FA ASL SEIWKA 0176 C8B4 98 TYA ;Get physical colour 0177 C8B5 05 FA ORA SEIWKA 0178 C8B7 AA TAX ;Byte to be given to VPROC1 0179 C8B8 A0 00 LDYIM &00 ;Initialise loop counter 0180 C8BA 0181 C8BA 28 DCCALB PLP ;Does NCOLOR=3? 0182 C8BB 08 PHP 0183 C8BC D0 0E BNE DCCALC ;No?, then skip 0184 C8BE 29 60 ANDIM &60 ;If b5 & b6 both set or clear, don't invert them 0185 C8C0 F0 09 BEQ DCCALD 0186 C8C2 C9 60 CMPIM &60 0187 C8C4 F0 05 BEQ DCCALD 0188 C8C6 8A TXA 0189 C8C7 49 60 EORIM &60 0190 C8C9 D0 01 BNE DCCALC ;(branch always taken) 0191 C8CB 8A DCCALD TXA 0192 C8CC 20 11 EA DCCALC JSR MVPRC1 ;Save (X) & (Y) 0193 C8CF 98 TYA ;Loop counter 0194 C8D0 38 SEC 0195 C8D1 6D 60 03 ADC NCOLOR 0196 C8D4 A8 TAY 0197 C8D5 8A TXA ;Restore (A) 0198 C8D6 69 10 ADCIM &10 ;c=0 0199 C8D8 AA TAX 0200 C8D9 C0 10 CPYIM &10 0201 C8DB 90 DD BCC DCCALB 0202 C8DD 28 PLP 0203 C8DE 28 PLP 0204 C8DF 60 RTS 0205 C8E0 0206 C8E0 0207 C8E0 ;OSWORD call to programme palette 0208 C8E0 0209 C8E0 PRPAL 0210 C8E0 08 PHP 0211 C8E1 2D 60 03 AND NCOLOR ;Get logical colour 0212 C8E4 AA TAX 0213 C8E5 C8 INY ;(Y):=1 0214 C8E6 B1 F0 LDAIY WARGS ;Load physical colour 0215 C8E8 4C 9E C8 JMP DCC1 0216 C8EB 0217 C8EB ;SYN ($16) Change mode 0218 C8EB 0219 C8EB AD 23 03 SYN LDA QEND ;Get the mode 0220 C8EE 4C 33 CB JMP CHMODE 0221 C8F1 0222 C8F1 ;ETB ($17) Programme soft font 0223 C8F1 ;Programme character font to user definition 0224 C8F1 ;Character to be programmed in Q+08, top row in Q+07 0225 C8F1 ;through to bottom row in Q+00 0226 C8F1 0227 C8F1 AD 1B 03 ETB LDA QEND-&08 ;Is it the soft font ? 0228 C8F4 C9 20 CMPIM &20 ;Is it a printable character ? 0229 C8F6 90 47 BCC ETBD 0230 C8F8 48 PHA ;Yes?, then get group 0231 C8F9 4A LSRA 0232 C8FA 4A LSRA 0233 C8FB 4A LSRA 0234 C8FC 4A LSRA 0235 C8FD 4A LSRA 0236 C8FE AA TAX ;Flag set ? 0237 C8FF BD 0D C4 LDAAX BITTBL 0238 C902 2C 67 03 BIT FNTFLG 0239 C905 D0 20 BNE ETBB ;Yes?, then just copy defn. 0240 C907 0241 C907 0242 C907 0D 67 03 ORA FNTFLG ;Set flag 0243 C90A 8D 67 03 STA FNTFLG 0244 C90D 8A TXA ;Copy page to soft font 0245 C90E 29 03 ANDIM &03 Acorn macro assembler Page 17 VDU File - MOS03 0246 C910 18 CLC 0247 C911 69 BF ADCIM HFMSB ;Point to hard font 0248 C913 85 DF STA ZTEMPC +&01 0249 C915 BD 67 03 LDAAX PGSFNT -&01 ;Point to soft font 0250 C918 85 DD STA ZTEMPB +&01 0251 C91A A0 00 LDYIM &00 0252 C91C 84 DC STY ZTEMPB 0253 C91E 84 DE STY ZTEMPC 0254 C920 B1 DE ETBC LDAIY ZTEMPC 0255 C922 91 DC STAIY ZTEMPB 0256 C924 88 DEY 0257 C925 D0 F9 BNE ETBC 0258 C927 68 ETBB PLA 0259 C928 20 3E D0 JSR CHADDR ;Point (ZTEMPC) to soft font 0260 C92B A0 07 LDYIM &07 ;& copy character into the font 0261 C92D B9 1C 03 ETBA LDAAY QEND-&07 0262 C930 91 DE STAIY ZTEMPC 0263 C932 88 DEY 0264 C933 10 F8 BPL ETBA 0265 C935 60 RTS 0266 C936 68 PLA 0267 C937 60 ETCX RTS 0268 C938 0269 C938 JMIV25 0270 C938 AD 1F 03 LDA PLMODE 0271 C93B 18 CLC 0272 C93C ; C=0 0273 C93C JMIV23 ;C=1 0274 C93C 6C 26 02 JMI VDUVEC 0275 C93F ; 0276 C93F C9 01 ETBD CMPIM &01 ;Valid command ? 0277 C941 90 15 BCC ETD 0278 C943 ; C=1 0279 C943 D0 F7 BNE JMIV23 ;No?, then jump indirect to user vector with C=1 0280 C945 ; 0281 C945 20 88 C5 JSR ANOMQ ;Anom. printing? ~~~ FUNCTION 1 Turn cursor on/off ~~~ 0282 C948 D0 ED BNE ETCX ;Yes?, then don't do it 0283 C94A A9 20 LDAIM &20 0284 C94C AC 1C 03 LDY QEND-&07 ;Hide(0) or display(1)? 0285 C94F F0 03 BEQ ETCB 0286 C951 AD 5F 03 ETCA LDA CSTEMP ;RESTORE CURSOR 0287 C954 A0 0A ETCB LDYIM &0A 0288 C956 D0 2D BNE CRTCPA ;Programme the 6845 without saving to CSTEMP 0289 C958 0290 C958 AD 1D 03 ETD LDA QEND-&06 ;~~~ FUNCTION 0 Programme 6845 register #(Q+7) WITH (Q+6) ~~~ 0291 C95B AC 1C 03 LDY QEND-&07 0292 C95E 0293 C95E C0 07 CRTCP CPYIM &07 0294 C960 90 23 BCC CRTCPA ;[register<7, so not register 7 or 10] 0295 C962 D0 03 BNE CRTCPC ;[not vertical sync position] 0296 C964 0297 C964 6D 90 02 ADC VERTIC ;apply user adjustment (c=1) 0298 C967 0299 C967 C0 08 CRTCPC CPYIM &08 0300 C969 D0 07 BNE CRTCPD ;[not interlace mode register] 0301 C96B 09 00 ORAIM &00 ; interlace mode register 0302 C96D 30 03 BMI CRTCPD ;[do not alter interlace (probably teletext)] 0303 C96F ; 0304 C96F 4D 91 02 EOR INTERL ;modify interlace 0305 C972 C0 0A CRTCPD CPYIM &0A ;Cursor start register ? 0306 C974 D0 0F BNE CRTCPA ;[not cursor start register] 0307 C976 8D 5F 03 STA CSTEMP ;Yes?, then record this for separate cursors 0308 C979 A8 TAY 0309 C97A A5 D0 LDA STATS ;Are cursors joined ? 0310 C97C 29 20 ANDIM &20 0311 C97E 08 PHP ;(very nasty coding, but it is short) 0312 C97F 98 TYA 0313 C980 A0 0A LDYIM &0A 0314 C982 28 PLP 0315 C983 D0 06 BNE CRTCPB ;Yes, then don't write to 6845 0316 C985 8C 00 FE CRTCPA STY CRTCA ;Address said register 0317 C988 8D 01 FE STA CRTCD ;and store data therein 0318 C98B 60 CRTCPB RTS ;(Referenced from EM) 0319 C98C 0320 C98C ;ESC ($1B) does bugger all 0321 C98C 0322 C98C ;Jump table points to the RTS at ACK 0323 C98C 0324 C98C ;EM ($19) - Plotting 0325 C98C 0326 C98C AE 61 03 EM LDX NPIX ;Filter out non-graphics modes 0327 C98F F0 A7 BEQ JMIV25 ;[text mode] 0328 C991 4C 60 D0 JMP EMA ;Jump to graphics routines 0329 C994 0330 C994 ;Hardware scroll down 0331 C994 ;Doesn't touch cursor 0332 C994 0333 C994 ; These routines return z=0 0334 C994 0335 C994 AE 50 03 HSCRDN LDX TOPSCN ;Subt. BYTROW from TOPSCN 0336 C997 AD 51 03 LDA TOPSCN+&01 0337 C99A 20 F8 CC JSR SUBROW 0338 C99D B0 14 BCS NEWTOP ;Wraparound? No?, then done 0339 C99F 6D 54 03 ADC BYTSCN ;Yes?, then add screen length 0340 C9A2 90 0F BCC NEWTOP ;(branch always taken) 0341 C9A4 0342 C9A4 AE 50 03 HSCRUP LDX TOPSCN ;Add BYTROW to TOPSCN 0343 C9A7 AD 51 03 LDA TOPSCN+&01 0344 C9AA 20 D4 CA JSR ADDROW 0345 C9AD 10 04 BPL NEWTOP ;Wraparound? 0346 C9AF 38 SEC 0347 C9B0 ED 54 03 SBC BYTSCN ;Yes?, then subtract off screen length 0348 C9B3 8D 51 03 NEWTOP STA TOPSCN +&01 0349 C9B6 8E 50 03 STX TOPSCN 0350 C9B9 A0 0C LDYIM &0C ;Prog. START of 6845 0351 C9BB D0 51 BNE AXCRTA ;(branch always taken) 0352 C9BD 0353 C9BD ;SUB ($1A) - Sets default text 0354 C9BD ;& graphics windows. 0355 C9BD ;Homes both cursors 0356 C9BD ;Sets graphics origin to (0,0) 0357 C9BD 0358 C9BD ;Clear all window parameters, 0359 C9BD ;Both cusors, & gr. origin 0360 C9BD 0361 C9BD A9 00 SUB LDAIM &00 0362 C9BF A2 2C LDXIM VDUWS+&04-GWLCOL ;THIS VALUE LIKELY TO CHANGE ! 0363 C9C1 9D 00 03 SUBA STAAX GWLCOL 0364 C9C4 CA DEX 0365 C9C5 10 FA BPL SUBA 0366 C9C7 Acorn macro assembler Page 18 VDU File - MOS03 0367 C9C7 ;Set other parameters 0368 C9C7 0369 C9C7 AE 55 03 LDX MODE ;Get no. of char. cols. 0370 C9CA BC EF C3 LDYAX PCOLS ;How many columns ? 0371 C9CD 8C 0A 03 STY TWRCOL ;Default text window 0372 C9D0 20 88 CA JSR SETPWW ;Set the text width 0373 C9D3 BC E7 C3 LDYAX PROWS ;Get no. char. rows 0374 C9D6 8C 09 03 STY TWBROW ;Default text window 0375 C9D9 A0 03 LDYIM &03 ;GRAPHICS WINDOW Top row 0376 C9DB 8C 23 03 STY QEND 0377 C9DE C8 INY 0378 C9DF 8C 21 03 STY QEND-&02 ;right column 0379 C9E2 CE 22 03 DEC QEND-&01 ;now = $FF 0380 C9E5 CE 20 03 DEC QEND-&03 ;now = $FF 0381 C9E8 20 39 CA JSR CAN ;Transfer to window & convert co-ords 0382 C9EB A9 F7 LDAIM &F7 ;Clear bit 3 of STATS (default windows set) 0383 C9ED 20 A8 C5 JSR STTAND 0384 C9F0 AE 50 03 LDX TOPSCN ;Programme cursor 0385 C9F3 AD 51 03 LDA TOPSCN+&01 ;to top L.H. byte 0386 C9F6 8E 4A 03 CSDSPA STX CSPOSN 0387 C9F9 8D 4B 03 STA CSPOSN +&01 0388 C9FC 10 04 BPL CSDSP 0389 C9FE 38 SEC 0390 C9FF ED 54 03 SBC BYTSCN 0391 CA02 86 D8 CSDSP STX ZMEMT 0392 CA04 85 D9 STA ZMEMT +&01 0393 CA06 AE 4A 03 LDX CSPOSN 0394 CA09 AD 4B 03 LDA CSPOSN +&01 0395 CA0C A0 0E LDYIM &0E 0396 CA0E 48 AXCRTA PHA 0397 CA0F AD 55 03 LDA MODE ;Is it teletext ? 0398 CA12 C9 07 CMPIM &07 0399 CA14 68 PLA 0400 CA15 B0 10 BCS AXCRTB 0401 CA17 86 DA STX ZTEMP ;No?, then divide by 8 0402 CA19 4A LSRA 0403 CA1A 66 DA ROR ZTEMP 0404 CA1C 4A LSRA 0405 CA1D 66 DA ROR ZTEMP 0406 CA1F 4A LSRA 0407 CA20 66 DA ROR ZTEMP 0408 CA22 A6 DA LDX ZTEMP 0409 CA24 4C 2B CA JMP AXCRTC 0410 CA27 ;For TTX, fiddle the high address lines 0411 CA27 E9 74 AXCRTB SBCIM &74 ; Carry already set here 0412 CA29 49 20 EORIM &20 0413 CA2B ;Write (A) to reg. (Y) of 6845 0414 CA2B ;& (X) to reg. (Y)+1 0415 CA2B 0416 CA2B 8C 00 FE AXCRTC STY CRTCA ;Access reg. (Y) 0417 CA2E 8D 01 FE STA CRTCD ;Store MSB 0418 CA31 C8 INY ;Access reg. (Y)+1 0419 CA32 8C 00 FE STY CRTCA 0420 CA35 8E 01 FE STX CRTCD ;Store LSB 0421 CA38 60 RTS 0422 CA39 0423 CA39 ;CAN ($18) Define graphics area 0424 CA39 0425 CA39 ;QEND-7 = L.H. margin = GWLCOL Low byte 1st 0426 CA39 ;QEND-5 = Bottom row = GWBROW 0427 CA39 ;QEND-3 = R.H. margin = GWRCOL 0428 CA39 ;QEND-1 = Top row = GWTROW 0429 CA39 0430 CA39 20 81 CA CAN JSR CANB ;Swap graphics cursor with innocuous bytes in WS 0431 CA3C A2 1C LDXIM QEND-&07-V 0432 CA3E A0 2C LDYIM CDELTA-V 0433 CA40 20 11 D4 JSR TRISA ;Calculate window differences to CDELTA 0434 CA43 0D 2D 03 ORA CDELTA+&01 ;(A) returns with CDELTA+3= DeltaY, so OR with DeltaX 0435 CA46 30 39 BMI CANB ;If either is -ve, then illegal window 0436 CA48 A2 20 LDXIM QEND-&03-V ;Convert window to Ico-ords 0437 CA4A 20 49 D1 JSR EIGABS 0438 CA4D A2 1C LDXIM QEND-&07-V 0439 CA4F 20 49 D1 JSR EIGABS 0440 CA52 AD 1F 03 LDA QEND-&04 ;Are both lower margins +ve ? 0441 CA55 0D 1D 03 ORA QEND-&06 0442 CA58 30 27 BMI CANB ;No?, then illegal 0443 CA5A AD 23 03 LDA QEND ;Is Y valid ? 0444 CA5D D0 22 BNE CANB ;Only if MSB is zero 0445 CA5F AE 55 03 LDX MODE ;Is X valid ? 0446 CA62 AD 21 03 LDA QEND-&02 ;Divide by 8 & see if > no. of character cols 0447 CA65 85 DA STA ZTEMP 0448 CA67 AD 20 03 LDA QEND-&03 ;LSB of RH margin -1 0449 CA6A 46 DA LSR ZTEMP 0450 CA6C 6A RORA 0451 CA6D 46 DA LSR ZTEMP 0452 CA6F D0 10 BNE CANB 0453 CA71 6A RORA 0454 CA72 4A LSRA 0455 CA73 DD EF C3 CMPAX PCOLS 0456 CA76 F0 02 BEQ CANA 0457 CA78 10 07 BPL CANB 0458 CA7A A0 00 CANA LDYIM GWLCOL-V ;Copy to window 0459 CA7C A2 1C LDXIM QEND-&07-V ;From Q 0460 CA7E 20 7C D4 JSR COPY8 0461 CA81 A2 10 CANB LDXIM GCSR-V ;Swap GCSR with CANWS, as EIGABS corrupts this 0462 CA83 A0 28 LDYIM CANWS-V 0463 CA85 4C E6 CD JMP SWAPF 0464 CA88 0465 CA88 ;Set printer window width 0466 CA88 ;Char. width in A 0467 CA88 ;Mode in X 0468 CA88 0469 CA88 C8 SETPWW INY 0470 CA89 98 TYA 0471 CA8A A0 00 LDYIM &00 0472 CA8C 8C 4D 03 STY PWWDTH +&01 ;Clear MSB 0473 CA8F 8D 4C 03 STA PWWDTH 0474 CA92 AD 4F 03 LDA BYTCH ;How many times to shift PWWDTH left ? 0475 CA95 4A LSRA 0476 CA96 F0 09 BEQ SETPWC ;TTX? 0477 CA98 0E 4C 03 SETPWA ASL PWWDTH 0478 CA9B 2E 4D 03 ROL PWWDTH +&01 0479 CA9E 4A LSRA 0480 CA9F 90 F7 BCC SETPWA 0481 CAA1 60 SETPWC RTS ;This used to be FSFAIL & ESCFL & ESCBB as well 0482 CAA2 0483 CAA2 ;GS ($1D) Define graphics origin 0484 CAA2 0485 CAA2 ;GSA Define graphics origin 0486 CAA2 ;The co-ordinates are in external 16 bit space. This does not 0487 CAA2 ;move the windows, but does move the graphics cursors Acorn macro assembler Page 19 VDU File - MOS03 0488 CAA2 0489 CAA2 A2 20 GS LDXIM QEND-&03-V 0490 CAA4 A0 0C LDYIM ORG-V ;Copy the new origin (external co-ords) to ORGY.. 0491 CAA6 20 8A D4 JSR COPYF 0492 CAA9 4C B8 D1 JMP IEG ;Update EXTERNAL cursor 0493 CAAC 0494 CAAC ;DEL ($7F) Delete previous char 0495 CAAC 0496 CAAC 20 C5 C5 DEL JSR BS ;Move back 1 character 0497 CAAF 20 88 C5 JSR ANOMQ 0498 CAB2 D0 13 BNE DELA 0499 CAB4 AE 60 03 LDX NCOLOR 0500 CAB7 F0 09 BEQ PTTXSP ;TTX space 0501 CAB9 85 DE STA ZTEMPC ;(A)=0 from ANOMQ 0502 CABB A9 C0 LDAIM HFMSB +&01 ;Point to hard font version of space 0503 CABD 85 DF STA ZTEMPC +&01 0504 CABF 4C BF CF JMP VDUPRB 0505 CAC2 A9 20 PTTXSP LDAIM &20 ;Print TTX space 0506 CAC4 4C DC CF JMP PTTX ;OK as (X)=0 0507 CAC7 A9 7F DELA LDAIM &7F ;Point to DEL, only unprintable char. in hard font =$FF...$FF 0508 CAC9 20 3E D0 JSR CHADDR 0509 CACC AE 5A 03 LDX BGCOLF ;Force this to be graphics background colour 0510 CACF A0 00 LDYIM &00 ;Mode is STORE 0511 CAD1 4C 63 CF JMP PRANC 0512 CAD4 LNK MOS04 0001 CAD4 0002 CAD4 TTL VDU File - MOS04 0003 CAD4 OPT MOS04 Acorn macro assembler Page 20 VDU File - MOS04 0004 CAD4 ;Last revision 02/06/82 0005 CAD4 0006 CAD4 ;02/06/82 Implode/Explode font change, RESET (fonts) changed 0007 CAD4 ;26/05/82 Replace table TBZTBX with LSRA 0008 CAD4 ;19/05/82 Compress PAGEE code 0009 CAD4 ;18/05/82 Conditional coding to remove bug from PAGE 0010 CAD4 ;01/05/82 Considerable recoding for new variable order & forward queueing 0011 CAD4 ;19/04/82 BYTE squashing 0012 CAD4 ;24/03/82 Add soft font implosion & explosion 0013 CAD4 ; Change refs. to BEGSCN+1 to BEGSCN 0014 CAD4 ;08/02/82 Remove initialisation of TRMCH 0015 CAD4 ;07/01/82 Remove initialisation of VDUVEC 0016 CAD4 ;16/11 Bug fix - page mode only at bottom line of window 0017 CAD4 ;14/11 Initialisation of DOTS removed 0018 CAD4 ;28/10 Initialisation of FNTFLG 0019 CAD4 0020 CAD4 ;Get address of line below 0021 CAD4 0022 CAD4 48 ADDROW PHA 0023 CAD5 8A TXA 0024 CAD6 18 CLC 0025 CAD7 6D 52 03 ADC BYTROW 0026 CADA AA TAX 0027 CADB 68 PLA 0028 CADC 6D 53 03 ADC BYTROW +&01 0029 CADF 60 RTS 0030 CAE0 0031 CAE0 ;Is page mode on ? 0032 CAE0 0033 CAE0 ;CTRL and SHIFT keys pressed (c=1) 0034 CAE0 0035 CAE0 20 14 CB PAGEF JSR PAGED ;reset LINES, N.B. does not corrupt c 0036 CAE3 ; If c=1 => set both LEDs 0037 CAE3 20 D9 E9 PAGE JSR MOSTST ;pause if CTRL and SHIFT keys pressed 0038 CAE6 90 02 BCC PAGEE ;[CTRL not pressed] 0039 CAE8 30 F6 BMI PAGEF ;[CTRL and SHIFT keys pressed ,c=1] 0040 CAEA ; CTRL without SHIFT 0041 CAEA 0042 CAEA [ PAGEFX =0 ;TRUE if bug in page to be fixed 0043 CAEA A5 D0 PAGEE LDA STATS 0044 CAEC 49 04 EORIM &04 ;invert page mode bit 0045 CAEE 29 46 ANDIM &46 ;Exit if C.E. or scroll disabled, or not in page mode 0046 CAF0 D0 2A BNE PAGEX 0047 CAF2 | 0052 CAF2 ] 0053 CAF2 0054 CAF2 AD 69 02 LDA LINES ;Is a page printed yet ? 0055 CAF5 30 22 BMI PAGEA ;If -ve, then reset (more down scrolls than up) 0056 CAF7 ; ensure on bottom line of text window 0057 CAF7 AD 19 03 LDA CSY 0058 CAFA CD 09 03 CMP TWBROW 0059 CAFD 90 1A BCC PAGEA ;[not on bottom line of text window] 0060 CAFF ; deal with overlap 0061 CAFF 4A LSRA 0062 CB00 4A LSRA 0063 CB01 38 SEC 0064 CB02 6D 69 02 ADC LINES 0065 CB05 6D 0B 03 ADC TWTROW ;(c=0) 0066 CB08 CD 09 03 CMP TWBROW 0067 CB0B 90 0C BCC PAGEA ;No, then continue 0068 CB0D 18 CLC ;do not set LEDs on first scroll test 0069 CB0E ;wait for shift key 0070 CB0E 20 D9 E9 PAGEC JSR MOSTST 0071 CB11 38 SEC ;test LEDs on subsequent scroll tests 0072 CB12 10 FA BPL PAGEC 0073 CB14 A9 FF PAGED LDAIM &FF ;Reinitialise LINES 0074 CB16 8D 69 02 STA LINES 0075 CB19 EE 69 02 PAGEA INC LINES 0076 CB1C 60 PAGEX RTS 0077 CB1D 0078 CB1D ;INTIALISATION ROUTINE 0079 CB1D ;Initial mode in (A) 0080 CB1D 0081 CB1D 48 RESET PHA ;Push mode 0082 CB1E A2 7F LDXIM VEND-V ;Clear all variables 0083 CB20 A9 00 LDAIM &00 0084 CB22 85 D0 STA STATS 0085 CB24 9D FF 02 RESETA STAAX V-&01 0086 CB27 CA DEX 0087 CB28 D0 FA BNE RESETA 0088 CB2A ; X=0 **** AND EQ status (used by FONT) **** 0089 CB2A 20 07 CD JSR FONT ;Ensure font imploded 0090 CB2D 68 PLA ;Pull the mode back again 0091 CB2E A2 7F LDXIM &7F ;Initialise CHCSR to character for DEL 0092 CB30 8E 66 03 STX CHCSR ;and fall through to ... 0093 CB33 0094 CB33 ;MODE CHANGE 0095 CB33 0096 CB33 2C 8E 02 CHMODE BIT MODEL ;adjust according to model 0097 CB36 30 02 BMI CHMOD1 ;[model B] 0098 CB38 09 04 ORAIM &04 ;model A 0099 CB3A 29 07 CHMOD1 ANDIM &07 0100 CB3C AA TAX 0101 CB3D 8E 55 03 STX MODE ;Initialise MODE 0102 CB40 BD 14 C4 LDAAX COLMOD ;Get no. colours 0103 CB43 8D 60 03 STA NCOLOR ;=0 if TTX 0104 CB46 BD FF C3 LDAAX BYTCHT ;No. bytes / char. 0105 CB49 8D 4F 03 STA BYTCH 0106 CB4C BD 3A C4 LDAAX NPIXTB ;no. pixles per byte -1, =0 if non-graphics mode 0107 CB4F 8D 61 03 STA NPIX 0108 CB52 D0 02 BNE CHMODB 0109 CB54 A9 07 LDAIM &07 ;Initialise left and right masks for read character 0110 CB56 0A CHMODB ASLA ;Define left and right masks. PRESERVE c !!! 0111 CB57 A8 TAY 0112 CB58 B9 06 C4 LDAAY MASKTB -&01 ;Offset to right mask 0113 CB5B 8D 63 03 STA MASKR 0114 CB5E 0A CHMODC ASLA 0115 CB5F 10 FD BPL CHMODC ;Generate left most mask 0116 CB61 8D 62 03 STA MASKL ;c=0 - preserve until byte width type generated 0117 CB64 BC 40 C4 LDYAX MODETB ;Memory map type 0118 CB67 8C 56 03 STY MEMODE 0119 CB6A B9 4F C4 LDAAY CZERO ;Initialise C0 0120 CB6D 20 F8 E9 JSR CREG ;must preserve c=0 0121 CB70 B9 4B C4 LDAAY CONE 0122 CB73 20 F8 E9 JSR CREG 0123 CB76 B9 59 C4 LDAAY BYTSTA ;Total bytes dsp.'ed 0124 CB79 8D 54 03 STA BYTSCN 0125 CB7C B9 5E C4 LDAAY STSCTB ;Addr. 1st to disp'ed 0126 CB7F 8D 4E 03 STA BEGSCN 0127 CB82 98 TYA ;Get byte width type 0128 CB83 69 02 ADCIM &02 ;(c=0) Map (0,1,2,3,4) to (2,2,1,1,0) Acorn macro assembler Page 21 VDU File - MOS04 0129 CB85 49 07 EORIM &07 0130 CB87 4A LSRA 0131 CB88 AA TAX 0132 CB89 BD 66 C4 LDAAX TBZTBA ;LSB of table addr. 0133 CB8C 85 E0 STA ZTBL 0134 CB8E A9 C3 LDAIM /(HRGTB ) ;MSB of same (always the same) 0135 CB90 85 E1 STA ZTBL +&01 0136 CB92 BD 63 C4 LDAAX BYTRTA ;Byte width of row 0137 CB95 8D 52 03 STA BYTROW 0138 CB98 8E 53 03 STX BYTROW +&01 0139 CB9B A9 43 LDAIM &43 ;Preserve b6, b1 & b0 of STATS only 0140 CB9D 20 A8 C5 JSR STTAND ;Clear all others 0141 CBA0 AE 55 03 LDX MODE ;Indirect mode to mMODREG 0142 CBA3 BD F7 C3 LDAAX INDMOD ;from this table 0143 CBA6 20 00 EA JSR MVPRC0 ;as close as possible to the reprogramming of the 6845 0144 CBA9 0145 CBA9 ;PROGRAMME THE 6845 0146 CBA9 0147 CBA9 08 PHP 0148 CBAA 78 SEI 0149 CBAB BE 69 C4 LDXAY CRTCX ;Get the table to Xmt 0150 CBAE A0 0B LDYIM &0B ;No. bytes to feed it 0151 CBB0 BD 6E C4 CRTCLP LDAAX CRTCTB ;Load byte to 0152 CBB3 20 5E C9 JSR CRTCP ;Programme the 6845 and save value of cursor start 0153 CBB6 CA DEX 0154 CBB7 88 DEY 0155 CBB8 10 F6 BPL CRTCLP 0156 CBBA 28 PLP 0157 CBBB 0158 CBBB 20 39 C8 JSR DCD ;Default log.phys. cols. 0159 CBBE 20 BD C9 JSR SUB ;Clear any windowing 0160 CBC1 0161 CBC1 ;fall through to ..... 0162 CBC1 0163 CBC1 A2 00 CLATXT LDXIM &00 ;TOPSCN:=BEGSCN 0164 CBC3 AD 4E 03 LDA BEGSCN ;Load must be in this to ensure n=0, tested in CSDSPA 0165 CBC6 8E 50 03 STX TOPSCN 0166 CBC9 8D 51 03 STA TOPSCN +&01 0167 CBCC 20 F6 C9 JSR CSDSPA ;Home cursor 0168 CBCF A0 0C LDYIM &0C ;Take divided address 0169 CBD1 20 2B CA JSR AXCRTC 0170 CBD4 AD 58 03 LDA BTCOLF 0171 CBD7 AE 56 03 LDX MEMODE ;Get mem.map type 0172 CBDA BC 54 C4 LDYAX CLSCTA ;Set up jump vector 0173 CBDD 8C 5D 03 STY JVEC 0174 CBE0 A0 CC LDYIM /(CLASCA ) ;Used to be LDYAX CLSCTB 0175 CBE2 8C 5E 03 STY JVEC +&01 0176 CBE5 A2 00 LDXIM &00 0177 CBE7 8E 69 02 STX LINES ;Initialise the number of lines scrolled 0178 CBEA 8E 18 03 STX CSX 0179 CBED 8E 19 03 STX CSY 0180 CBF0 6C 5D 03 JMI JVEC 0181 CBF3 0182 CBF3 RCHDEF 0183 CBF3 20 3E D0 JSR CHADDR ;Read character definition 0184 CBF6 A0 00 LDYIM &00 ;Address character (start of defn. now in ZTEMPC) 0185 CBF8 B1 DE PRABA LDAIY ZTEMPC ;Copy definition 0186 CBFA C8 INY 0187 CBFB 91 F0 STAIY WARGS 0188 CBFD C0 08 CPYIM &08 0189 CBFF D0 F7 BNE PRABA 0190 CC01 60 RTS 0191 CC02 0192 CC02 9D 00 30 CLASCA STAAX &3000 ;Modes 1-3 (20K) 0193 CC05 9D 00 31 STAAX &3100 0194 CC08 9D 00 32 STAAX &3200 0195 CC0B 9D 00 33 STAAX &3300 0196 CC0E 9D 00 34 STAAX &3400 0197 CC11 9D 00 35 STAAX &3500 0198 CC14 9D 00 36 STAAX &3600 0199 CC17 9D 00 37 STAAX &3700 0200 CC1A 9D 00 38 STAAX &3800 0201 CC1D 9D 00 39 STAAX &3900 0202 CC20 9D 00 3A STAAX &3A00 0203 CC23 9D 00 3B STAAX &3B00 0204 CC26 9D 00 3C STAAX &3C00 0205 CC29 9D 00 3D STAAX &3D00 0206 CC2C 9D 00 3E STAAX &3E00 0207 CC2F 9D 00 3F STAAX &3F00 0208 CC32 9D 00 40 CLASCB STAAX &4000 ;Mode 3 (16k) 0209 CC35 9D 00 41 STAAX &4100 0210 CC38 9D 00 42 STAAX &4200 0211 CC3B 9D 00 43 STAAX &4300 0212 CC3E 9D 00 44 STAAX &4400 0213 CC41 9D 00 45 STAAX &4500 0214 CC44 9D 00 46 STAAX &4600 0215 CC47 9D 00 47 STAAX &4700 0216 CC4A 9D 00 48 STAAX &4800 0217 CC4D 9D 00 49 STAAX &4900 0218 CC50 9D 00 4A STAAX &4A00 0219 CC53 9D 00 4B STAAX &4B00 0220 CC56 9D 00 4C STAAX &4C00 0221 CC59 9D 00 4D STAAX &4D00 0222 CC5C 9D 00 4E STAAX &4E00 0223 CC5F 9D 00 4F STAAX &4F00 0224 CC62 9D 00 50 STAAX &5000 0225 CC65 9D 00 51 STAAX &5100 0226 CC68 9D 00 52 STAAX &5200 0227 CC6B 9D 00 53 STAAX &5300 0228 CC6E 9D 00 54 STAAX &5400 0229 CC71 9D 00 55 STAAX &5500 0230 CC74 9D 00 56 STAAX &5600 0231 CC77 9D 00 57 STAAX &5700 0232 CC7A 9D 00 58 CLASCC STAAX &5800 ;Modes 4,5 (10K) 0233 CC7D 9D 00 59 STAAX &5900 0234 CC80 9D 00 5A STAAX &5A00 0235 CC83 9D 00 5B STAAX &5B00 0236 CC86 9D 00 5C STAAX &5C00 0237 CC89 9D 00 5D STAAX &5D00 0238 CC8C 9D 00 5E STAAX &5E00 0239 CC8F 9D 00 5F STAAX &5F00 0240 CC92 9D 00 60 CLASCD STAAX &6000 ;Mode 6 (8k) 0241 CC95 9D 00 61 STAAX &6100 0242 CC98 9D 00 62 STAAX &6200 0243 CC9B 9D 00 63 STAAX &6300 0244 CC9E 9D 00 64 STAAX &6400 0245 CCA1 9D 00 65 STAAX &6500 0246 CCA4 9D 00 66 STAAX &6600 0247 CCA7 9D 00 67 STAAX &6700 0248 CCAA 9D 00 68 STAAX &6800 0249 CCAD 9D 00 69 STAAX &6900 Acorn macro assembler Page 22 VDU File - MOS04 0250 CCB0 9D 00 6A STAAX &6A00 0251 CCB3 9D 00 6B STAAX &6B00 0252 CCB6 9D 00 6C STAAX &6C00 0253 CCB9 9D 00 6D STAAX &6D00 0254 CCBC 9D 00 6E STAAX &6E00 0255 CCBF 9D 00 6F STAAX &6F00 0256 CCC2 9D 00 70 STAAX &7000 0257 CCC5 9D 00 71 STAAX &7100 0258 CCC8 9D 00 72 STAAX &7200 0259 CCCB 9D 00 73 STAAX &7300 0260 CCCE 9D 00 74 STAAX &7400 0261 CCD1 9D 00 75 STAAX &7500 0262 CCD4 9D 00 76 STAAX &7600 0263 CCD7 9D 00 77 STAAX &7700 0264 CCDA 9D 00 78 STAAX &7800 0265 CCDD 9D 00 79 STAAX &7900 0266 CCE0 9D 00 7A STAAX &7A00 0267 CCE3 9D 00 7B STAAX &7B00 0268 CCE6 9D 00 7C CLASCE STAAX &7C00 ;Mode 7 (1k = TTX) 0269 CCE9 9D 00 7D STAAX &7D00 0270 CCEC 9D 00 7E STAAX &7E00 0271 CCEF 9D 00 7F STAAX &7F00 0272 CCF2 E8 INX 0273 CCF3 F0 70 BEQ ENSCRX 0274 CCF5 6C 5D 03 RUNNER JMI JVEC 0275 CCF8 0276 CCF8 ;Get the next line up, 0277 CCF8 ;test if wraparound 0278 CCF8 ;This is here as padding 0279 CCF8 0280 CCF8 48 SUBROW PHA 0281 CCF9 8A TXA 0282 CCFA 38 SEC 0283 CCFB ED 52 03 SBC BYTROW 0284 CCFE AA TAX 0285 CCFF 68 PLA 0286 CD00 ED 53 03 SBC BYTROW +&01 0287 CD03 CD 4E 03 CMP BEGSCN 0288 CD06 FONT0 0289 CD06 60 RTS 0290 CD07 0291 CD07 FONT 0292 CD07 ; 0293 CD07 ; implode font 0294 CD07 ; 0295 CD07 A9 0F LDAIM &0F ;Fonts 1,2,3 hard (set 0). MSb not used 0296 CD09 8D 67 03 STA FNTFLG 0297 CD0C ; 0298 CD0C A9 0C LDAIM SFPAGE 0299 CD0E A0 06 LDYIM &06 ;Set Fonts 1 to 7 to page SFPAGE 0300 CD10 99 68 03 FIMPA STAAY PGSFNT 0301 CD13 88 DEY 0302 CD14 10 FA BPL FIMPA 0303 CD16 ; 0304 CD16 ; test operation type 0305 CD16 ; 0306 CD16 ; force X in range 0307 CD16 E0 07 CPXIM &07 0308 CD18 90 02 BCC FONTOK ;[X <= 6] 0309 CD1A A2 06 LDXIM &06 0310 CD1C FONTOK ;0 <= X <= 6 0311 CD1C 8E 46 02 STX FONTSW ;record font state 0312 CD1F ; 0313 CD1F AD 43 02 LDA IHWM 0314 CD22 ; 0315 CD22 ; explode fonts that lie within extension pages 0316 CD22 ; 0317 CD22 A2 00 LDXIM &00 0318 CD24 FEXPA 0319 CD24 EC 46 02 CPX FONTSW 0320 CD27 B0 0B BCS FEXPA0 0321 CD29 ; C=0 0322 CD29 BC BA C4 LDYAX FFSZOT 0323 CD2C 99 68 03 STAAY PGSFNT 0324 CD2F ; C=0 0325 CD2F 69 01 ADCIM &01 0326 CD31 E8 INX 0327 CD32 D0 F0 BNE FEXPA ;[ALWAYS jump] 0328 CD34 FEXPA0 0329 CD34 ; 0330 CD34 ;X = FONTSW 0331 CD34 8D 44 02 STA HWM 0332 CD37 ; 0333 CD37 A8 TAY 0334 CD38 F0 CC BEQ FONT0 0335 CD3A A2 11 LDXIM SVHWMC 0336 CD3C 4C 68 F1 JMP SVOP 0337 CD3F 0338 CD3F 0339 CD3F LNK MOS05 0001 CD3F 0002 CD3F TTL VDU File - MOS05 0003 CD3F OPT MOS05 Acorn macro assembler Page 23 VDU File - MOS05 0004 CD3F ; 0005 CD3F ;Last update 05/05/82 0006 CD3F 0007 CD3F ;05/05/82 RSAN corrected 0008 CD3F ;05/05/82 TADDRY changed to allow for only 1 table 0009 CD3F ;01/05/82 Recoded using new variable order & manifests 0010 CD3F ;01/05/82 Recode for new order of variables 0011 CD3F ;22/04/82 Encode ADDSCN & SUBSCN 0012 CD3F ;19/04/82 Comments added plus small byte squash 0013 CD3F ;25/03/82 Change all refs. to BEGSCN+1 to BEGSCN 0014 CD3F 0015 CD3F ;Account for scroll disabling if needs be 0016 CD3F ;Requires c=1 if scroll DOWN (cursor up) & vice versa 0017 CD3F ;If scroll enabled (b1 of STATS =0) adjusts PCSY unless on a margin 0018 CD3F ;If scroll disabled, wraps cursor, pulls return address from stack 0019 CD3F ;and jumps to CSDA. 0020 CD3F 0021 CD3F A9 02 ENSCRL LDAIM &02 ;Is scroll disabled ? 0022 CD41 24 D0 BIT STATS 0023 CD43 D0 02 BNE ENSCRM ;Yes?, then skip 0024 CD45 50 32 BVC ENSCRR ;Or is CE set ? 0025 CD47 AD 09 03 ENSCRM LDA TWBROW ;Assume scroll up (so go to bottom row) 0026 CD4A 90 03 BCC ENSCRN ;Unless c=1 0027 CD4C AD 0B 03 LDA TWTROW ;Whence scroll DOWN (& go to top row) 0028 CD4F 70 08 ENSCRN BVS ENSCRO ;If OUTPUT cursor, skip 0029 CD51 8D 19 03 STA CSY ;(this assumes windows are rectangular!) 0030 CD54 68 PLA ;Cheat return stack 0031 CD55 68 PLA 0032 CD56 4C AF C6 JMP CSDA 0033 CD59 08 ENSCRO PHP ;To preserve carry 0034 CD5A CD 65 03 CMP PCSY ;Would the input cursor like to go off screen ? 0035 CD5D F0 19 BEQ ENSCRP ;Yes?, then don't readdress it 0036 CD5F 28 PLP ;Restore the carry, to see which way to go 0037 CD60 90 04 BCC ENSCRQ 0038 CD62 CE 65 03 DEC PCSY ;Scroll DOWN, so follow it down 0039 CD65 60 ENSCRX RTS ;May be referenced from MOS04 0040 CD66 EE 65 03 ENSCRQ INC PCSY ;Scroll UP, so go up as well 0041 CD69 60 RTS 0042 CD6A 0043 CD6A ;OCSRDL Delete output cursor 0044 CD6A 0045 CD6A 08 OCSRDL PHP 0046 CD6B 48 PHA 0047 CD6C AC 4F 03 LDY BYTCH 0048 CD6F 88 DEY ;TTX? 0049 CD70 D0 1D BNE OCSRIV ;Not TTX?, then same as writing cursor, as it inverts 0050 CD72 AD 38 03 LDA TTXTMP ;TTX?, then write remebered byte 0051 CD75 91 D8 STAIY ZMEMT ;(Y)=0 0052 CD77 68 OCSREX PLA ;& exit 0053 CD78 28 ENSCRP PLP ;Get the stack correct 0054 CD79 60 ENSCRR RTS 0055 CD7A 0056 CD7A ;OCSRWR Write output cursor 0057 CD7A 0058 CD7A 08 OCSRWR PHP 0059 CD7B 48 PHA 0060 CD7C AC 4F 03 LDY BYTCH 0061 CD7F 88 DEY ;TTX? 0062 CD80 D0 0D BNE OCSRIV 0063 CD82 B1 D8 LDAIY ZMEMT ;(Y)=0 Yes?, then read byte directly from screen 0064 CD84 8D 38 03 STA TTXTMP ;and store it out of harm's way (no plotting in this mode) 0065 CD87 AD 66 03 LDA CHCSR ;Write the cursor 0066 CD8A 91 D8 STAIY ZMEMT ;(Y)=0 0067 CD8C 4C 77 CD JMP OCSREX 0068 CD8F A9 FF OCSRIV LDAIM &FF 0069 CD91 C0 1F CPYIM &1F ;Mode 2 ? 0070 CD93 D0 02 BNE OCSRIW 0071 CD95 A9 3F LDAIM INVSXT ;Yes?, then don't invert the flashing bit 0072 CD97 85 DA OCSRIW STA ZTEMP 0073 CD99 B1 D8 OCSRIU LDAIY ZMEMT ;Invert the character cell 0074 CD9B 45 DA EOR ZTEMP 0075 CD9D 91 D8 STAIY ZMEMT 0076 CD9F 88 DEY 0077 CDA0 10 F7 BPL OCSRIU 0078 CDA2 30 D3 BMI OCSREX ; Branch always 0079 CDA4 0080 CDA4 ;Soft scrolling (non-anom.) 0081 CDA4 0082 CDA4 ;Scroll DOWN 0083 CDA4 0084 CDA4 20 5B CE SSCRDN JSR SSCRIN ;Initialise 0085 CDA7 AD 09 03 LDA TWBROW ;1st receive address is bottom LH point 0086 CDAA 8D 19 03 STA CSY ;(CSX initialised in SSCRIN) 0087 CDAD 20 06 CF JSR TADDRY ;address bottom LH point (guaranteed in window) 0088 CDB0 20 F8 CC SSCRDA JSR SUBROW ;Get the address of the LH point of the next line up 0089 CDB3 B0 03 BCS SSCRDB ;Wraparound between these two lines? NO, then continue 0090 CDB5 6D 54 03 ADC BYTSCN ;Yes,then add screen and note we must scroll slowly! 0091 CDB8 85 DB SSCRDB STA ZTEMP +&01 ;store transmit address 0092 CDBA 86 DA STX ZTEMP 0093 CDBC 85 DC STA ZTEMPB ;& MSB of next receive address (LSB is not changed) 0094 CDBE B0 06 BCS SSCRDE ;c unchanged since just after SSCRDA 0095 CDC0 20 73 CE SSCRDC JSR SSCRS ;Scroll slowly ! 0096 CDC3 4C CE CD JMP SSCRDD 0097 CDC6 20 F8 CC SSCRDE JSR SUBROW ;Get next line up 0098 CDC9 90 F5 BCC SSCRDC ;Wraparound occured ?, then slow scroll to be safe 0099 CDCB 20 38 CE JSR XMIT ;Scroll fast is possible 0100 CDCE A5 DC SSCRDD LDA ZTEMPB ;MSB of next receive address 0101 CDD0 A6 DA LDX ZTEMP ;LSB of same 0102 CDD2 85 D9 STA ZMEMT +&01 ;Initialise next receive address 0103 CDD4 86 D8 STX ZMEMT 0104 CDD6 C6 DE DEC ZTEMPC ;Any more lines to copy ? 0105 CDD8 D0 D6 BNE SSCRDA ;Don't bother to copy last line 0106 CDDA A2 28 SSCREX LDXIM SSWS-V ;Preserve or restore current text cursor 0107 CDDC A0 18 LDYIM CSX-V 0108 CDDE A9 02 SWAP2 LDAIM &02 0109 CDE0 D0 06 BNE SWAP 0110 CDE2 A2 24 SWAPB LDXIM GCSIR-V ;SPLOTY requires c preserved 0111 CDE4 A0 14 SWAPC LDYIM OLDCS-V 0112 CDE6 0113 CDE6 ;SWAPF swaps 4 bytes between (V)+(X) & (V)+(Y) 0114 CDE6 0115 CDE6 A9 04 SWAPF LDAIM &04 ;by falling through to ... 0116 CDE8 0117 CDE8 ;SWAP swaps (A) bytes between (V)+(X) & (V)+(Y) 0118 CDE8 0119 CDE8 85 DA SWAP STA ZTEMP 0120 CDEA BD 00 03 SWAPA LDAAX V 0121 CDED 48 PHA 0122 CDEE B9 00 03 LDAAY V 0123 CDF1 9D 00 03 STAAX V 0124 CDF4 68 PLA Acorn macro assembler Page 24 VDU File - MOS05 0125 CDF5 99 00 03 STAAY V 0126 CDF8 E8 INX 0127 CDF9 C8 INY 0128 CDFA C6 DA DEC ZTEMP 0129 CDFC D0 EC BNE SWAPA 0130 CDFE 60 RTS 0131 CDFF 0132 CDFF 0133 CDFF ;Soft scroll UP 0134 CDFF 0135 CDFF 20 5B CE SSCRUP JSR SSCRIN ;Initialise 0136 CE02 AC 0B 03 LDY TWTROW ;Receive from top line, LH column 0137 CE05 8C 19 03 STY CSY 0138 CE08 20 06 CF JSR TADDRY ;Get 1st receive address (point guaranteed in window) 0139 CE0B 20 D4 CA SSCRUA JSR ADDROW ;Get line below 0140 CE0E 10 04 BPL SSCRUE ;Wraparound ? 0141 CE10 38 SEC ;Yes, then correct and scroll slowly 0142 CE11 ED 54 03 SBC BYTSCN 0143 CE14 85 DB SSCRUE STA ZTEMP +&01 ;Transmit address 0144 CE16 86 DA STX ZTEMP 0145 CE18 85 DC STA ZTEMPB ;MSB of next receive addr., LSB is preserved 0146 CE1A 90 06 BCC SSCRUB ;(c unchanged since just after SSCRUA) 0147 CE1C 20 73 CE SSCRUC JSR SSCRS ;Scroll slowly 0148 CE1F 4C 2A CE JMP SSCRUD 0149 CE22 20 D4 CA SSCRUB JSR ADDROW ;Get next line down 0150 CE25 30 F5 BMI SSCRUC ;Wraparound ?, then scroll slowly to be safe 0151 CE27 20 38 CE JSR XMIT ;No?, then we can scroll fast 0152 CE2A A5 DC SSCRUD LDA ZTEMPB ;Load next receive address 0153 CE2C A6 DA LDX ZTEMP 0154 CE2E 85 D9 STA ZMEMT +&01 ;and store it 0155 CE30 86 D8 STX ZMEMT 0156 CE32 C6 DE DEC ZTEMPC ;any more lines to copy ? 0157 CE34 D0 D5 BNE SSCRUA ;don't bother with the last line 0158 CE36 F0 A2 BEQ SSCREX ; Jump always 0159 CE38 0160 CE38 ;XMIT - Fast soft scroll 0161 CE38 ;Copy PWWDTH bytes from (ZTEMP) to (ZMEMT) 0162 CE38 0163 CE38 AE 4D 03 XMIT LDX PWWDTH +&01 ;How many pages? 0164 CE3B F0 10 BEQ XMITB ;None?, then attempt fractional 0165 CE3D A0 00 LDYIM &00 0166 CE3F B1 DA XMITA LDAIY ZTEMP ;Inner loop - copy complete page 0167 CE41 91 D8 STAIY ZMEMT 0168 CE43 C8 INY 0169 CE44 D0 F9 BNE XMITA 0170 CE46 E6 D9 INC ZMEMT +&01 ;Prepare to copy next page 0171 CE48 E6 DB INC ZTEMP +&01 0172 CE4A CA DEX ;Any more complete pages to copy ? 0173 CE4B D0 F2 BNE XMITA 0174 CE4D AC 4C 03 XMITB LDY PWWDTH ;Copy fractional page? 0175 CE50 F0 08 BEQ XMITD ;No?, then exit 0176 CE52 88 XMITC DEY 0177 CE53 B1 DA LDAIY ZTEMP ;Yes?, then do so 0178 CE55 91 D8 STAIY ZMEMT 0179 CE57 98 TYA 0180 CE58 D0 F8 BNE XMITC 0181 CE5A 60 XMITD RTS ;Referenced below 0182 CE5B 0183 CE5B ;SSCRIN Soft scroll initialisation 0184 CE5B 0185 CE5B ;(SSWS) := (CSX)(CSY) 0186 CE5B ;(CSX) := (TWLCOL) 0187 CE5B ;(ZTEMPC) := No. of rows to scroll, minus one 0188 CE5B 0189 CE5B 20 DA CD SSCRIN JSR SSCREX ;Store current text cursor for future reference 0190 CE5E 38 SEC ;Determine no. of rows to scroll 0191 CE5F AD 09 03 LDA TWBROW ;i.e. no. rows in window minus 1 0192 CE62 ED 0B 03 SBC TWTROW 0193 CE65 85 DE STA ZTEMPC 0194 CE67 D0 05 BNE SSCRIM 0195 CE69 68 PLA ;If zero lines to scroll, then cheat stack 0196 CE6A 68 PLA 0197 CE6B 4C DA CD JMP SSCREX ;& restore cursor 0198 CE6E 0199 CE6E AD 08 03 SSCRIM LDA TWLCOL ;Put x cursor on LH margin 0200 CE71 10 70 BPL CLTLND 0201 CE73 0202 CE73 0203 CE73 ;SSCRS Slow soft scroll 0204 CE73 ;Scrolls 1 row of characters, one by one from (ZTEMP) to (ZMEMT), 0205 CE73 ;preserving the LSB of ZTEMP. 0206 CE73 ;Requires that ZMEMT & ZTEMP be juxtaposed. 0207 CE73 ;Checks for wraparound after each character is copied 0208 CE73 0209 CE73 A5 DA SSCRS LDA ZTEMP ;Push LSB of ZTEMP 0210 CE75 48 PHA 0211 CE76 38 SEC ;Calc no. chars to copy -1 0212 CE77 AD 0A 03 LDA TWRCOL 0213 CE7A ED 08 03 SBC TWLCOL 0214 CE7D 85 DF STA ZTEMPC +&01 ;No. of columns to be scrolled (for loop) 0215 CE7F AC 4F 03 SSCRSA LDY BYTCH 0216 CE82 88 DEY 0217 CE83 B1 DA SSCRSB LDAIY ZTEMP ;~~~ Copy 1 character ~~~ 0218 CE85 91 D8 STAIY ZMEMT ;by copying (BYTCH) consecutive bytes 0219 CE87 88 DEY 0220 CE88 10 F9 BPL SSCRSB 0221 CE8A A2 02 LDXIM &02 ;Now add BYTCH to ZMEMT & ZTEMP, 0222 CE8C 18 SSCRSC CLC ;checking for wraparound on both 0223 CE8D B5 D8 LDAZX ZMEMT ;uses ZX mode, hence need for ZMEMT to be next to ZTEMP 0224 CE8F 6D 4F 03 ADC BYTCH 0225 CE92 95 D8 STAZX ZMEMT 0226 CE94 B5 D9 LDAZX ZMEMT +&01 0227 CE96 69 00 ADCIM &00 0228 CE98 10 04 BPL SSCRSD ;Did wraparound occur? 0229 CE9A 38 SEC 0230 CE9B ED 54 03 SBC BYTSCN 0231 CE9E 95 D9 SSCRSD STAZX ZMEMT +&01 0232 CEA0 CA DEX 0233 CEA1 CA DEX 0234 CEA2 F0 E8 BEQ SSCRSC ;(Do ZMEMT) 0235 CEA4 C6 DF DEC ZTEMPC +&01 ;Any more characters? 0236 CEA6 10 D7 BPL SSCRSA 0237 CEA8 68 PLA ;Restore LSB of ZMEMT 0238 CEA9 85 DA STA ZTEMP 0239 CEAB 60 RTS 0240 CEAC 0241 CEAC ;Clear the line of text addressed by CSY 0242 CEAC ;Preserve CSY & CSX 0243 CEAC 0244 CEAC AD 18 03 CLTLIN LDA CSX ;Push the current X cursor position 0245 CEAF 48 PHA Acorn macro assembler Page 25 VDU File - MOS05 0246 CEB0 20 6E CE JSR SSCRIM ;CSX = Left margin of window 0247 CEB3 20 06 CF JSR TADDRY ;Init. ZMEMT 0248 CEB6 38 SEC 0249 CEB7 AD 0A 03 LDA TWRCOL 0250 CEBA ED 08 03 SBC TWLCOL 0251 CEBD 85 DC STA ZTEMPB ;Column count 0252 CEBF AD 58 03 CLTLNA LDA BTCOLF ;get colour 0253 CEC2 AC 4F 03 LDY BYTCH ;Bytes / character 0254 CEC5 88 CLTNB DEY ;Inner loop - clear one character cell 0255 CEC6 91 D8 STAIY ZMEMT ;(preserves z from previous DEY) 0256 CEC8 D0 FB BNE CLTNB ;1 char cell 0257 CECA 8A TXA ;Update ZMEMT 0258 CECB 18 CLC 0259 CECC 6D 4F 03 ADC BYTCH 0260 CECF AA TAX 0261 CED0 A5 D9 LDA ZMEMT +&01 0262 CED2 69 00 ADCIM &00 0263 CED4 10 04 BPL CLNLC ;Wraparound ? 0264 CED6 38 SEC ;Yes, then subtract off the number of bytes per screen 0265 CED7 ED 54 03 SBC BYTSCN 0266 CEDA 86 D8 CLNLC STX ZMEMT 0267 CEDC 85 D9 STA ZMEMT +&01 0268 CEDE C6 DC DEC ZTEMPB ;One less character to clear 0269 CEE0 10 DD BPL CLTLNA ;Any more? 0270 CEE2 68 PLA 0271 CEE3 8D 18 03 CLTLND STA CSX 0272 CEE6 38 FAIL SEC 0273 CEE7 60 RTS 0274 CEE8 0275 CEE8 ;Addresses CSX,CSY to memory locn. on screen. 0276 CEE8 ;Checks that CSX & CSY are in window 0277 CEE8 ;Returns with no action and c=1 if outside. 0278 CEE8 ;If OK, initialises ZMEMT and CSPOSN 0279 CEE8 ;Exits with cursor address in (AX) 0280 CEE8 ;For cursor display, follow immediately with 0281 CEE8 ;JSR CSDSP 0282 CEE8 0283 CEE8 AE 18 03 TADDR LDX CSX ;Check window of CSX 0284 CEEB EC 08 03 CPX TWLCOL ;Lower than LH margin ? 0285 CEEE 30 F6 BMI FAIL 0286 CEF0 EC 0A 03 CPX TWRCOL ;Higher than RH edge ? 0287 CEF3 F0 02 BEQ TADDRX 0288 CEF5 10 EF BPL FAIL 0289 CEF7 AE 19 03 TADDRX LDX CSY ;Check CSY 0290 CEFA EC 0B 03 CPX TWTROW 0291 CEFD 30 E7 BMI FAIL 0292 CEFF EC 09 03 CPX TWBROW 0293 CF02 F0 02 BEQ TADDRY 0294 CF04 10 E0 BPL FAIL 0295 CF06 0296 CF06 ;End of windowing, now calc. memory posn. 0297 CF06 ;As TADDR with no bounds checking 0298 CF06 ;Returns carry clear 0299 CF06 0300 CF06 AD 19 03 TADDRY LDA CSY ;Twice row no. to Y 0301 CF09 0A ASLA 0302 CF0A A8 TAY ;(c=0 at this point) 0303 CF0B B1 E0 LDAIY ZTBL ;MSB 0304 CF0D 85 D9 STA ZMEMT+&01 0305 CF0F C8 INY 0306 CF10 A9 02 LDAIM &02 0307 CF12 2D 56 03 AND MEMODE ;Non-zero if table offset is to be halved 0308 CF15 08 PHP 0309 CF16 B1 E0 LDAIY ZTBL ;LSB 0310 CF18 28 PLP 0311 CF19 F0 03 BEQ TADDRH 0312 CF1B 46 D9 LSR ZMEMT+&01 0313 CF1D 6A RORA 0314 CF1E 6D 50 03 TADDRH ADC TOPSCN ;c=0 Add LSB 0315 CF21 85 D8 STA ZMEMT 0316 CF23 A5 D9 LDA ZMEMT+&01 ;Add MSB 0317 CF25 6D 51 03 ADC TOPSCN+&01 0318 CF28 A8 TAY ;Xfr MSB to Y 0319 CF29 ;Mpy. CSX by BYTCH 0320 CF29 AD 18 03 LDA CSX 0321 CF2C AE 4F 03 LDX BYTCH ;Is it TTX ? 0322 CF2F CA DEX 0323 CF30 F0 12 BEQ TADDRE ;Skip mult. if TTX 0324 CF32 E0 0F CPXIM &0F ;4 colour (16 bytes) ? 0325 CF34 F0 03 BEQ TADDRF 0326 CF36 90 02 BCC TADDRG ;Less ? Then 2 colour 0327 CF38 0A ASLA ;Must have been 16 colour 0328 CF39 0A TADDRF ASLA ;4 colour 0329 CF3A 0A TADDRG ASLA ;2 colour 0330 CF3B 0A ASLA 0331 CF3C 90 02 BCC TADDRB 0332 CF3E C8 INY ;c=1?, then inc. MSB by 2 0333 CF3F C8 INY 0334 CF40 0A TADDRB ASLA 0335 CF41 90 02 BCC TADDRC 0336 CF43 C8 INY ;c=1, then inc. MSB by 1 0337 CF44 18 TADDRE CLC 0338 CF45 65 D8 TADDRC ADC ZMEMT ;(c=0), add LSB of row offset 0339 CF47 85 D8 STA ZMEMT 0340 CF49 8D 4A 03 STA CSPOSN 0341 CF4C AA TAX ;LSB is returned by this routine in X 0342 CF4D 98 TYA ;MSB to A 0343 CF4E 69 00 ADCIM &00 0344 CF50 8D 4B 03 STA CSPOSN +&01 ;Store to cursor before wraparound 0345 CF53 10 04 BPL TADDRD ;Wraparound ? 0346 CF55 38 SEC ;Yes, then subt. scn. 0347 CF56 ED 54 03 SBC BYTSCN 0348 CF59 85 D9 TADDRD STA ZMEMT +&01 ;Store physical address to ZMEMT 0349 CF5B 18 CLC ;indicate successful addressing 0350 CF5C 60 RTS 0351 CF5D 0352 CF5D ;PRINT CHARACTER TO VDU 0353 CF5D 0354 CF5D 0355 CF5D 0356 CF5D 0357 CF5D ;ANOMALOUS PRINTING 0358 CF5D 0359 CF5D AE 59 03 PRANM LDX FGCOLF ;Printing to be in foreground graphics colour 0360 CF60 AC 5B 03 LDY GPLFMD ;In the current foreground colour mode 0361 CF63 20 B3 D0 PRANC JSR SETZG ;Initialise ZGORA & ZGEOR 0362 CF66 0363 CF66 ;The graphics cursor is copied to 2 locations, APCS1 0364 CF66 ;and APCS2 . The latter is left untouched until the end of the printing, 0365 CF66 ;when it is restored to the GCSIY. The former is copied to the GCSIY 0366 CF66 ;after every column of pixels is printed, with the X cursor incremented Acorn macro assembler Page 26 VDU File - MOS05 0367 CF66 ;each time. 0368 CF66 0369 CF66 20 86 D4 JSR COPYFA ;Copy GCSIY to APCS2 ... 0370 CF69 A0 00 LDYIM &00 ;Initialise row counter 0371 CF6B 84 DC PRANMC STY ZTEMPB 0372 CF6D A4 DC LDY ZTEMPB 0373 CF6F B1 DE LDAIY ZTEMPC ;Anything to do ? 0374 CF71 F0 13 BEQ PRANMG ;No, then skip 0375 CF73 85 DD STA ZTEMPB +&01 0376 CF75 10 03 PRANMA BPL PRANMD 0377 CF77 20 E3 D0 JSR WPLOTA ;Yes, then plot if inside window 0378 CF7A EE 24 03 PRANMD INC GCSIX ;Increment X cursor 0379 CF7D D0 03 BNE PRANME 0380 CF7F EE 25 03 INC GCSIX +&01 0381 CF82 06 DD PRANME ASL ZTEMPB +&01 0382 CF84 D0 EF BNE PRANMA 0383 CF86 A2 28 PRANMG LDXIM APCS1-V ;Restore previous x cursor 0384 CF88 A0 24 LDYIM GCSIR-V 0385 CF8A 20 82 D4 JSR COPY2 0386 CF8D AC 26 03 LDY GCSIY ;Decrement Igraphics Y cursor 0387 CF90 D0 03 BNE PRANMF 0388 CF92 CE 27 03 DEC GCSIY +&01 0389 CF95 CE 26 03 PRANMF DEC GCSIY 0390 CF98 A4 DC LDY ZTEMPB ;Do next row 0391 CF9A C8 INY 0392 CF9B C0 08 CPYIM &08 0393 CF9D D0 CC BNE PRANMC 0394 CF9F A2 28 LDXIM APCS1 ;Finished, so restore grpahics cursor 0395 CFA1 A0 24 LDYIM GCSIR-V 0396 CFA3 4C 8A D4 JMP COPYF ; (branch always taken) 0397 CFA6 0398 CFA6 ;RSAN Anomalous cursor home 0399 CFA6 0400 CFA6 A2 06 RSAN LDXIM GWTROW-V ;Copy GWLCOL to GCSIR 0401 CFA8 A0 26 LDYIM GCSIY-V 0402 CFAA 20 82 D4 JSR COPY2 ;Copy 4 bytes of RAM saves 2 bytes of ROM 0403 CFAD 0404 CFAD ;& fall through to ... 0405 CFAD 0406 CFAD 0407 CFAD ;CRAN Anomalous carriage return 0408 CFAD 0409 CFAD A2 00 CRAN LDXIM GWLCOL-V ;Copy GWLCOL to GCSIX 0410 CFAF A0 24 LDYIM GCSIX-V 0411 CFB1 20 82 D4 JSR COPY2 0412 CFB4 4C B8 D1 JMP IEG 0413 CFB7 0414 CFB7 ;NON-ANOMALOUS 0415 CFB7 0416 CFB7 ;Character to be printed in (A) 0417 CFB7 0418 CFB7 ;Set up address of bytes to be 0419 CFB7 ;copied from soft font. Result 0420 CFB7 ;to ZTEMP 0421 CFB7 0422 CFB7 AE 60 03 VDUPR LDX NCOLOR ;TTX? 0423 CFBA F0 20 BEQ PTTX 0424 CFBC 20 3E D0 JSR CHADDR ;Point (ZTEMPC) to character in soft font 0425 CFBF AE 60 03 VDUPRB LDX NCOLOR ;Because CHADDR now destroys (X) 0426 CFC2 A5 D0 LDA STATS ;Is this anomalous printing ? 0427 CFC4 29 20 ANDIM &20 0428 CFC6 D0 95 BNE PRANM ;Anom. printing 0429 CFC8 0430 CFC8 ;Now select the mode 0431 CFC8 0432 CFC8 A0 07 LDYIM &07 ;No. rows (except TTX) 0433 CFCA E0 03 CPXIM &03 0434 CFCC F0 20 BEQ PFOUR ;4 colour mode ? 0435 CFCE B0 4E BCS PSXTN ;16 colour mode ? 0436 CFD0 0437 CFD0 ;TWO colour mode 0438 CFD0 0439 CFD0 B1 DE PTWO LDAIY ZTEMPC 0440 CFD2 05 D2 ORA ZORA 0441 CFD4 45 D3 EOR ZEOR 0442 CFD6 91 D8 STAIY ZMEMT 0443 CFD8 88 DEY 0444 CFD9 10 F5 BPL PTWO 0445 CFDB 60 RTS 0446 CFDC 0447 CFDC ;TELETEXT mode 0448 CFDC 0449 CFDC A0 02 PTTX LDYIM &02 ;Transform these three wretched characters again 0450 CFDE D9 B6 C4 PTTXA CMPAY TTXTB 0451 CFE1 F0 06 BEQ PTTXC 0452 CFE3 88 DEY 0453 CFE4 10 F8 BPL PTTXA 0454 CFE6 81 D8 PTTXB STAIX ZMEMT ;as (X)=0 0455 CFE8 60 RTS 0456 CFE9 B9 B7 C4 PTTXC LDAAY TTXTB +&01 ;Cheat as $23->$5F->$60->$23 0457 CFEC D0 F8 BNE PTTXB ;(branch always taken) 0458 CFEE 0459 CFEE ;FOUR colour mode 0460 CFEE 0461 CFEE B1 DE PFOUR LDAIY ZTEMPC ;Get bit pattern 0462 CFF0 48 PHA ;Push for L.S.Nybble 0463 CFF1 4A LSRA 0464 CFF2 4A LSRA 0465 CFF3 4A LSRA 0466 CFF4 4A LSRA 0467 CFF5 AA TAX 0468 CFF6 BD 1F C3 LDAAX BPFTB ;Get expanded patten 0469 CFF9 05 D2 ORA ZORA ;of M.S.Nybble 0470 CFFB 45 D3 EOR ZEOR 0471 CFFD 91 D8 STAIY ZMEMT 0472 CFFF 98 TYA 0473 D000 18 CLC 0474 D001 69 08 ADCIM &08 ;Access next char. cell 0475 D003 A8 TAY 0476 D004 68 PLA ;Get L.S.Nybble 0477 D005 29 0F ANDIM &0F 0478 D007 AA TAX 0479 D008 BD 1F C3 LDAAX BPFTB 0480 D00B 05 D2 ORA ZORA 0481 D00D 45 D3 EOR ZEOR 0482 D00F 91 D8 STAIY ZMEMT 0483 D011 98 TYA 0484 D012 E9 08 SBCIM &08 ;c=0, thus subt. 9 0485 D014 A8 TAY 0486 D015 10 D7 BPL PFOUR 0487 D017 60 PSXTC RTS ;Also used by PSXTN Acorn macro assembler Page 27 VDU File - MOS05 0488 D018 0489 D018 ;SIXTEEN colour mode 0490 D018 0491 D018 98 PSXTB TYA ;Ref.the 1st cell again 0492 D019 E9 21 SBCIM &21 ;As c=1 0493 D01B 30 FA BMI PSXTC ;Finished ? 0494 D01D A8 TAY ;No, then carry on .. 0495 D01E 0496 D01E B1 DE PSXTN LDAIY ZTEMPC ;Get bit pattern 0497 D020 85 DC STA ZTEMPB ;For Rotate lefts 0498 D022 38 SEC ;Marker bit,=1 1st time only 0499 D023 A9 00 PSXTA LDAIM &00 0500 D025 26 DC ROL ZTEMPB ;ROL to include marker 0501 D027 F0 EF BEQ PSXTB ;Finished ? 0502 D029 2A ROLA 0503 D02A 06 DC ASL ZTEMPB 0504 D02C 2A ROLA ;c=0 here, (A)=next 2 bits 0505 D02D AA TAX ;Get expanded bit pattern 0506 D02E BD 2F C3 LDAAX BPSTB 0507 D031 05 D2 ORA ZORA 0508 D033 45 D3 EOR ZEOR 0509 D035 91 D8 STAIY ZMEMT 0510 D037 18 CLC 0511 D038 98 TYA ;Access next char. cell 0512 D039 69 08 ADCIM &08 ;c=0 before & after 0513 D03B A8 TAY 0514 D03C 90 E5 BCC PSXTA ;(branch always taken) 0515 D03E 0516 D03E ;Addresses character in soft font. 0517 D03E ;Takes (ascii) value in A, multiplies by 8, adds appropriate font address 0518 D03E ;(assumed to be on page boudary), and puts result to ZTEMPC. 0519 D03E ;This addresses top row of character, subsequent rows being in the 0520 D03E ;following 7 bytes. 0521 D03E 0522 D03E 0A CHADDR ASLA ;ZTEMPC:=8*CHAR. + MSB of font 0523 D03F 2A ROLA 0524 D040 2A ROLA 0525 D041 85 DE STA ZTEMPC ;Store LSB of addr. with bits 0-2 the low bits of the high addr. 0526 D043 29 03 ANDIM &03 ;Get page number of character 0527 D045 2A ROLA 0528 D046 AA TAX 0529 D047 29 03 ANDIM &03 0530 D049 69 BF ADCIM HFMSB ;MSB of hard font - overwrite if soft font (c=0 from last ROLA) 0531 D04B A8 TAY 0532 D04C BD 0D C4 LDAAX BITTBL ;Which bit in the flag byte is to be tested 0533 D04F 2C 67 03 BIT FNTFLG ;Test to see if soft or hard font 0534 D052 F0 03 BEQ CHADDS ;Clear, thus hard font 0535 D054 BC 67 03 LDYAX PGSFNT -&01 ;Load soft font page number 0536 D057 84 DF CHADDS STY ZTEMPC +&01 ;Store MSByte 0537 D059 A5 DE LDA ZTEMPC 0538 D05B 29 F8 ANDIM &F8 ;LSB of address 0539 D05D 85 DE STA ZTEMPC 0540 D05F 60 RTS 0541 D060 LNK MOS06 0001 D060 0002 D060 TTL VDU File - MOS06 0003 D060 OPT MOS06 Acorn macro assembler Page 28 VDU File - MOS06 0004 D060 0005 D060 ;Last revision 15/05/82 0006 D060 0007 D060 ;15/06/82 Adjust bad plot mode indirection code 0008 D060 ;05/05/82 GADDR converted such that it takes only 1 table. 0009 D060 ; Moved to MOS11 0010 D060 ;01/05/82 Recode to allow for new order of variables 0011 D060 ;21/04/82 Conditional assembly of start/end point double plotting. 0012 D060 ;22/01/82 Provide EIGABS 0013 D060 ;07/01/82 Put X to LSB of pointer 0014 D060 0015 D060 ;******* PLOTTING ******* 0016 D060 0017 D060 ;Prologue - converts from external to internal 0018 D060 ;co-ords, and distinguishes between types of 0019 D060 ;line & triangles 0020 D060 0021 D060 A2 20 EMA LDXIM NEWPT-V ;Convert external to internal 0022 D062 20 4D D1 JSR EIG ;for the 4 bytes starting at Q 0023 D065 AD 1F 03 LDA PLMODE ;Get plot mode 0024 D068 C9 04 CMPIM &04 ;BASIC's MOVE command 0025 D06A F0 6D BEQ EMAEX 0026 D06C A0 05 LDYIM &05 ;Point to do damn' all mode (for plotting that produces no change) 0027 D06E 29 03 ANDIM &03 0028 D070 F0 0E BEQ EMAA ;No change, then exit 0029 D072 4A LSRA ;Is it odd ? 0030 D073 B0 03 BCS EMAF ;No?, then invert 0031 D075 88 DEY ;(Y) = 4. Point to INVERT values of table 0032 D076 D0 08 BNE EMAA ;(Branch always taken) 0033 D078 AA EMAF TAX 0034 D079 BC 5B 03 LDYAX GPLFMD 0035 D07C BD 59 03 LDAAX FGCOLF 0036 D07F AA TAX 0037 D080 20 B3 D0 EMAA JSR SETZG 0038 D083 0039 D083 ;What's to be done ? 0040 D083 0041 D083 AD 1F 03 LDA PLMODE ;Get plot mode 0042 D086 ;* TAY 0043 D086 30 23 BMI EXGREF ;Negative, then reference external routine 0044 D088 0A ASLA ;Get type of operation 0045 D089 10 3B BPL EMAD ;Is it a line? 0046 D08B 29 F0 ANDIM &F0 ;Get rid of irrelevant data 0047 D08D 0A ASLA ;Is it point ($80, will be shifted out) ? 0048 D08E F0 46 BEQ EMAC 0049 D090 49 40 EORIM &40 ;Triangles? 0050 D092 F0 14 BEQ EMAG 0051 D094 48 PHA 0052 D095 20 DC D0 JSR EMAEY ;Copy newpoint to internal cursor 0053 D098 68 PLA 0054 D099 49 60 EORIM &60 ;SPLOT 0055 D09B F0 11 BEQ EME ;($60=$20 EOR $40) 0056 D09D C9 40 CMPIM &40 ;SPLOT looking for b/g ($60 = $40 EOR $60 EOR $40) 0057 D09F D0 0A BNE EXGREF 0058 D0A1 A9 02 LDAIM &02 ;This is what is EORed with the flag register 0059 D0A3 85 DC STA ZTEMPB 0060 D0A5 4C 06 D5 JMP SCHEAT 0061 D0A8 0062 D0A8 4C EA D5 EMAG JMP EMC ;Jump to triangles 0063 D0AB EXGREF 0064 D0AB ;* TYA ;Restore plot mode to A 0065 D0AB 4C 38 C9 JMP JMIV25 0066 D0AE 0067 D0AE 85 DC EME STA ZTEMPB ;(A)=0 .This is what is EORed with the flag register 0068 D0B0 4C BF D4 JMP SPLOT ;Fill plot 0069 D0B3 0070 D0B3 ;Set up ZGORA & ZGEOR, using 0071 D0B3 ;(X)=Full colour byte 0072 D0B3 ;(Y)=Plot mode 0073 D0B3 0074 D0B3 8A SETZG TXA 0075 D0B4 19 1C C4 ORAAY TBZGOO 0076 D0B7 59 1D C4 EORAY TBZGEO 0077 D0BA 85 D4 STA ZGORA 0078 D0BC 8A TXA 0079 D0BD 19 1B C4 ORAAY TBZGOE 0080 D0C0 59 20 C4 EORAY TBZGEE 0081 D0C3 85 D5 STA ZGEOR 0082 D0C5 60 RTS 0083 D0C6 0084 D0C6 ;Plot a line or curve 0085 D0C6 0086 D0C6 0A EMAD ASLA ;Is it a line or curve ? 0087 D0C7 30 E2 BMI EXGREF ;Curve, so reference user routine 0088 D0C9 0A ASLA 0089 D0CA 0A ASLA ;It's a line, so is the first point to be plotted again? 0090 D0CB 10 03 BPL EMAB ;No, then skip this, as routine plots both anyway 0091 D0CD ; 0092 D0CD [ STARTP=0 0095 D0CD | 0096 D0CD ; plot end point twice 0097 D0CD 20 EB D0 JSR WPLOT 0098 D0D0 ] 0099 D0D0 ; 0100 D0D0 20 ED D1 EMAB JSR LINE 0101 D0D3 4C D9 D0 JMP EMAEX 0102 D0D6 0103 D0D6 ;Plot a point 0104 D0D6 0105 D0D6 20 EB D0 EMAC JSR WPLOT ;Plot only if it is in window 0106 D0D9 ;SPLOTY requires that EMAEX preserves carry 0107 D0D9 20 E2 CD EMAEX JSR SWAPB ;Swap current cursor with last cursor 0108 D0DC A0 24 EMAEY LDYIM GCSIR-V ;Copy new point to Icursor 0109 D0DE A2 20 EMAEZ LDXIM NEWPT-V 0110 D0E0 4C 8A D4 JMP COPYF 0111 D0E3 0112 D0E3 ;WPLOT windows point at NEWPT and plots it if inside 0113 D0E3 0114 D0E3 A2 24 WPLOTA LDXIM GCSIR-V ;WPLOTA does this to current graphics cursor 0115 D0E5 20 5F D8 JSR GADDV ;WPLOTB does this for any point pointed to by X 0116 D0E8 F0 06 BEQ PLOT 0117 D0EA 60 RTS 0118 D0EB 20 5D D8 WPLOT JSR GADDW ;Window & address NEWPT 0119 D0EE D0 13 BNE PLOTEX ;Out of window, then exit 0120 D0F0 0121 D0F0 ;otherwise fall through to ..... 0122 D0F0 0123 D0F0 ;PLOT plots a point 0124 D0F0 ;Requires LINEY, ZMEMG, ZGORA, ZGEOR 0125 D0F0 ;Uses ZTEMP as work byte 0126 D0F0 ;Alters 1 byte on screen Acorn macro assembler Page 29 VDU File - MOS06 0127 D0F0 0128 D0F0 AC 1A 03 PLOT LDY YLINE 0129 D0F3 A5 D1 PLOTS LDA ZMASK 0130 D0F5 25 D4 AND ZGORA 0131 D0F7 11 D6 ORAIY ZMEMG 0132 D0F9 85 DA STA ZTEMP 0133 D0FB A5 D5 LDA ZGEOR 0134 D0FD 25 D1 AND ZMASK 0135 D0FF 45 DA EOR ZTEMP 0136 D101 91 D6 STAIY ZMEMG 0137 D103 60 PLOTEX RTS 0138 D104 0139 D104 B1 D6 PLOTFF LDAIY ZMEMG ;Plots a full byte 0140 D106 05 D4 ORA ZGORA 0141 D108 45 D5 EOR ZGEOR 0142 D10A 91 D6 STAIY ZMEMG 0143 D10C 60 RTS 0144 D10D 0145 D10D ;WIND windows the point at V+(X), as follows 0146 D10D ;If the point is below the lower limit, the window is 1 0147 D10D ;If the point is above the upper limit, the window is 2 0148 D10D ;If the point is within both limits, the window is 0 0149 D10D ;The total window, returned in A (with z set appropriately) 0150 D10D ;is 4 times the window in the Y direction, plus the window 0151 D10D ;in the X direction. 0152 D10D ;The routine uses ZTEMP as a work byte 0153 D10D ;All windows, as specified by GWxxxx are reckoned as inclusive, 0154 D10D ;with the high byte last. 0155 D10D ;The order of the windows in RAM is reckoned as follows 0156 D10D ;GWLCOL, GWBROW, GWRCOL, GWTROW 0157 D10D 0158 D10D A2 24 WINDCS LDXIM GCSIR-V ;Special entry point to window graphics cursor 0159 D10F 0160 D10F A0 00 WIND LDYIM &00 ;Initialise result 0161 D111 84 DA STY ZTEMP 0162 D113 A0 02 LDYIM &02 ;Do the Y co-ords 0163 D115 20 28 D1 JSR WINDA 0164 D118 06 DA ASL ZTEMP ;Mult. the Y window by 4 0165 D11A 06 DA ASL ZTEMP 0166 D11C CA DEX 0167 D11D CA DEX 0168 D11E A0 00 LDYIM &00 ;Do the X window 0169 D120 20 28 D1 JSR WINDA 0170 D123 E8 INX ;Restore X 0171 D124 E8 INX 0172 D125 A5 DA LDA ZTEMP 0173 D127 60 RTS 0174 D128 0175 D128 ;Subtract margin from point to obtain sign of difference 0176 D128 0177 D128 BD 02 03 WINDA LDAAX V+&02 ;(LSB) 0178 D12B D9 00 03 CMPAY GWLCOL ;(LSB of lower limit) 0179 D12E BD 03 03 LDAAX V+&03 ;(MSB) 0180 D131 F9 01 03 SBCAY GWLCOL+&01 ;(MSB of lower limit) 0181 D134 30 10 BMI WINDAA 0182 D136 B9 04 03 LDAAY GWRCOL ;(LSB of upper limit) 0183 D139 DD 02 03 CMPAX V+&02 ;(LSB) 0184 D13C B9 05 03 LDAAY GWRCOL+&01 ;(MSB of upper limit) 0185 D13F FD 03 03 SBCAX V+&03 ;(MSB) 0186 D142 10 04 BPL WINDAB ;Is this <= upper limit ? 0187 D144 E6 DA INC ZTEMP 0188 D146 E6 DA WINDAA INC ZTEMP 0189 D148 60 WINDAB RTS ;No longer referenced from EIG, incidentally, saving TWO WHOLE BYTES !! 0190 D149 0191 D149 ;EIGABS in some embarassment is to provide EIG in ABSOLUTE co-ords 0192 D149 0193 D149 A9 FF EIGABS LDAIM &FF 0194 D14B D0 03 BNE EIGC ;(branch always taken) 0195 D14D 0196 D14D ;Convert external to internal co-ordinates 0197 D14D 0198 D14D ;EIG converts from external co-ords (either relative or abs) 0199 D14D ;and produces internal ones in situ. No windowing is done. 0200 D14D ;Requires (X) = the offset from V of the points to be converted 0201 D14D ;b2 of PLMODE = 0 for relative co-ords (add the Ecursor) 0202 D14D ; 1 for absolute co-ords (add the origin) 0203 D14D ;GCSR, ORGX, ORGY as usual 0204 D14D ;Writes the transformed co-ordinates from whence they came 0205 D14D ;Also writes new point to external cursor (GCSX,GCSY) 0206 D14D ;hence in triangle relative mode, the points are relative 0207 D14D ;to the last specified, not the original cursor 0208 D14D 0209 D14D ;a) Add the cursor to current posn. if relative 0210 D14D ;& add origin in both cases 0211 D14D 0212 D14D AD 1F 03 EIG LDA PLMODE 0213 D150 85 DA EIGC STA ZTEMP 0214 D152 A0 02 LDYIM &02 ;Do this for Y co-ordinates 0215 D154 20 76 D1 JSR EIGS 0216 D157 20 AD D1 JSR DIVAXT ;1024 points vertically 0217 D15A A0 00 LDYIM &00 0218 D15C CA DEX 0219 D15D CA DEX 0220 D15E 20 76 D1 JSR EIGS ;Do this for X co-ordinates 0221 D161 0222 D161 ;b) scale down by the necessary factor 0223 D161 ;(EIGS has already divided by 2) 0224 D161 0225 D161 AC 61 03 LDY NPIX ;How many pixles ? 0226 D164 C0 03 CPYIM &03 0227 D166 F0 05 BEQ EIGA ;4?, then divide by 4 0228 D168 B0 06 BCS EIGB ;8?, then divide by 2 0229 D16A 20 AD D1 JSR DIVAXT ;2?, then divide by 8 0230 D16D 20 AD D1 EIGA JSR DIVAXT 0231 D170 AD 56 03 EIGB LDA MEMODE ;Is it a 10K mode? 0232 D173 D0 38 BNE DIVAXT ;YES, then another divide by 2 0233 D175 60 RTS ; NO, then skip 0234 D176 0235 D176 18 EIGS CLC 0236 D177 A5 DA LDA ZTEMP ;Test b2 of plot mode, for rel./abs. 0237 D179 29 04 ANDIM &04 0238 D17B F0 09 BEQ EIGSA ;Clear, so relative ( & skip ) 0239 D17D BD 02 03 LDAAX V+&02 ;(LSB) ~~~ ABSOLUTE ~~~ 0240 D180 48 PHA 0241 D181 BD 03 03 LDAAX V+&03 ;(MSB) 0242 D184 90 0E BCC EIGSB ;(branch always taken) 0243 D186 BD 02 03 EIGSA LDAAX V+&02 ;~~~ RELATIVE ~~~ 0244 D189 79 10 03 ADCAY GCSR ;so add prev. cursor (LSB) 0245 D18C 48 PHA 0246 D18D BD 03 03 LDAAX V+&03 ;(MSB) 0247 D190 79 11 03 ADCAY GCSR+&01 Acorn macro assembler Page 30 VDU File - MOS06 0248 D193 18 CLC 0249 D194 99 11 03 EIGSB STAAY GCSR+&01 ;Update MSB of cursor 0250 D197 79 0D 03 ADCAY ORG+&01 ;Now add origin for both addressing modes ! 0251 D19A 9D 03 03 STAAX V+&03 ;(MSB) 0252 D19D 68 PLA ;Pull LSByte 0253 D19E 99 10 03 STAAY GCSR ;Update LSB of cursor 0254 D1A1 18 CLC 0255 D1A2 79 0C 03 ADCAY ORG ;(LSB) 0256 D1A5 9D 02 03 STAAX V+&02 0257 D1A8 90 03 BCC DIVAXT 0258 D1AA FE 03 03 INCAX V+&03 ;Carry into MSB if needs be 0259 D1AD 0260 D1AD ;Divide this by 2 by falling through to ... 0261 D1AD 0262 D1AD BD 03 03 DIVAXT LDAAX V+&03 ;Signed division by 2 0263 D1B0 0A ASLA ;(Screen now 1280 by 1024) 0264 D1B1 7E 03 03 RORAX V+&03 0265 D1B4 7E 02 03 RORAX V+&02 0266 D1B7 60 RTS 0267 D1B8 0268 D1B8 ;IEG Inverse of EIG. Converts Icursor to Ecursor 0269 D1B8 0270 D1B8 A0 10 IEG LDYIM GCSR-V ;Copy GCSIY to GCSY 0271 D1BA 20 88 D4 JSR COPYFB 0272 D1BD A2 02 LDXIM &02 ;Convert y co-ordinates 0273 D1BF A0 02 LDYIM &02 ;by multiplying by 4 0274 D1C1 20 D5 D1 JSR IEGC 0275 D1C4 A2 00 LDXIM &00 ;Convert x co-ordinates 0276 D1C6 A0 04 LDYIM &04 ;By multiplying by 2 0277 D1C8 AD 61 03 LDA NPIX ;4, or 8, depending on (NPIX) 0278 D1CB 88 IEGA DEY 0279 D1CC 4A LSRA 0280 D1CD D0 FC BNE IEGA 0281 D1CF AD 56 03 LDA MEMODE ;Get memory map type 0282 D1D2 F0 01 BEQ IEGC ;=1 if 10K mode 0283 D1D4 C8 INY ;in which case, multiply by another factor of two & fall through to ... 0284 D1D5 0285 D1D5 1E 10 03 IEGC ASLAX GCSR 0286 D1D8 3E 11 03 ROLAX GCSR+&01 0287 D1DB 88 DEY 0288 D1DC D0 F7 BNE IEGC 0289 D1DE 38 SEC ;Now subtract off origin to give external co-ordinate 0290 D1DF 20 E3 D1 JSR IEGD 0291 D1E2 E8 INX 0292 D1E3 BD 10 03 IEGD LDAAX GCSR 0293 D1E6 FD 0C 03 SBCAX ORG 0294 D1E9 9D 10 03 STAAX GCSR 0295 D1EC 60 RTS 0296 D1ED 0297 D1ED LNK MOS07 0001 D1ED TTL VDU File - MOS07 0002 D1ED OPT MOS07 Acorn macro assembler Page 31 VDU File - MOS07 0003 D1ED 0004 D1ED ;Last revision 01/05/82 0005 D1ED 0006 D1ED ;01/05/82 Recoded to allow for new order of variables & manifests 0007 D1ED ;21/04/82 LINE rewritten 0008 D1ED ;19/04/82 One byte saved in SB 0009 D1ED ;25/03/82 Change all refs. to BEGSCN+1 to BEGSCN 0010 D1ED ;14/11/81 Variable mark space on DOTS removed 0011 D1ED 0012 D1ED ;******* PLOTTING ******* 0013 D1ED 0014 D1ED ;LINE plots straight line from cursor to new point 0015 D1ED ;taking account windowing, & plotting partial lines 0016 D1ED ;if necessary 0017 D1ED 0018 D1ED ;Requires GCSIR = the current cursor position (I co-ords) 0019 D1ED ;NEWPT = the point to plotted to (I co-ords) 0020 D1ED ;Windowing is assumed of neither 0021 D1ED 0022 D1ED 0023 D1ED ;Plot a straight line 0024 D1ED 0025 D1ED 20 0D D4 LINE JSR LINSA ;Find DeltaX & DeltaY to LDELTA 0026 D1F0 ;LINSB Returns n=1 iff MOD DeltaX < MOD DeltaY 0027 D1F0 ;Encoded version of a previous routine 0028 D1F0 0029 D1F0 AD 2B 03 LDA LDELTA+&03 ;DY, MSB Are the deltas of the same sign? 0030 D1F3 4D 29 03 EOR LDELTA+&01 ;DX, MSB 0031 D1F6 30 0F BMI LINSBA 0032 D1F8 AD 2A 03 LDA LDELTA+&02 ;YES, then compare DeltaY - DeltaX 0033 D1FB CD 28 03 CMP LDELTA 0034 D1FE AD 2B 03 LDA LDELTA+&03 0035 D201 ED 29 03 SBC LDELTA+&01 0036 D204 4C 14 D2 JMP LINSBB 0037 D207 AD 28 03 LINSBA LDA LDELTA ;NO, then add 0038 D20A 18 CLC 0039 D20B 6D 2A 03 ADC LDELTA+&02 0040 D20E AD 29 03 LDA LDELTA+&01 0041 D211 6D 2B 03 ADC LDELTA+&03 0042 D214 6A LINSBB RORA ;c to b7 of A 0043 D215 A2 00 LDXIM &00 0044 D217 4D 2B 03 EOR LDELTA+&03 ;If DY < 0, then invert b7 of A. Sets n as required 0045 D21A ; 0046 D21A 10 02 BPL LINEA 0047 D21C A2 02 LDXIM &02 0048 D21E 86 DE LINEA STX ZTEMPC ;0 if p.b.X, 2 if p.b.Y 0049 D220 BD AA C4 LDAAX D1JTB ;JVEC initialisation (D1 jump vector) 0050 D223 8D 5D 03 STA JVEC 0051 D226 BD AB C4 LDAAX D1JTB+&01 0052 D229 8D 5E 03 STA JVEC+&01 0053 D22C BD 29 03 LDAAX LDELTA+&01 ;Sign of D1 0054 D22F 10 04 BPL LINEB 0055 D231 A2 24 LDXIM GCSIR-V ;+ve, then LSTART from GCSIR... 0056 D233 D0 02 BNE LINEC ;(branch always taken) 0057 D235 A2 20 LINEB LDXIM NEWPT-V ;Copy LSTART from new point 0058 D237 86 DF LINEC STX ZTEMPC+&01 ;Offset of LSTART (=PStart of old) 0059 D239 A0 2C LDYIM LSTART-V ;Copy to LSTART 0060 D23B 20 8A D4 JSR COPYF 0061 D23E A5 DF LDA ZTEMPC+&01 ;Get Horizontal co-ordinate of other (end) point 0062 D240 49 04 EORIM &04 ;This requires NEWPT to be multiple of 8 & GCSIR 4 above it 0063 D242 85 DD STA ZTEMPB+&01 0064 D244 05 DE ORA ZTEMPC ;Get Hend (horizontal co-ordinate of endpoint) 0065 D246 AA TAX 0066 D247 20 80 D4 JSR COPY2H 0067 D24A AD 1F 03 LDA PLMODE ;Initialise dotted line test 0068 D24D 29 10 ANDIM &10 ;Isolate b4 0069 D24F 0A ASLA 0070 D250 0A ASLA 0071 D251 0A ASLA ;now $80 if plot dotted line, $00 if full line 0072 D252 85 DB STA ZTEMP+&01 0073 D254 A2 2C LDXIM LSTART-V ;Window start point LSTART 0074 D256 20 0F D1 JSR WIND 0075 D259 85 DC STA ZTEMPB 0076 D25B F0 06 BEQ LINED 0077 D25D A9 40 LDAIM &40 ;Start point not inside, so slow plot 0078 D25F 05 DB ORA ZTEMP+&01 0079 D261 85 DB STA ZTEMP+&01 0080 D263 A6 DD LINED LDX ZTEMPB+&01 ;Window other point 0081 D265 20 0F D1 JSR WIND 0082 D268 24 DC BIT ZTEMPB ;Anything to do ? 0083 D26A F0 01 BEQ LINEE 0084 D26C 60 RTS ;No, then exit 0085 D26D A6 DE LINEE LDX ZTEMPC ;Isolate 2nd horizontal window 0086 D26F F0 02 BEQ LINEF 0087 D271 4A LSRA 0088 D272 4A LSRA 0089 D273 29 02 LINEF ANDIM &02 0090 D275 F0 07 BEQ LINEG ;Zero, so Hend is in window 0091 D277 8A TXA ;Point X to upper margin! 0092 D278 09 04 ORAIM GWRCOL-V ;Assumes GWLCOL-V is a multiple of 4 0093 D27A AA TAX ;Endpoint outside horizontal window, 0094 D27B 20 80 D4 JSR COPY2H ;so alter Hend to high margin 0095 D27E 20 2C D4 LINEG JSR LINSG ;Get L values & MOD deltas 0096 D281 A5 DE LDA ZTEMPC 0097 D283 49 02 EORIM &02 0098 D285 AA TAX ;Unsigned D2 0099 D286 A8 TAY 0100 D287 AD 29 03 LDA LDELTA+&01 ;Sign of D2 ? 0101 D28A 4D 2B 03 EOR LDELTA+&03 0102 D28D 10 01 BPL LINEH 0103 D28F E8 INX ;Signed D2 - E,W,N,S 0104 D290 BD AE C4 LINEH LDAAX D2JTBL ;Initialise D2 jump vector 0105 D293 8D 32 03 STA D2JVEC 0106 D296 BD B2 C4 LDAAX D2JTBH 0107 D299 8D 33 03 STA D2JVEC+&01 0108 D29C A9 7F LDAIM &7F ;dotted line initialisation 0109 D29E 8D 34 03 STA DOTFLG 0110 D2A1 24 DB BIT ZTEMP+&01 0111 D2A3 70 29 BVS LINEI ;Slow plot , so set ZTEMPC strangely 0112 D2A5 BD 47 C4 LDAAX EWTBA ;(4,0,6,2) Calculate V points 0113 D2A8 AA TAX 0114 D2A9 38 SEC 0115 D2AA BD 00 03 LDAAX GWLCOL 0116 D2AD F9 2C 03 SBCAY LSTART 0117 D2B0 85 DA STA ZTEMP 0118 D2B2 BD 01 03 LDAAX GWLCOL+&01 0119 D2B5 F9 2D 03 SBCAY LSTART+&01 0120 D2B8 A4 DA LDY ZTEMP 0121 D2BA AA TAX ;Ensure +ve 0122 D2BB 10 03 BPL LINEH1 0123 D2BD 20 9B D4 JSR NEGAY Acorn macro assembler Page 32 VDU File - MOS07 0124 D2C0 AA LINEH1 TAX ;MSB of no. V points 0125 D2C1 C8 INY ;Increment this no. 0126 D2C2 D0 01 BNE LINEH2 0127 D2C4 E8 INX 0128 D2C5 8A LINEH2 TXA ;MSB non-zero ? 0129 D2C6 F0 02 BEQ LINEH3 0130 D2C8 A0 00 LDYIM &00 ;Yes, then no limit to no. of vertical points 0131 D2CA 84 DF LINEH3 STY ZTEMPC+&01 ; Zero is always set here 0132 D2CC F0 09 BEQ LINEJ1 0133 D2CE 8A LINEI TXA ;b7 = sign of D2. b1=D2 0134 D2CF 4A LSRA 0135 D2D0 6A RORA 0136 D2D1 09 02 ORAIM &02 0137 D2D3 45 DE EOR ZTEMPC 0138 D2D5 85 DE STA ZTEMPC 0139 D2D7 A2 2C LINEJ1 LDXIM LSTART-V ;Address the first point 0140 D2D9 20 64 D8 JSR GADDR ;Now loads YLINE to Y 0141 D2DC A6 DC LDX ZTEMPB 0142 D2DE D0 02 BNE LINEN 0143 D2E0 C6 DD DEC ZTEMPB+&01 0144 D2E2 CA LINEN DEX 0145 D2E3 ; 0146 D2E3 ; Fall through to main plot routine 0147 D2E3 ; 0148 D2E3 A5 DB LINEJ LDA ZTEMP +&01 ;Was midpoint or DOTS referenced ? 0149 D2E5 F0 1F BEQ DOTYES ;No?, then run along 0150 D2E7 10 10 BPL MPTEST ;No, then do midpoint test 0151 D2E9 2C 34 03 BIT DOTFLG ;b7 set, then dotted 0152 D2EC 10 05 BPL DOTY ;Branch if last was a space 0153 D2EE CE 34 03 DEC DOTFLG ;now to $7F 0154 D2F1 D0 23 BNE DOTNO ;(branch always taken) 0155 D2F3 EE 34 03 DOTY INC DOTFLG ;to $80 0156 D2F6 0A ASLA 0157 D2F7 10 0D BPL DOTYES ;No?, then plot the point 0158 D2F9 86 DC MPTEST STX ZTEMPB ;Store X temporarily 0159 D2FB A2 2C LDXIM LSTART-V ;Window the point at Q +0D (PStart) 0160 D2FD 20 5F D8 JSR GADDV ;& address if window was successful 0161 D300 A6 DC LDX ZTEMPB ;Restore X 0162 D302 09 00 ORAIM &00 ;To TSTA (a la 6800) (result of window) 0163 D304 D0 10 BNE DOTNO ;Outside?, then skip the plot 0164 D306 A5 D1 DOTYES LDA ZMASK ;Plot the point 0165 D308 25 D4 AND ZGORA 0166 D30A 11 D6 ORAIY ZMEMG 0167 D30C 85 DA STA ZTEMP 0168 D30E A5 D5 LDA ZGEOR 0169 D310 25 D1 AND ZMASK 0170 D312 45 DA EOR ZTEMP 0171 D314 91 D6 STAIY ZMEMG 0172 D316 0173 D316 ;L := L - DeltaV 0174 D316 0175 D316 38 DOTNO SEC 0176 D317 AD 35 03 LDA LPARMS ;L,LSB 0177 D31A ED 37 03 SBC LPARMS+&02 ;DeltaV,LSB 0178 D31D 8D 35 03 STA LPARMS 0179 D320 AD 36 03 LDA LPARMS+&01 ;L,MSB 0180 D323 ED 38 03 SBC LPARMS+&03 ;DeltaV,MSB 0181 D326 B0 11 BCS LINED1 ;Skip if D2 not to be taken ( L > 0 ) 0182 D328 85 DA STA ZTEMP ;D2 must be taken, thus 0183 D32A AD 35 03 LDA LPARMS ;L := L + DeltaH 0184 D32D 6D 39 03 ADC LPARMS+&04 ;LSB of DeltaH (c=0) 0185 D330 8D 35 03 STA LPARMS 0186 D333 A5 DA LDA ZTEMP 0187 D335 6D 3A 03 ADC LPARMS+&05 ;MSB of DeltaH 0188 D338 18 CLC ;Do do D2 0189 D339 8D 36 03 LINED1 STA LPARMS+&01 ;Store MSB of L, preserving c 0190 D33C 08 PHP ;Needed for decrementing no. of V points 0191 D33D B0 09 BCS LINEE1 ;Don't do D2 if you're not meant to 0192 D33F 6C 32 03 JMI D2JVEC ;Jump to D2, through JVEC2, to xB (below) 0193 D342 88 NB DEY 0194 D343 10 03 BPL LINEE1 ;~~~~~~~~~~~~~~ D2 KING MOVES ~~~~~~~~~~~~~~ 0195 D345 20 D3 D3 JSR NBDY 0196 D348 6C 5D 03 LINEE1 JMI JVEC 0197 D34B C8 SB INY 0198 D34C C0 08 CPYIM &08 0199 D34E D0 F8 BNE LINEE1 0200 D350 18 CLC ; encoded version of SBDY 0201 D351 A5 D6 LDA ZMEMG 0202 D353 6D 52 03 ADC BYTROW 0203 D356 85 D6 STA ZMEMG 0204 D358 A5 D7 LDA ZMEMG +&01 0205 D35A 6D 53 03 ADC BYTROW +&01 0206 D35D 10 04 BPL SBDYA 0207 D35F 38 SEC 0208 D360 ED 54 03 SBC BYTSCN 0209 D363 85 D7 SBDYA STA ZMEMG +&01 0210 D365 A0 00 LDYIM &00 0211 D367 6C 5D 03 JMI JVEC 0212 D36A 46 D1 EB LSR ZMASK 0213 D36C 90 DA BCC LINEE1 0214 D36E 20 ED D3 JSR EBDY 0215 D371 6C 5D 03 JMI JVEC 0216 D374 06 D1 WB ASL ZMASK 0217 D376 90 D0 BCC LINEE1 0218 D378 20 FD D3 JSR WBDY 0219 D37B 6C 5D 03 JMI JVEC 0220 D37E 88 NA DEY 0221 D37F 10 0C BPL LINEF1 ;~~~~~~~~~~~~~~ D1 KING MOVES ~~~~~~~~~~~~~~ 0222 D381 20 D3 D3 JSR NBDY 0223 D384 D0 07 BNE LINEF1 ; NBDY returns Zero false 0224 D386 46 D1 EA LSR ZMASK 0225 D388 90 03 BCC LINEF1 0226 D38A 20 ED D3 JSR EBDY 0227 D38D 28 LINEF1 PLP ;Did D2 occur ? Result to c (c=0 if it did) 0228 D38E E8 INX ;Inc no. H points left to plot (following preserves c) 0229 D38F D0 04 BNE LINEG1 0230 D391 E6 DD INC ZTEMPB +&01 0231 D393 F0 0A BEQ LINEX ;Zero?, then exit 0232 D395 24 DB LINEG1 BIT ZTEMP +&01 ;Was midpoint referenced? (preserves c) 0233 D397 70 07 BVS FRIGA ;Yes, then go to the nasty bit 0234 D399 B0 35 BCS LINEK ;D2 ?, then test V window. c from last PLP 0235 D39B C6 DF DEC ZTEMPC +&01 ;Off V window ?, then exit 0236 D39D D0 31 BNE LINEK 0237 D39F 60 LINEX RTS 0238 D3A0 A5 DE FRIGA LDA ZTEMPC ;Which direction was D2 ? 0239 D3A2 86 DC STX ZTEMPB 0240 D3A4 29 02 ANDIM &02 0241 D3A6 AA TAX 0242 D3A7 B0 19 BCS FRIGC ;No D2?, then skip the adjustment of V 0243 D3A9 24 DE BIT ZTEMPC ;Was D2 +ve ? 0244 D3AB 30 0A BMI FRIGB Acorn macro assembler Page 33 VDU File - MOS07 0245 D3AD FE 2C 03 INCAX LSTART ;D2 +ve, so increment V co-ord 0246 D3B0 D0 10 BNE FRIGC 0247 D3B2 FE 2D 03 INCAX LSTART+&01 0248 D3B5 90 0B BCC FRIGC ;(branch always taken) 0249 D3B7 BD 2C 03 FRIGB LDAAX LSTART ;D2 -ve, so dec. the V co-ord. 0250 D3BA D0 03 BNE FRIGF 0251 D3BC DE 2D 03 DECAX LSTART+&01 0252 D3BF DE 2C 03 FRIGF DECAX LSTART 0253 D3C2 8A FRIGC TXA ;Get offset of D1 0254 D3C3 49 02 EORIM &02 0255 D3C5 AA TAX 0256 D3C6 FE 2C 03 INCAX LSTART ;D1 +ve,so inc. H co-ord 0257 D3C9 D0 03 BNE FRIGD 0258 D3CB FE 2D 03 INCAX LSTART+&01 0259 D3CE A6 DC FRIGD LDX ZTEMPB 0260 D3D0 4C E3 D2 LINEK JMP LINEJ 0261 D3D3 0262 D3D3 ;BOUNDARY ROUTINES 0263 D3D3 0264 D3D3 ;NORTH 0265 D3D3 0266 D3D3 ; Returns zero false 0267 D3D3 38 NBDY SEC 0268 D3D4 A5 D6 LDA ZMEMG 0269 D3D6 ED 52 03 SBC BYTROW 0270 D3D9 85 D6 STA ZMEMG 0271 D3DB A5 D7 LDA ZMEMG +&01 0272 D3DD ED 53 03 SBC BYTROW +&01 0273 D3E0 CD 4E 03 CMP BEGSCN ;Wraparound ? 0274 D3E3 B0 03 BCS NBDYA 0275 D3E5 6D 54 03 ADC BYTSCN 0276 D3E8 85 D7 NBDYA STA ZMEMG +&01 0277 D3EA A0 07 LDYIM &07 0278 D3EC 60 RTS 0279 D3ED 0280 D3ED ;EAST 0281 D3ED 0282 D3ED AD 62 03 EBDY LDA MASKL 0283 D3F0 85 D1 STA ZMASK 0284 D3F2 A5 D6 LDA ZMEMG 0285 D3F4 69 07 ADCIM &07 ;c=1 from branch not taken to call this 0286 D3F6 85 D6 STA ZMEMG 0287 D3F8 90 02 BCC EBDYA 0288 D3FA E6 D7 INC ZMEMG +&01 0289 D3FC 60 EBDYA RTS 0290 D3FD 0291 D3FD ;WEST 0292 D3FD 0293 D3FD AD 63 03 WBDY LDA MASKR ;encoded version of WBDY 0294 D400 85 D1 STA ZMASK 0295 D402 A5 D6 LDA ZMEMG 0296 D404 D0 02 BNE WBDYA 0297 D406 C6 D7 DEC ZMEMG +&01 0298 D408 E9 08 WBDYA SBCIM &08 ;c=1 from failure of BCC 0299 D40A 85 D6 STA ZMEMG 0300 D40C 60 RTS 0301 D40D 0302 D40D LNK MOS08 0001 D40D 0002 D40D TTL VDU File - MOS08 0003 D40D OPT MOS08 Acorn macro assembler Page 34 VDU File - MOS08 0004 D40D 0005 D40D ;Last revision 18/05/82 0006 D40D ; 0007 D40D ;18/05/82 External graphics cursor now updated on exit of SPLOT 0008 D40D ;04/05/82 SPLOT routine entered 0009 D40D ;01/05/82 Recoded using new variable order & manifests 0010 D40D ;21/04/82 Most of this deleted ! LINSG modified for new LINE routine 0011 D40D ;19/04/82 Byte saving in LINSCE 0012 D40D 0013 D40D ;LINSA calculates Delta X & Delta Y 0014 D40D ;(New point - cursor), where both are in Ico-ords 0015 D40D ;Max. I value always assumed to be $8000, as arithmetic 0016 D40D ;is performed in 2's comp., 16 bit 0017 D40D ;New point in NEWPT, results to LDELTA 0018 D40D 0019 D40D A0 28 LINSA LDYIM LDELTA-V ;Offset of results from V 0020 D40F A2 20 LDXIM NEWPT-V ;Offset of operands, from V 0021 D411 0022 D411 ;fall through to ....... 0023 D411 0024 D411 ;TRISA calculates Delta X & Delta Y for operands starting 0025 D411 ;at V+(X), and results to V+(Y). Calculation from 0026 D411 ;(Point at (V+(X)+4)) - (Point at (V+(X))) 0027 D411 0028 D411 20 18 D4 TRISA JSR TRISAA 0029 D414 E8 INX 0030 D415 E8 INX 0031 D416 C8 INY 0032 D417 C8 INY 0033 D418 38 TRISAA SEC 0034 D419 BD 04 03 LDAAX V+&04 0035 D41C FD 00 03 SBCAX V 0036 D41F 99 00 03 STAAY V 0037 D422 BD 05 03 LDAAX V+&05 0038 D425 FD 01 03 SBCAX V+&01 0039 D428 99 01 03 STAAY V+&01 0040 D42B 60 RTS 0041 D42C 0042 D42C ;LINSG calculates no. H points before H exit 0043 D42C ;putting 2's comp. to ZTEMPB,ZTEMPB +01 (LSB 1st). 0044 D42C ;Initialises MOD DELTAs & L 0045 D42C ;Requires ZTEMPB as usual, destroying original data 0046 D42C 0047 D42C A5 DE LINSG LDA ZTEMPC ;Calc. MOD DELTAs. 0048 D42E D0 07 BNE LINSGB ;Plot by Y, so straight copy 0049 D430 A2 28 LDXIM LDELTA-V ;Swap DeltaX & DeltaY 0050 D432 A0 2A LDYIM LDELTA+&02-V 0051 D434 20 DE CD JSR SWAP2 0052 D437 A2 28 LINSGB LDXIM LDELTA-V ;Copy from modified DX & DY (now DH & DV) 0053 D439 A0 37 LDYIM LPARMS+&02-V ;to LPARMS+2=LDELTA 0054 D43B 20 8A D4 JSR COPYF ;Copy 4 bytes 0055 D43E 0056 D43E ;Initialise No. H points 0057 D43E 0058 D43E 38 SEC 0059 D43F A6 DE LDX ZTEMPC 0060 D441 AD 30 03 LDA HEND ;He, LSB 0061 D444 FD 2C 03 SBCAX LSTART ;HSt, LSB 0062 D447 A8 TAY 0063 D448 AD 31 03 LDA HEND+&01 ;He, MSB 0064 D44B FD 2D 03 SBCAX LSTART+&01 ;HSt, MSB 0065 D44E 30 03 BMI LINSGA ;Ensure in 2's comp. 0066 D450 20 9B D4 JSR NEGAY 0067 D453 85 DD LINSGA STA ZTEMPB +&01 0068 D455 84 DC STY ZTEMPB 0069 D457 0070 D457 ;now initialise L & MODULO the DH & DV 0071 D457 0072 D457 A2 35 LDXIM LPARMS-V ;Point to the deltas 0073 D459 0074 D459 ;& fall through to ... 0075 D459 0076 D459 ;TRISB Set up L & MODULO deltas. 0077 D459 ;Assumes V+(X) points to LL,LH,DVL,DVH,DHL,DHH 0078 D459 ;Sets all Dxy to ABS in situ. Sets L := DH/2 (2 byte arith) 0079 D459 0080 D459 20 67 D4 TRISB JSR TRISBA ;Do DH 0081 D45C 4A LSRA 0082 D45D 9D 01 03 STAAX V+&01 ;Initialise LH 0083 D460 98 TYA ;Now do LL 0084 D461 6A RORA 0085 D462 9D 00 03 STAAX V 0086 D465 CA DEX ;Now DV 0087 D466 CA DEX 0088 D467 BC 04 03 TRISBA LDYAX V+&04 ;LSB 0089 D46A BD 05 03 LDAAX V+&05 ;MSB 0090 D46D 10 0C BPL TRISBB ;Find ABS value 0091 D46F 20 9B D4 JSR NEGAY 0092 D472 9D 05 03 STAAX V+&05 ;PAIN - why the hell isn't there a STYAX on this wretched chip ?? 0093 D475 48 PHA 0094 D476 98 TYA 0095 D477 9D 04 03 STAAX V+&04 0096 D47A 68 PLA 0097 D47B 60 TRISBB RTS 0098 D47C 0099 D47C 0100 D47C ;COPYF copies 4 bytes from (V)+(X) to (V)+(Y) 0101 D47C 0102 D47C A9 08 COPY8 LDAIM &08 0103 D47E D0 0C BNE COPY 0104 D480 0105 D480 A0 30 COPY2H LDYIM HEND-V 0106 D482 A9 02 COPY2 LDAIM &02 0107 D484 D0 06 BNE COPY 0108 D486 0109 D486 A0 28 COPYFA LDYIM APCS1-V 0110 D488 A2 24 COPYFB LDXIM GCSIR-V 0111 D48A A9 04 COPYF LDAIM &04 ;SPLOTY requires that c preserved 0112 D48C 85 DA COPY STA ZTEMP 0113 D48E BD 00 03 COPYA LDAAX V 0114 D491 99 00 03 STAAY V 0115 D494 E8 INX 0116 D495 C8 INY 0117 D496 C6 DA DEC ZTEMP 0118 D498 D0 F4 BNE COPYA 0119 D49A 60 RTS 0120 D49B 0121 D49B 48 NEGAY PHA ;Negate (AY) - push MSB 0122 D49C 98 TYA 0123 D49D 49 FF EORIM &FF 0124 D49F A8 TAY Acorn macro assembler Page 35 VDU File - MOS08 0125 D4A0 68 PLA 0126 D4A1 49 FF EORIM &FF 0127 D4A3 C8 INY 0128 D4A4 D0 03 BNE NEGAYA 0129 D4A6 18 CLC 0130 D4A7 69 01 ADCIM &01 0131 D4A9 60 NEGAYA RTS 0132 D4AA 0133 D4AA 20 5D D8 SPF JSR GADDW ;Address new point COMMON CODE 0134 D4AD D0 08 BNE SPFA ;Off window?, then exit 0135 D4AF B1 D6 LDAIY ZMEMG ;Get the current byte 0136 D4B1 4D 5A 03 EOR BGCOLF ;Set b/g pixels to zero 0137 D4B4 85 DA STA ZTEMP 0138 D4B6 60 RTS 0139 D4B7 68 SPFA PLA 0140 D4B8 68 PLA 0141 D4B9 0142 D4B9 ; & fall through to 0143 D4B9 0144 D4B9 EE 26 03 SPLOTY INC GCSIY ;Failed, so make the L.H. cursor > R.H. 0145 D4BC 4C 45 D5 JMP SPLOTX 0146 D4BF 0147 D4BF ;SPLOT plots from the new point left & right 0148 D4BF ; until it finds a pixel which is NOT background colour 0149 D4BF ; It scans a byte at a time if possible, taking a lot 0150 D4BF ; of code. 0151 D4BF 0152 D4BF 0153 D4BF 20 AA D4 SPLOT JSR SPF 0154 D4C2 25 D1 AND ZMASK ;Is the new point in b/g? 0155 D4C4 D0 F3 BNE SPLOTY ;No?, then exit 0156 D4C6 A2 00 LDXIM &00 ;Set up for plotting to the left 0157 D4C8 20 92 D5 JSR SPS ;Corrupts all registers 0158 D4CB F0 2D BEQ SPLOTE ;Nothing to do 0159 D4CD AC 1A 03 LDY YLINE 0160 D4D0 06 D1 ASL ZMASK ;Don't want to plot the midpoint again 0161 D4D2 B0 05 BCS SPLOTB ;So move left 0162 D4D4 20 74 D5 JSR SPB ;Plot the LH fractional byte 0163 D4D7 90 21 BCC SPLOTE ;No complete bytes to attempt? 0164 D4D9 0165 D4D9 20 FD D3 SPLOTB JSR WBDY ;Do complete bytes left 0166 D4DC B1 D6 LDAIY ZMEMG ;(NB WBDY assumes c=1) 0167 D4DE 4D 5A 03 EOR BGCOLF 0168 D4E1 85 DA STA ZTEMP 0169 D4E3 D0 12 BNE SPLOTD ;Not a complete byte of b/g? 0170 D4E5 38 SEC ;Go for next byte - add to pixel counter 0171 D4E6 8A TXA 0172 D4E7 6D 61 03 ADC NPIX 0173 D4EA 90 04 BCC SPLOTC 0174 D4EC E6 DB INC ZTEMP+&01 ;MSB of pixel counter 0175 D4EE 10 07 BPL SPLOTD ;Reached margin? Then skip 0176 D4F0 AA SPLOTC TAX ;Not reached margin - then 0177 D4F1 20 04 D1 JSR PLOTFF 0178 D4F4 38 SEC ;carry on 0179 D4F5 B0 E2 BCS SPLOTB ;(branch always taken). Sorry about the last comment 0180 D4F7 0181 D4F7 20 74 D5 SPLOTD JSR SPB ;Do whatever is right of the line 0182 D4FA A0 00 SPLOTE LDYIM &00 ;Translate back to Ico-ords 0183 D4FC 20 AC D5 JSR SPU 0184 D4FF 0185 D4FF A0 20 LDYIM NEWPT-V ;Entry point for look for b/g colour 0186 D501 A2 24 LDXIM GCSIR-V ;Swap newpoint (in GCSIR) & calculated RH endpoint 0187 D503 20 E6 CD JSR SWAPF 0188 D506 0189 D506 20 AA D4 SCHEAT JSR SPF ;Address midpoint again held in NEWPT 0190 D509 A2 04 LDXIM &04 ;Set up for plotting right 0191 D50B 20 92 D5 JSR SPS ;Musn't corrupt ZTEMP 0192 D50E 8A TXA ;Plot the midpoint 0193 D50F D0 02 BNE SPLOTA 0194 D511 C6 DB DEC ZTEMP+&01 0195 D513 CA SPLOTA DEX 0196 D514 0197 D514 20 4B D5 SPLOTL JSR SPA ;Do this RH fractional byte 0198 D517 90 27 BCC SPLOTK ;No full bytes to attempt? 0199 D519 0200 D519 20 ED D3 SPLOTI JSR EBDY ;Full bytes right 0201 D51C B1 D6 LDAIY ZMEMG 0202 D51E 4D 5A 03 EOR BGCOLF 0203 D521 85 DA STA ZTEMP 0204 D523 0205 D523 A5 DC LDA ZTEMPB 0206 D525 D0 ED BNE SPLOTL 0207 D527 0208 D527 A5 DA LDA ZTEMP 0209 D529 D0 12 BNE SPLOTJ ;This isn't a full byte 0210 D52B 38 SEC ;Add (NPIX)+1=no.pixels to counter 0211 D52C 8A TXA 0212 D52D 6D 61 03 ADC NPIX 0213 D530 90 04 BCC SPLOTF 0214 D532 E6 DB INC ZTEMP+&01 0215 D534 10 07 BPL SPLOTJ ;Skip if hit margin 0216 D536 AA SPLOTF TAX 0217 D537 20 04 D1 JSR PLOTFF 0218 D53A 38 SEC 0219 D53B B0 DC BCS SPLOTI ;(branch always taken) 0220 D53D 0221 D53D 20 4B D5 SPLOTJ JSR SPA 0222 D540 A0 04 SPLOTK LDYIM &04 ;Convert to address of LH endpoint 0223 D542 20 AC D5 JSR SPU 0224 D545 20 D9 D0 SPLOTX JSR EMAEX ;Finished 0225 D548 4C B8 D1 JMP IEG ;update external cursor 0226 D54B 0227 D54B ;SPA Plots fractional LH byte on RH line end 0228 D54B 0229 D54B A5 D1 SPA LDA ZMASK ;Push the initial combined mask 0230 D54D 48 PHA 0231 D54E 18 CLC 0232 D54F 90 0F BCC SPAF ;(branch always taken) 0233 D551 0234 D551 68 SPAA PLA ;Try next pixel - pull combined mask 0235 D552 E8 INX ;Increment the pixel counter 0236 D553 D0 04 BNE SPAB 0237 D555 E6 DB INC ZTEMP+&01 0238 D557 10 16 BPL SPAE ;Exit if all pixels plotted 0239 D559 46 D1 SPAB LSR ZMASK ;Shift mask 0240 D55B B0 12 BCS SPAE ;Exit if shifted out of character cell 0241 D55D 05 D1 ORA ZMASK ;Continue forming combined mask 0242 D55F 48 PHA ;& push it again 0243 D560 A5 D1 SPAF LDA ZMASK ;START HERE 0244 D562 24 DA BIT ZTEMP ;Is this pixel b/g colour ? 0245 D564 Acorn macro assembler Page 36 VDU File - MOS08 0246 D564 08 PHP ;Invert z flag if needs be 0247 D565 68 PLA 0248 D566 45 DC EOR ZTEMPB ;By inverting it with ZTEMPB (0 or 2) 0249 D568 48 PHA 0250 D569 28 PLP 0251 D56A 0252 D56A F0 E5 BEQ SPAA ;Try next pixel if you haven't found what you're looking for 0253 D56C 68 PLA ;Found it?, then pull combined mask 0254 D56D 45 D1 EOR ZMASK ;& delete this pixel from it 0255 D56F 85 D1 SPAE STA ZMASK ;These must preserve c! 0256 D571 4C F0 D0 JMP PLOT 0257 D574 0258 D574 ;SPB Plots fractional RH byte on LH line end 0259 D574 0260 D574 A9 00 SPB LDAIM &00 0261 D576 18 CLC 0262 D577 90 0A BCC SPBF ;(branch always taken) 0263 D579 0264 D579 E8 SPBA INX 0265 D57A D0 04 BNE SPBB 0266 D57C E6 DB INC ZTEMP+&01 0267 D57E 10 EF BPL SPAE 0268 D580 0A SPBB ASLA 0269 D581 B0 0B BCS SPBC 0270 D583 05 D1 SPBF ORA ZMASK 0271 D585 24 DA BIT ZTEMP 0272 D587 F0 F0 BEQ SPBA 0273 D589 45 D1 EOR ZMASK 0274 D58B 4A LSRA 0275 D58C 90 E1 BCC SPAE ;(branch always taken) 0276 D58E 0277 D58E 6A SPBC RORA 0278 D58F 38 SEC 0279 D590 B0 DD BCS SPAE ;(branch always taken) 0280 D592 0281 D592 ;SPS Set up pixel counter 0282 D592 0283 D592 BD 00 03 SPS LDAAX GWLCOL 0284 D595 38 SEC 0285 D596 ED 20 03 SBC NEWPT 0286 D599 A8 TAY 0287 D59A BD 01 03 LDAAX GWLCOL+&01 0288 D59D ED 21 03 SBC NEWPT+&01 0289 D5A0 30 03 BMI SPSA ;Ensure this is -ve 0290 D5A2 20 9B D4 JSR NEGAY 0291 D5A5 85 DB SPSA STA ZTEMP+&01 ;Store MSB 0292 D5A7 98 TYA 0293 D5A8 AA TAX ;LSB to X 0294 D5A9 05 DB ORA ZTEMP+&01 ;Set z=1 if nothing to do 0295 D5AB 60 RTS 0296 D5AC 0297 D5AC ;SPU Work out the internal co-ordinates of where we are 0298 D5AC 0299 D5AC 84 DA SPU STY ZTEMP 0300 D5AE 8A TXA 0301 D5AF A8 TAY 0302 D5B0 A5 DB LDA ZTEMP+&01 0303 D5B2 30 02 BMI SPUA ;This byte is $00 at most 0304 D5B4 A9 00 LDAIM &00 ;although it can get a $01 in it 0305 D5B6 A6 DA SPUA LDX ZTEMP 0306 D5B8 D0 03 BNE SPUB 0307 D5BA 20 9B D4 JSR NEGAY 0308 D5BD 48 SPUB PHA 0309 D5BE 18 CLC 0310 D5BF 98 TYA 0311 D5C0 7D 00 03 ADCAX GWLCOL 0312 D5C3 8D 20 03 STA NEWPT 0313 D5C6 68 PLA 0314 D5C7 7D 01 03 ADCAX GWLCOL+&01 0315 D5CA 8D 21 03 STA NEWPT+&01 0316 D5CD 60 RTS 0317 D5CE 0318 D5CE CSREAD 0319 D5CE A9 03 LDAIM &03 ;Convert internal co-ordiantes at OLDCS & GCSIR 0320 D5D0 20 D5 D5 JSR SPCA 0321 D5D3 A9 07 LDAIM &07 0322 D5D5 48 SPCA PHA 0323 D5D6 20 E2 CD JSR SWAPB ;Swap old cursor with cursor 0324 D5D9 20 B8 D1 JSR IEG ;Convert to external co-ordiantes 0325 D5DC A2 03 LDXIM &03 ;& copy it 0326 D5DE 68 PLA 0327 D5DF A8 TAY 0328 D5E0 BD 10 03 SPCB LDAAX GCSR 0329 D5E3 91 F0 STAIY WARGS 0330 D5E5 88 DEY 0331 D5E6 CA DEX 0332 D5E7 10 F7 BPL SPCB 0333 D5E9 60 RTS 0334 D5EA 0335 D5EA LNK MOS10 0001 D5EA 0002 D5EA TTL VDU File - MOS10 0003 D5EA OPT MOS10 Acorn macro assembler Page 37 VDU File - MOS10 0004 D5EA 0005 D5EA ;Last revision 10/05/82 0006 D5EA 0007 D5EA ;10/05/82 Save 1 byte by BCS HPLOT -> BCC TRSRTS 0008 D5EA ;05/05/82 HPLOT uses PLOTFF 0009 D5EA ;01/05/82 Recoded using manifests & new ordering of static variables 0010 D5EA ;07/02/82 Zero height triangles not so disasterous (GPT) 0011 D5EA 0012 D5EA ;TRIANGLE PLOTTING 0013 D5EA 0014 D5EA ;INITIALISATION 0015 D5EA 0016 D5EA A2 20 EMC LDXIM NEWPT-V ;Copy new point & graphics cursor to a safe place 0017 D5EC A0 3E LDYIM GCSTMP-V 0018 D5EE 20 7C D4 JSR COPY8 0019 D5F1 20 32 D6 JSR SORTA ;Sort into Y co-ords, in order NEWPT=Lo, GCSIR=Hi, OLDCS=Med 0020 D5F4 A2 14 LDXIM OLDCS-V 0021 D5F6 A0 24 LDYIM GCSIR-V 0022 D5F8 20 36 D6 JSR SORTY 0023 D5FB 20 32 D6 JSR SORTA 0024 D5FE A2 20 LDXIM NEWPT-V ;Set paramters for hypotenuse ... 0025 D600 A0 2A LDYIM HDELTA-V ;Find Deltas 0026 D602 20 11 D4 JSR TRISA 0027 D605 AD 2B 03 LDA HDELTA+&01 ;Copy sign of DeltaX to determine direction 0028 D608 8D 32 03 STA HDIREC 0029 D60B A2 28 LDXIM HPARMS 0030 D60D 20 59 D4 JSR TRISB ;complete definition of hypotenuse parameters 0031 D610 A0 2E LDYIM HSTART-V ;Copy NEWPT to PStart of hypotenuse 0032 D612 20 DE D0 JSR EMAEZ 0033 D615 ;Swap Y co-ords 2 & 3, to give 1st side 0034 D615 20 E2 CD JSR SWAPB ;Y co-ords now in order Lo, Med, Hi 0035 D618 18 CLC ;Don't plot the last line 0036 D619 20 58 D6 JSR TRSF ;Do the lower half of the triangle 0037 D61C ;Swap points to enable set up of 2nd side 0038 D61C 20 E2 CD JSR SWAPB ;Y co-ords now Lo, Hi, Med 0039 D61F A2 20 LDXIM NEWPT-V ;swap Y co-ords 1 & 3 to give 2nd side 0040 D621 20 E4 CD JSR SWAPC ;& now Med, Hi, Lo 0041 D624 38 SEC ;Do plot the last line 0042 D625 20 58 D6 JSR TRSF ;& plot the top half 0043 D628 A2 3E LDXIM GCSTMP-V ;Restore original graphics cursor & new point 0044 D62A A0 20 LDYIM NEWPT-V 0045 D62C 20 7C D4 JSR COPY8 0046 D62F 4C D9 D0 JMP EMAEX ;& do things to the cursors 0047 D632 0048 D632 ;(SORTY exits with (X)<(Y)) 0049 D632 0050 D632 A2 20 SORTA LDXIM NEWPT-V 0051 D634 A0 14 LDYIM OLDCS-V 0052 D636 BD 02 03 SORTY LDAAX V+&02 0053 D639 D9 02 03 CMPAY V+&02 0054 D63C BD 03 03 LDAAX V+&03 0055 D63F F9 03 03 SBCAY V+&03 0056 D642 30 13 BMI TRSRTS 0057 D644 4C E6 CD JMP SWAPF 0058 D647 0059 D647 CSRPOS 0060 D647 AD 18 03 LDA CSX ;~~~ Read text cursor position ~~~ 0061 D64A 38 SEC 0062 D64B ED 08 03 SBC TWLCOL 0063 D64E AA TAX 0064 D64F AD 19 03 LDA CSY 0065 D652 38 SEC 0066 D653 ED 0B 03 SBC TWTROW 0067 D656 A8 TAY 0068 D657 60 TRSRTS RTS ;No, then return 0069 D658 0070 D658 ;TRSF Initialises a parameter list for ULN 0071 D658 ;Sets up the "sides" (as opposed to the hypoteneuse) only. Skips if 0072 D658 ;the 2 Y values are equal, otherwise calls HPLOT & ULN the requisite 0073 D658 ;number of times 0074 D658 ;Assumes the points forming the side to be initialised are in 0075 D658 ;NEWPT & GCSIR 0076 D658 0077 D658 08 TRSF PHP ;Push carry - is set if last line is to be plotted 0078 D659 A2 20 LDXIM NEWPT-V ;Set up triangle parameters 0079 D65B A0 35 LDYIM SDELTA-V ;Find deltas (sides only) 0080 D65D 20 11 D4 JSR TRISA 0081 D660 AD 36 03 LDA SDELTA+&01 ;Find direction by sign of DeltaX 0082 D663 8D 3D 03 STA SDIREC 0083 D666 A2 33 LDXIM SPARMS-V ;Find MOD Deltas, and initialise L 0084 D668 20 59 D4 JSR TRISB 0085 D66B A0 39 LDYIM SSTART-V ;Copy NEWPT to SSTART 0086 D66D 20 DE D0 JSR EMAEZ 0087 D670 38 SEC ;How many Y values are there to be done ? 0088 D671 AD 22 03 LDA NEWPT+&02 0089 D674 ED 26 03 SBC GCSIY 0090 D677 8D 1B 03 STA TRINLN ;Result (2's comp.) to TRINLN 0091 D67A AD 23 03 LDA NEWPT+&03 0092 D67D ED 27 03 SBC GCSIY+&01 0093 D680 8D 1C 03 STA TRINLN+&01 ;(MSB) 0094 D683 0D 1B 03 ORA TRINLN ;Anything to do? 0095 D686 F0 17 BEQ TRSFA 0096 D688 20 A2 D6 TRSFB JSR HPLOT ;Plot the line 0097 D68B A2 33 LDXIM SPARMS-V ;Move the side up 0098 D68D 20 74 D7 JSR ULN 0099 D690 A2 28 LDXIM HPARMS-V ;Move the hypoteneuse up 0100 D692 20 74 D7 JSR ULN 0101 D695 EE 1B 03 INC TRINLN ;Any more lines ? 0102 D698 D0 EE BNE TRSFB ;Yes, then loop, otherwise 0103 D69A EE 1C 03 INC TRINLN+&01 0104 D69D D0 E9 BNE TRSFB 0105 D69F 0106 D69F 28 TRSFA PLP ;Plot the last line? 0107 D6A0 90 B5 BCC TRSRTS ;No, if c=0 0108 D6A2 0109 D6A2 ;HPLOT Fast plot of horizontal line 0110 D6A2 ;Plots horizontal line in current colour from points defined 0111 D6A2 ;at SSTART & HSTART, or, if entered at HPLOTA, from 0112 D6A2 ;GWTROW+(X) to GWTROW+(Y). 0113 D6A2 ;Y co-ordinate taken from point at (X) 0114 D6A2 0115 D6A2 A2 39 HPLOT LDXIM SSTART-V ;Initialise point pointers 0116 D6A4 A0 2E LDYIM HSTART-V 0117 D6A6 86 DE HPLOTA STX ZTEMPC ;Store these point pointers 0118 D6A8 BD 00 03 LDAAX V ;Is x co-ord. of (X)<(Y) ? 0119 D6AB D9 00 03 CMPAY V 0120 D6AE BD 01 03 LDAAX V+&01 0121 D6B1 F9 01 03 SBCAY V+&01 0122 D6B4 30 06 BMI HPLOTB ;No, then swap (X) < = > (Y) 0123 D6B6 98 TYA 0124 D6B7 A4 DE LDY ZTEMPC Acorn macro assembler Page 38 VDU File - MOS10 0125 D6B9 AA TAX 0126 D6BA 86 DE STX ZTEMPC 0127 D6BC 84 DF HPLOTB STY ZTEMPC +&01 0128 D6BE 0129 D6BE ;ZTEMPC & X now contain the offset from V to the L.H. point 0130 D6BE ;& ZTEMPC +01 & Y the offset from V to the R.H. point 0131 D6BE 0132 D6BE B9 00 03 LDAAY V ;Push R.H. x co-ordinate 0133 D6C1 48 PHA 0134 D6C2 B9 01 03 LDAAY V+&01 0135 D6C5 48 PHA 0136 D6C6 A6 DF LDX ZTEMPC +&01 ;Window the R.H. point 0137 D6C8 20 0F D1 JSR WIND 0138 D6CB F0 0D BEQ HPLOTC ;Within window?, then plot to this point 0139 D6CD C9 02 CMPIM &02 ;Only other allowed value of this window is 2 0140 D6CF D0 3D BNE HPLOTX ;Exit if this isn't =2 0141 D6D1 A2 04 LDXIM GWRCOL-V ;It was 2?, then copy R.H. margin to x co-ord of RH point 0142 D6D3 A4 DF LDY ZTEMPC+&01 0143 D6D5 20 82 D4 JSR COPY2 0144 D6D8 A6 DF LDX ZTEMPC+&01 0145 D6DA 20 64 D8 HPLOTC JSR GADDR ;Address (modified) RH end point 0146 D6DD A6 DE LDX ZTEMPC ;Window L.H. end point 0147 D6DF 20 0F D1 JSR WIND 0148 D6E2 4A LSRA ;Only allowed values of this window are 0 & 1 0149 D6E3 D0 29 BNE HPLOTX ;Neither of those?, then exit 0150 D6E5 90 02 BCC HPLOTD ;Window was zero, then don't modify L.H. end point 0151 D6E7 A2 00 LDXIM GWLCOL-V ;L.H. endpoint was to the left of L. margin, so plot to latter 0152 D6E9 A4 DF HPLOTD LDY ZTEMPC +&01 ;Point to R.H. end point 0153 D6EB 38 SEC ;to determine no. of points needed 0154 D6EC B9 00 03 LDAAY V ;Generate no. of points to be plotted 0155 D6EF FD 00 03 SBCAX V 0156 D6F2 85 DC STA ZTEMPB 0157 D6F4 B9 01 03 LDAAY V+&01 0158 D6F7 FD 01 03 SBCAX V+&01 0159 D6FA 85 DD STA ZTEMPB +&01 0160 D6FC A9 00 LDAIM &00 ;Generate the mask for the R.H. fractional byte 0161 D6FE 0A HPLOTG ASLA 0162 D6FF 05 D1 ORA ZMASK ;Generate R.H fractional mask 0163 D701 A4 DC LDY ZTEMPB 0164 D703 D0 14 BNE HPLOTE 0165 D705 C6 DD DEC ZTEMPB +&01 ;No more points to be plotted ? 0166 D707 10 10 BPL HPLOTE 0167 D709 85 D1 STA ZMASK ;No?, then plot this byte only 0168 D70B 20 F0 D0 JSR PLOT 0169 D70E A6 DF HPLOTX LDX ZTEMPC+&01 ;Restore R.H. end point's x co-ordinate 0170 D710 68 PLA 0171 D711 9D 01 03 STAAX V+&01 0172 D714 68 PLA 0173 D715 9D 00 03 STAAX V 0174 D718 60 RTS 0175 D719 C6 DC HPLOTE DEC ZTEMPB 0176 D71B AA TAX ;Continue with generation of R.H. fractional byte mask 0177 D71C 10 E0 BPL HPLOTG ;until b7 of this mask is set, whence is the mask complete 0178 D71E 85 D1 STA ZMASK 0179 D720 20 F0 D0 JSR PLOT ;Plot R.H. fractional byte 0180 D723 A6 DC LDX ZTEMPB ;LSB of no. points to be plotted, excl RH fractional byte 0181 D725 E8 INX ;Increment this, for no. points is inclusive 0182 D726 D0 02 BNE HPLOTL 0183 D728 E6 DD INC ZTEMPB +&01 0184 D72A 8A HPLOTL TXA 0185 D72B 48 PHA ;Needed for the determination of the LH fractional byte 0186 D72C 46 DD LSR ZTEMPB +&01 ;Divide no. points by no.pixels to give no. bytes 0187 D72E 6A RORA 0188 D72F AC 61 03 LDY NPIX 0189 D732 C0 03 CPYIM &03 0190 D734 F0 05 BEQ HPLOTP 0191 D736 90 06 BCC HPLOTQ 0192 D738 46 DD LSR ZTEMPB +&01 ;y>3, i.e 8 pixels per byte 0193 D73A 6A RORA 0194 D73B 46 DD HPLOTP LSR ZTEMPB +&01 ;y=3, i.e. 4 pixels per byte 0195 D73D 4A LSRA 0196 D73E AC 1A 03 HPLOTQ LDY YLINE ;Prepare ye the way of the loop 0197 D741 AA TAX ;Contains the nuber of complete bytes to be filled in 0198 D742 F0 0F BEQ HPLOTF ;None?, then skip to plotting of L.H. fractional byte 0199 D744 0200 D744 98 HPLOTI TYA ;MAIN FULL BYTE LOOP 0201 D745 38 SEC ;Move Y back 8 bytes 0202 D746 E9 08 SBCIM &08 0203 D748 A8 TAY 0204 D749 B0 02 BCS HPLOTH ;Carry generated? 0205 D74B C6 D7 DEC ZMEMG +&01 ;Yes?, then decrement MSB of IY vector 0206 D74D 20 04 D1 HPLOTH JSR PLOTFF ;Plot the bugger ! 0207 D750 CA DEX ;Any more ? 0208 D751 D0 F1 BNE HPLOTI ;Yes, then loop again 0209 D753 0210 D753 68 HPLOTF PLA ;Pull the LSB of the number of points to plotted 0211 D754 2D 61 03 AND NPIX ;No. of points in L.H. fractional byte 0212 D757 F0 B5 BEQ HPLOTX ;Leave if nothing to do 0213 D759 AA TAX ;Generate the mask for the LH fractional byte 0214 D75A A9 00 LDAIM &00 0215 D75C 0A HPLOTJ ASLA 0216 D75D 0D 63 03 ORA MASKR 0217 D760 CA DEX 0218 D761 D0 F9 BNE HPLOTJ 0219 D763 85 D1 STA ZMASK 0220 D765 98 TYA 0221 D766 38 SEC ;Move Y back 8 bytes again 0222 D767 E9 08 SBCIM &08 0223 D769 A8 TAY 0224 D76A B0 02 BCS HPLOTK ;Carry generated 0225 D76C C6 D7 DEC ZMEMG +&01 ;Yes?, then decrement MSB of IY vector 0226 D76E 20 F3 D0 HPLOTK JSR PLOTS ;Plot the L.H. fractional byte 0227 D771 4C 0E D7 JMP HPLOTX 0228 D774 0229 D774 ;ULN Increments the current graphics line which is drawing the triangle 0230 D774 ;It varies the X points according to the values of the MOD deltas, and 0231 D774 ;the direction byte. 0232 D774 ;As input, it requires in X the offset of the parameter list from V. 0233 D774 ;The parameter list is assumed to be in the following order : 0234 D774 ;Bytes 0-1 "L", the variable used in determining the steps left/right 0235 D774 ;Bytes 2-3 MOD Delta X 0236 D774 ;Bytes 4-5 MOD Delta Y 0237 D774 ;Bytes 6-9 Point from which the line is to be drawn (XL,XH,YL,YH) 0238 D774 ;Byte A Direction - +ve if x increasing as Y does, else -ve 0239 D774 0240 D774 FE 08 03 ULN INCAX V+&08 ;Increment Y value of point to be drawn from/to 0241 D777 D0 03 BNE ULNA 0242 D779 FE 09 03 INCAX V+&09 0243 D77C 38 ULNA SEC ;L := L - MOD(DeltaX) 0244 D77D BD 00 03 LDAAX V 0245 D780 FD 02 03 SBCAX V+&02 Acorn macro assembler Page 39 VDU File - MOS10 0246 D783 9D 00 03 STAAX V 0247 D786 BD 01 03 LDAAX V+&01 0248 D789 FD 03 03 SBCAX V+&03 0249 D78C 9D 01 03 STAAX V+&01 0250 D78F 10 30 BPL ULNB ;+ve?, then skip the move X part following 0251 D791 BD 0A 03 ULNF LDAAX V+&0A ;Move X, which direction ? 0252 D794 30 0B BMI ULNC ;Skip if move left 0253 D796 FE 06 03 INCAX V+&06 ;Move right, therefore increment the X value 0254 D799 D0 11 BNE ULND 0255 D79B FE 07 03 INCAX V+&07 0256 D79E 4C AC D7 JMP ULND 0257 D7A1 BD 06 03 ULNC LDAAX V+&06 ;Move left, therefore decrement X value 0258 D7A4 D0 03 BNE ULNE 0259 D7A6 DE 07 03 DECAX V+&07 0260 D7A9 DE 06 03 ULNE DECAX V+&06 0261 D7AC 18 ULND CLC ;L := L + MOD DeltaY 0262 D7AD BD 00 03 LDAAX V 0263 D7B0 7D 04 03 ADCAX V+&04 0264 D7B3 9D 00 03 STAAX V 0265 D7B6 BD 01 03 LDAAX V+&01 0266 D7B9 7D 05 03 ADCAX V+&05 0267 D7BC 9D 01 03 STAAX V+&01 0268 D7BF 30 D0 BMI ULNF ;Move left/right again ? TRAP HORIZONTAL LINES BEFORE !! 0269 D7C1 60 ULNB RTS 0270 D7C2 LNK MOS11 0001 D7C2 0002 D7C2 TTL VDU File - MOS11 0003 D7C2 OPT MOS11 Acorn macro assembler Page 40 VDU File - MOS11 0004 D7C2 0005 D7C2 ;Last revision 05/05/82 0006 D7C2 0007 D7C2 ;05/05/82 Move GADDR here. Change to tabke with 1 entry only 0008 D7C2 ;01/05/82 Recoded to account for new ordering of variables 0009 D7C2 ;24/04/82 READCH returns mode in Y, char. in X (AGAIN!) 0010 D7C2 ;19/04/82 Improved exit at RPXLC 0011 D7C2 ;16/04/82 improved READCH code 0012 D7C2 ;25/03/82 Change order of READCH character search 0013 D7C2 ;22/01/82 Change EIG to EIGABS for READPX 0014 D7C2 ;07/01/82 Rewrite READCH for non-TTX (GPT) 0015 D7C2 ;16/11/81 Fix to READCH change (15/11) 0016 D7C2 ;15/11/81 READCH returns mode in Y, char. in X 0017 D7C2 ;09/11/81 (Paul) Read start of VDU space coping with model A 0018 D7C2 0019 D7C2 ;READCH Reads the character at the current cursor location, 0020 D7C2 ;returning the result in A. 0021 D7C2 ;If the character is not found, 0 is returned. 0022 D7C2 ;Assumes new font splitting, using FNTFLG & PGSFNT 0023 D7C2 0024 D7C2 READCH 0025 D7C2 AC 60 03 LDY NCOLOR ;Is it TTX? 0026 D7C5 D0 15 BNE READCE 0027 D7C7 B1 D8 LDAIY ZMEMT ;Yes, then read character direct (Y=0) 0028 D7C9 A0 02 LDYIM &02 ;Look for characters to be swapped 0029 D7CB D9 B7 C4 RDTTXA CMPAY TTXTB+&01 ;Is it one of them? 0030 D7CE D0 04 BNE RDTTXZ 0031 D7D0 B9 B6 C4 LDAAY TTXTB ;Cheat in reverse order (see PTTX) 0032 D7D3 88 DEY ;ensure no further exchange 0033 D7D4 88 RDTTXZ DEY 0034 D7D5 10 F4 BPL RDTTXA 0035 D7D7 AC 55 03 READKE LDY MODE ;Only way of getting the mode 0036 D7DA AA TAX 0037 D7DB 60 RTS 0038 D7DC 0039 D7DC 0040 D7DC 20 08 D8 READCE JSR PTCNV ;Get the bit pattern to READWS 0041 D7DF A2 20 LDXIM &20 ;First character to be checked 0042 D7E1 8A READKF TXA ;Address charcter 0043 D7E2 48 PHA 0044 D7E3 20 3E D0 JSR CHADDR ;Result to ZTEMPC 0045 D7E6 68 PLA 0046 D7E7 AA TAX 0047 D7E8 A0 07 READKA LDYIM &07 ;Compare this character 0048 D7EA B9 28 03 READKB LDAAY READWS ;Get bit pattern 0049 D7ED D1 DE CMPIY ZTEMPC ;Compare with font 0050 D7EF D0 08 BNE READKC ;Different?, then not this character 0051 D7F1 88 DEY ;Same?, then look at next row down 0052 D7F2 10 F6 BPL READKB 0053 D7F4 8A TXA 0054 D7F5 E0 7F CPXIM &7F ;Is it a DEL? 0055 D7F7 D0 DE BNE READKE ;No?, then you have found it 0056 D7F9 E8 READKC INX ;Next character up 0057 D7FA A5 DE LDA ZTEMPC ;LSB of font pointer up by 8 0058 D7FC 18 CLC 0059 D7FD 69 08 ADCIM &08 0060 D7FF 85 DE STA ZTEMPC 0061 D801 D0 E5 BNE READKA ;More on this page? 0062 D803 8A TXA ;Finished search? 0063 D804 D0 DB BNE READKF ;No?, then try next page 0064 D806 F0 CF BEQ READKE ;(branch always taken) 0065 D808 0066 D808 ;Converts the 8,16 or 32 byte character on the screen to an 8 byte 0067 D808 ;bit pattern in Q .. Q+07. Not very fast, in particular, the 8 byte 0068 D808 ;version could be speeded up. Background text colour is recognized 0069 D808 ;as 'background', even if cursors are joined. Anything else is 0070 D808 ;recognised as 'foreground' 0071 D808 0072 D808 ;ZTEMP is the row number (7..0) 0073 D808 ;ZTEMP +01 is he bit pattern being formed from this row 0074 D808 ;ZTEMPB is the mask being used to isolate the current pixel 0075 D808 0076 D808 A0 07 PTCNV LDYIM &07 ;The row to be converted 0077 D80A 84 DA PTCNVA STY ZTEMP ;Start of 'convert 1 row' loop 0078 D80C A9 01 LDAIM &01 ;The bit pattern to be formed 0079 D80E 85 DB STA ZTEMP +&01 ;Finshed when a carry shifted out 0080 D810 AD 62 03 PTCNVB LDA MASKL ;Isolates the pixel to be tested in the current byte 0081 D813 85 DC STA ZTEMPB ;Must move to next byte when carry shifted out left 0082 D815 B1 D8 LDAIY ZMEMT ;Get the byte to be tested 0083 D817 4D 58 03 EOR BTCOLF ;Isolate back from foreground 0084 D81A 18 CLC 0085 D81B 24 DC PTCNVC BIT ZTEMPB ;Are any of the bits in this pixel set ? 0086 D81D F0 01 BEQ PTCNVD ;No?, then this pixel was background 0087 D81F 38 SEC ;Yes?, then it was foreground 0088 D820 26 DB PTCNVD ROL ZTEMP +&01 ;Shift this bit into the bit pattern 0089 D822 B0 0A BCS PTCNVE ;carry shifted out?, then this pattern is complete 0090 D824 46 DC LSR ZTEMPB ;Isolate the next pixel 0091 D826 90 F3 BCC PTCNVC ;carry clear, then continue 0092 D828 98 TYA ;c=1, then examine the next byte in the row 0093 D829 69 07 ADCIM &07 ;(c=1), by adding 8 to Y 0094 D82B A8 TAY 0095 D82C 90 E2 BCC PTCNVB ;and continue (branch always taken) 0096 D82E A4 DA PTCNVE LDY ZTEMP ;Restore Y 0097 D830 A5 DB LDA ZTEMP +&01 ;bit pattern finished, store it in the READWS 0098 D832 99 28 03 STAAY READWS 0099 D835 88 DEY ;& do the next row up 0100 D836 10 D2 BPL PTCNVA 0101 D838 60 RTS ;or return 0102 D839 0103 D839 ;RPXL Reads the pixel at V+(A), 0104 D839 ;returning $FF if the cursor is out of the window, else the logical 0105 D839 ;colour at the cursor. 0106 D839 ;Assumes the current cursor in internal representation is GCSIY... 0107 D839 0108 D839 48 RPXLD PHA 0109 D83A AA TAX ;Convert to Ico-ords 0110 D83B 20 49 D1 JSR EIGABS 0111 D83E 68 PLA 0112 D83F AA TAX 0113 D840 20 5F D8 JSR GADDV 0114 D843 D0 15 BNE RPXLC ;Out of window?, then return $FF. 0115 D845 B1 D6 LDAIY ZMEMG 0116 D847 0A RPXLA ASLA ;Shift out the leftmost bit 0117 D848 26 DA ROL ZTEMP ;& shift into the byte to receive the pixel's logical colour 0118 D84A 06 D1 ASL ZMASK ;unless the bit was irrelevant 0119 D84C 08 PHP ;(to see if this is finished, later) 0120 D84D B0 02 BCS RPXLB 0121 D84F 46 DA LSR ZTEMP ;kick the bit out again if it wasn't relevant 0122 D851 28 RPXLB PLP ;Have we finished ? 0123 D852 D0 F3 BNE RPXLA ;No?, then loop 0124 D854 A5 DA LDA ZTEMP ;Yes?, then isolate the logical colour Acorn macro assembler Page 41 VDU File - MOS11 0125 D856 2D 60 03 AND NCOLOR 0126 D859 60 RTS ;& finish 0127 D85A A9 FF RPXLC LDAIM &FF ;Return $FF if point was outside graphics window 0128 D85C 60 RPXLX RTS ;& finish 0129 D85D 0130 D85D ;Window a point, & plot if in window 0131 D85D 0132 D85D A2 20 GADDW LDXIM NEWPT-V ;Do this for new point 0133 D85F 20 0F D1 GADDV JSR WIND ;Do this for general point. Is it in window ? 0134 D862 D0 F8 BNE RPXLX ;No, then skip the windowing 0135 D864 0136 D864 ;otherwise fall through to ... 0137 D864 0138 D864 ;GADDR Addresses a single pixel on the graphics screen 0139 D864 ;Results are not guaranteed unless point is on screen 0140 D864 ;Requires :- 0141 D864 ;(X) = offset from V of point to be addressed. 0142 D864 ;Format of the pointed at point is INTERNAL co-ords, non-inverted Y axis 0143 D864 ;with 4 bytes of XL,XH,YL,YH. 0144 D864 ;ZTBL points to row offset table as per character writing 0145 D864 ;TOPSCN as usual. 0146 D864 ;NPIX = No. pixles per byte 0147 D864 ;Wraparound may occur on ends of lines only, thus hardware must display 0148 D864 ;ALL the characters in the display area (OK for modes as proposed). 0149 D864 ;Sets the following variables 0150 D864 ;YLINE = line offset within character cell (0..7) 0151 D864 ;ZMEMG = 1st byte of character cell 0152 D864 ;ZMASK = mask 0153 D864 0154 D864 BD 02 03 GADDR LDAAX V+&02 ;(Y,LSB) MSB assumed 0 0155 D867 49 FF EORIM &FF ;Invert Y axis 0156 D869 A8 TAY 0157 D86A 29 07 ANDIM &07 ;Get YLINE = 3 least significant bits of Y 0158 D86C 8D 1A 03 STA YLINE 0159 D86F 98 TYA 0160 D870 4A LSRA ;Get twice the character row (for 2 byte entry lookup table) 0161 D871 4A LSRA 0162 D872 4A LSRA 0163 D873 0A ASLA ;c=0 guaranteed (better than AND $FE : CLC) 0164 D874 A8 TAY ;Character row offset 0165 D875 B1 E0 LDAIY ZTBL ;Add row offset to TOPSCN 0166 D877 85 DA STA ZTEMP ;MSB 0167 D879 C8 INY 0168 D87A B1 E0 LDAIY ZTBL ;LSB 0169 D87C AC 56 03 LDY MEMODE 0170 D87F F0 03 BEQ GADDRD ; Divide by 2 if 10K mode (can only be 0 or 2) 0171 D881 46 DA LSR ZTEMP 0172 D883 6A RORA 0173 D884 6D 50 03 GADDRD ADC TOPSCN ;c=0 guaranteed before this add 0174 D887 85 D6 STA ZMEMG 0175 D889 A5 DA LDA ZTEMP 0176 D88B 6D 51 03 ADC TOPSCN+&01 0177 D88E 85 D7 STA ZMEMG +&01 0178 D890 0179 D890 ;Now calculate the X offset 0180 D890 0181 D890 BD 01 03 LDAAX V+&01 ;(MSB,X) 0182 D893 85 DA STA ZTEMP 0183 D895 BD 00 03 LDAAX V ;(LSB,X) 0184 D898 48 PHA ;Push the LSB of the X co-ordinate 0185 D899 2D 61 03 AND NPIX ;Calc. ZMASK (NB, c=0 from prev. addition) 0186 D89C 6D 61 03 ADC NPIX ;This gives the correct starting position 0187 D89F A8 TAY ;within the table, plus 1 0188 D8A0 B9 06 C4 LDAAY MASKTB-&01 ;So compensate by subtracting one here 0189 D8A3 85 D1 STA ZMASK 0190 D8A5 68 PLA ;Retrieve the LSB of X co-ordinate 0191 D8A6 AC 61 03 LDY NPIX 0192 D8A9 C0 03 CPYIM &03 ;Divide by NPIX, and mult. by 8 0193 D8AB F0 05 BEQ GADDRA ;4 pixles/byte - mult. by 2 0194 D8AD B0 06 BCS GADDRB ;8 pixles/byte - don't do anything 0195 D8AF 0A ASLA ;2 pixles per byte - mult. by 4 0196 D8B0 26 DA ROL ZTEMP 0197 D8B2 0A GADDRA ASLA 0198 D8B3 26 DA ROL ZTEMP 0199 D8B5 29 F8 GADDRB ANDIM &F8 ;Ignore any low order bits 0200 D8B7 18 CLC ;Calculate the final address, LSB 1st 0201 D8B8 65 D6 ADC ZMEMG 0202 D8BA 85 D6 STA ZMEMG 0203 D8BC A5 DA LDA ZTEMP 0204 D8BE 65 D7 ADC ZMEMG +&01 0205 D8C0 10 04 BPL GADDRC ;Skip wraparound if < $8000 0206 D8C2 38 SEC ;Correct by subtracting off screen if it is 0207 D8C3 ED 54 03 SBC BYTSCN 0208 D8C6 85 D7 GADDRC STA ZMEMG +&01 ;Store final address, MSB 0209 D8C8 AC 1A 03 LDY YLINE 0210 D8CB A9 00 COPYZX LDAIM &00 ;Sets z=1 0211 D8CD 60 RTS 0212 D8CE 0213 D8CE ;VDUB for cursor control keys 0214 D8CE 0215 D8CE VDUB 0216 D8CE 48 PHA 0217 D8CF A9 A0 LDAIM &A0 ;To see if the cursors are joined or drivers disabled when BIT is done 0218 D8D1 AE 6A 02 LDX QPOSN ;Qing bytes ? 0219 D8D4 D0 40 BNE VDUBEX ;Yes?, then ignore this 0220 D8D6 24 D0 BIT STATS ;Are the drivers enabled ? 0221 D8D8 D0 3C BNE VDUBEX ;Leave if not, or cursors joined 0222 D8DA 70 19 BVS VDUBA ;Are we in cursor edit mode ? Yes?, then skip 0223 D8DC AD 5F 03 LDA CSTEMP ;Flash the cursor at twice the rate 0224 D8DF 29 9F ANDIM &9F ;Sets b5=0, b6=1 of r10 of 6845, giving fast flashing cursor 0225 D8E1 09 40 ORAIM &40 0226 D8E3 20 54 C9 JSR ETCB ;Store in r10 of 6845, don't save to CSTEMP 0227 D8E6 A2 18 LDXIM CSX-V ;Set b1 of STATS or store CSX to PCSX 0228 D8E8 A0 64 LDYIM PCSX-V 0229 D8EA 20 82 D4 JSR COPY2 0230 D8ED 20 7A CD JSR OCSRWR ;Print the output cursor 0231 D8F0 A9 02 LDAIM &02 ;Set b1 of STATS 0232 D8F2 20 9D C5 JSR STTOR 0233 D8F5 A9 BF VDUBA LDAIM &BF ;Clear b6 of STATS 0234 D8F7 20 A8 C5 JSR STTAND 0235 D8FA 68 PLA ;Restore input character to routine 0236 D8FB 29 7F ANDIM &7F ;Kill the parity bit 0237 D8FD 20 C0 C4 JSR VDU ;Execute cursor movement on input cursor 0238 D900 A9 40 LDAIM &40 ;Set b6 of STATS 0239 D902 4C 9D C5 JMP STTOR 0240 D905 0241 D905 ;Copy key in cursor editing 0242 D905 0243 D905 COPYCH 0244 D905 A9 20 LDAIM &20 ;Cursors joined ? 0245 D907 24 D0 BIT STATS Acorn macro assembler Page 42 VDU File - MOS11 0246 D909 50 C0 BVC COPYZX ;Not C.E. mode, then do nothing 0247 D90B D0 BE BNE COPYZX ;Cursors joined, so do nothing 0248 D90D 20 C2 D7 JSR READCH ;Read character at cursor position 0249 D910 F0 05 BEQ COPYCX ;Not recognised?, then exit with no further action 0250 D912 48 PHA ;Move input cursor right 0251 D913 20 64 C6 JSR HT ;But with no scrolling 0252 D916 68 VDUBEX PLA 0253 D917 60 COPYCX RTS 0254 D918 0255 D918 ;CSEDEX Finish cursor edit mode 0256 D918 0257 D918 A9 BD CSEDEX LDAIM &BD ;Clear b1 & b6 from STATS 0258 D91A 20 A8 C5 JSR STTAND 0259 D91D 20 51 C9 JSR ETCA ;Restore cursor from CSTEMP to r10 of 6845 0260 D920 A9 0D LDAIM TRMCH ;Restore (A) 0261 D922 60 RTS 0262 D923 0263 D923 TOPCMD 0264 D923 AE 55 03 LDX MODE ;~~~ Beginning of screen memory ~~~ 0265 D926 0266 D926 ;& fall through to .... 0267 D926 0268 D926 TOPMDX 0269 D926 8A TXA ;Don't trust (X) anymore .... 0270 D927 29 07 ANDIM &07 0271 D929 A8 TAY 0272 D92A ; read VDU low water mark for mode Y 0273 D92A BE 40 C4 LDXAY MODETB ;~~~ Read beginning of memory for mode (Y) ~~~ 0274 D92D BD 5E C4 LDAAX STSCTB ;A := hi-byte of lwm address 0275 D930 A2 00 LDXIM &00 ;Used later 0276 D932 ; check model type 0277 D932 2C 8E 02 BIT MODEL 0278 D935 30 07 BMI PRBB1 ;[model B, all modes permissable] 0279 D937 ; model A 0280 D937 ; return HWM of zero for modes 0 to 3 0281 D937 ; (cos they require between 16K and 20K) 0282 D937 29 3F ANDIM &3F ;correct for 16K m/c (model A) 0283 D939 C0 04 CPYIM &04 ;fault modes<=3 on model A 0284 D93B B0 01 BCS PRBB1 ;[mode>=4] 0285 D93D 8A TXA ;model A and mode<=3. Sets (A):=0 0286 D93E PRBB1 ;return low water mark 0287 D93E A8 TAY 0288 D93F 60 RTS 0289 D940 0290 D940 ENDVDU ;end of VDU code 0291 D940 ; Now test code layout for correctness 0292 D940 0293 D940 0000 T1 * SOH:SHR:&8-CODORG:SHR:&3 0294 D940 0000 T2 * DCA:SHR:&8-CODORG:SHR:&3 0295 D940 0000 T3 * DCB:SHR:&8-CODORG:SHR:&3 0296 D940 0000 T4 * DCC:SHR:&8-CODORG:SHR:&3 0297 D940 0000 T5 * SYN:SHR:&8-CODORG:SHR:&3 0298 D940 0000 T6 * ETB:SHR:&8-CODORG:SHR:&3 0299 D940 0000 T7 * CAN:SHR:&8-CODORG:SHR:&3 0300 D940 0000 T8 * EM:SHR:&8-CODORG:SHR:&3 0301 D940 0000 T9 * FS:SHR:&8-CODORG:SHR:&3 0302 D940 0000 TA * GS:SHR:&8-CODORG:SHR:&3 0303 D940 0000 TB * US:SHR:&8-CODORG:SHR:&3 0304 D940 [ T1=0 0305 D940 | 0307 D940 ] 0308 D940 [ T2=0 0309 D940 | 0311 D940 ] 0312 D940 [ T3=0 0313 D940 | 0315 D940 ] 0316 D940 [ T4=0 0317 D940 | 0319 D940 ] 0320 D940 [ T5=0 0321 D940 | 0323 D940 ] 0324 D940 [ T6=0 0325 D940 | 0327 D940 ] 0328 D940 [ T7=0 0329 D940 | 0331 D940 ] 0332 D940 [ T8=0 0333 D940 | 0335 D940 ] 0336 D940 [ T9=0 0337 D940 | 0339 D940 ] 0340 D940 [ TA=0 0341 D940 | 0343 D940 ] 0344 D940 [ TB=0 0345 D940 | 0347 D940 ] 0348 D940 0349 D940 00C3 TC * HRGTB:SHR: 8 0350 D940 00C3 TD * TXTTB:SHR: 8 0351 D940 [ TC-TD=0 0352 D940 | 0354 D940 ] 0355 D940 0356 D940 00CC TE * CLASCA:SHR: 8 0357 D940 00CC TF * CLASCE:SHR: 8 0358 D940 0359 D940 [ TE-TF=0 0360 D940 | 0362 D940 ] 0363 D940 0364 D940 OPT OPPON 0365 D940 < 3 0366 D940 0367 D940 LNK MOS30 0001 D940 ; MOS30 0002 D940 OPT &01 0003 D940 TTL MOS30 Manifests 0004 D940 0005 D940 ;Change record: 0006 D940 0007 D940 0008 D940 < &0003 0009 D940 > &0002 0010 D940 0011 D940 0012 D940 Acorn macro assembler Page 43 MOS30 Manifests 0013 D940 0014 D940 ; module print selections 0015 D940 ; 0016 D940 0005 MOS30 * DEFOPT 0017 D940 0005 MOS32 * DEFOPT 0018 D940 0005 MOS34 * DEFOPT 0019 D940 0005 MOS36 * DEFOPT 0020 D940 0005 MOS38 * DEFOPT 0021 D940 0005 MOS40 * DEFOPT 0022 D940 0005 MOS42 * DEFOPT 0023 D940 0005 MOS44 * DEFOPT 0024 D940 0005 MOS46 * DEFOPT 0025 D940 0005 MOS48 * DEFOPT 0026 D940 0027 D940 0005 MOS52 * DEFOPT 0028 D940 0005 MOS54 * DEFOPT 0029 D940 0005 MOS56 * DEFOPT 0030 D940 0031 D940 0005 MOS99 * DEFOPT 0032 D940 0033 D940 0034 D940 OPT MOS30 Acorn macro assembler Page 44 MOS30 Manifests 0035 D940 ;(c) 1981 ACORN Computers Limited 0036 D940 ;BBC Microcomputer Machine Operating System (MOS) 0037 D940 ;Change record: 0038 D940 ;Author(s): 0039 D940 ;PB Paul Bond 0040 D940 ;MP Mike Prees 0041 D940 0042 D940 0043 D940 ; version number 0044 D940 ; 0045 D940 0001 MCVER * &01 ;OS binary version number 0046 D940 0031 VERA * "1" 0047 D940 0032 VERB * "2" 0048 D940 0030 VERC * "0" 0049 D940 0050 D940 0051 D940 ; composition 0052 D940 ; 0053 D940 0000 TRUE * &00 ;for conditional assembly 0054 D940 00FF FALSE * &FF ;for conditional assembly 0055 D940 0056 D940 0057 D940 ; options 0058 D940 ; 0059 D940 0000 INKYSW * TRUE 0060 D940 0061 D940 0062 D940 ; VDU software interface 0063 D940 ; 0064 D940 C300 VDUORG * &C300 ;VDU software module origin 0065 D940 C300 VDINIT * VDUORG +&00 ;initialise RAM and VDU 0066 D940 D940 ORIGIN * ENDVDU 0067 D940 0068 D940 0069 D940 ; tube interface 0070 D940 ; 0071 D940 ^ &0400 0072 D940 0400 TBLANG # &03 ;enter language 0073 D940 0403 TBESC # &03 ;alter escape condition 0074 D940 0406 TBADDR # &03 ;address translation 0075 D940 0076 D940 0077 D940 0078 D940 ; error codes 0079 D940 0080 D940 ; special reports 0081 D940 ; 0082 D940 0083 D940 0084 D940 0085 D940 ; infamous BASIC error number assignment boob 0086 D940 ; 0087 D940 0088 D940 0089 D940 0090 D940 ; MOS errors 0091 D940 ; 0092 D940 0093 D940 0094 D940 0095 D940 ; $FF is reserved for a non-trappable error in future systems 0096 D940 ; 0097 D940 00FE BADCMD * &FE ;'Bad command' 0098 D940 00FD BADST * &FD ;'Bad string' 0099 D940 00FC BADADR * &FC ;'Bad address' 0100 D940 00FB BADKY * &FB ;'Bad key' 0101 D940 00FA KEYUSE * &FA ;'Key in use' 0102 D940 00F9 NOLROM * &F9 ;'No language ROM' 0103 D940 00F8 NOFSYS * &F8 ;'No filing system' 0104 D940 00F7 FX0MSG * &F7 ;operating system version number 0105 D940 0106 D940 0107 D940 ; file system control operations 0108 D940 ; 0109 D940 0000 FSOPT * &00 ;*OPT x,y value assumed by FX code 0110 D940 0001 FSEOF * &01 ;EOF#chan value assumed by FX code 0111 D940 0002 FSNOTA * &02 ;*non-alpha 0112 D940 0003 FSNAME * &03 ;*name 0113 D940 0004 FSRUN * &04 ;*RUN name 0114 D940 0005 FSCAT * &05 ;*CAT name 0115 D940 0006 FSDIE * &06 ;kill filing system 0116 D940 0007 FSHRNG * &07 ;return handle range in X (lo) and Y (hi) 0117 D940 0118 D940 0008 FSCLI * &08 ;*command encountered 0119 D940 0120 D940 0121 D940 ; user print operations 0122 D940 ; 0123 D940 0000 UPTIME * &00 ;timer interrupt 0124 D940 0001 UPWRCH * &01 ;write character 0125 D940 ; return C=0 => printer busy, C=1 => printer free 0126 D940 0127 D940 0128 D940 0129 D940 0130 D940 ; NET operations 0131 D940 ; 0132 D940 ; hi-level 0133 D940 ; 0134 D940 ; VALUES $01-$03,$05 RESERVED FOR PRINTER INTERFACE 0135 D940 0004 NTWRCH * &04 ;WRCH 0136 D940 0006 NTRDCH * &06 ;RDCH 0137 D940 0138 D940 0008 NTWORD * &08 ;OSWORD call (c.f. SVWORD) 0139 D940 0140 D940 0141 D940 0142 D940 ; service ROM operations 0143 D940 ; 0144 D940 0010 NROM * &0010 ;number of paged ROMs 0145 D940 0146 D940 0000 SVNOP * &00 ;no operation 0147 D940 0001 SVSTAT * &01 ;offer static allocation 0148 D940 0002 SVDYN * &02 ;offer dynamic allocation 0149 D940 0003 SVBOOT * &03 ;offer bootstrap 0150 D940 0004 SVNAME * &04 ;offer command 0151 D940 0005 SVINT * &05 ;unknown interrupt 0152 D940 0006 SVBRK * &06 ;offer BRK 0153 D940 0007 SVBYTE * &07 ;offer bad OSBYTE (N.B. also NTxxxx code) 0154 D940 0008 SVWORD * &08 ;offer bad OSWORD (N.B. also NTxxxx code) 0155 D940 ; Acorn macro assembler Page 45 MOS30 Manifests 0156 D940 [ FALSE=0 0158 D940 | 0159 D940 0009 SVHELP * &09 ;*HELP facility 0160 D940 ] 0161 D940 ; 0162 D940 000A SVCSHR * &0A ;claim shared workspace 0163 D940 000B SVRNMI * &0B ;release NMI 0164 D940 000C SVCNMI * &0C ;claim NMI 0165 D940 000D SVISFS * &0D ;initialise speech filing system 0166 D940 000E SVRSFS * &0E ;read from speech filing system 0167 D940 000F SVFSIC * &0F ;changed filing system indirections 0168 D940 0169 D940 0010 SVSHES * &10 ;shut EXEC and SPOOL files 0170 D940 0011 SVHWMC * &11 ;change of HWM ******** DO NOT CHANGE ******** 0171 D940 0012 SVSTFS * &12 ;start filing system N 0172 D940 00FE SVTPIN * &FE ;tube post-initialisation **** VALUE ASSUMED BY RESET **** 0173 D940 00FF SVTUBE * &FF ;initialise tube software 0174 D940 0175 D940 0176 D940 ; language entry reasons 0177 D940 ; 0178 D940 0000 LGNONE * &00 ;no language ROM (tube entry reason) 0179 D940 0001 LGENTR * &01 ;enter language 0180 D940 0181 D940 0182 D940 ; RS423 transmitter control bits 0183 D940 ; 0184 D940 0000 RHITXD * &00 ;RTS hi, Tx interrupt disabled 0185 D940 0020 RHITXE * &20 ;RTS hi, Tx interrupt enabled 0186 D940 0040 RLOTXD * &40 ;RTS lo, Tx interrupt disabled 0187 D940 0060 RHITXB * &60 ;RTS hi, Tx break 0188 D940 0056 RSCDEF * &16+RLOTXD ;Rx interrupt disabled ... 0189 D940 ; ... RTS lo, Tx interrupt disabled, divide by 64, 8 data bits, 1 stop bit 0190 D940 0191 D940 0192 D940 ; speech processor opcodes 0193 D940 ; 0194 D940 0010 SPOPRB * &10 ;read byte 0195 D940 0060 SPOPSE * &60 ;speak external 0196 D940 0030 SPOPBR * &30 ;read and branch 0197 D940 0040 SPOPLA * &40 ;load address 0198 D940 0050 SPOPSP * &50 ;speak 0199 D940 00FF SPOPRT * &FF ;reset 0200 D940 0201 D940 0202 D940 ; memory map assignments 0203 D940 ; 0204 D940 FC00 FRED * &FC00 0205 D940 FCFF MEG1P * &FCFF ;1MHz bus page selector 0206 D940 FD00 JIM * &FD00 0207 D940 FE00 SHEIL * &FE00 0208 D940 FE08 ACIA * &FE08 0209 D940 FE10 SERPRC * &FE10 ;serial processor 0210 D940 0211 D940 FE20 VPROC0 * &FE20 ;video processor 0212 D940 FE21 VPROC1 * VPROC0 +&01 0213 D940 FE20 STNID * &FE20 ;ECONET station identifier 0214 D940 FE30 ROM * &FE30 ;ROM select latch 0215 D940 FE40 VIAA * &FE40 ;first 6522 0216 D940 FE60 VIAB * &FE60 ;second 6522 0217 D940 0218 D940 0219 D940 ; analog to digital converter 0220 D940 ; 0221 D940 FEC0 ADCONV * &FEC0 0222 D940 FEC0 ADCCTL * ADCONV +&00 0223 D940 FEC1 ADCHI * ADCONV +&01 0224 D940 FEC2 ADCLO * ADCONV +&02 0225 D940 0226 D940 0227 D940 ; tube register(s) 0228 D940 ; 0229 D940 FEE0 TREG0 * &FEE0 0230 D940 FEE5 TREG3 * &FEE5 0231 D940 0232 D940 0233 D940 0234 D940 ; test software indirection 0235 D940 ; 0236 D940 FDFE TSTSFT * &FDFE 0237 D940 0238 D940 0239 D940 ; language ROM address 0240 D940 ; 0241 D940 8000 LANG * &8000 0242 D940 8000 ROMHRD * LANG +&00 ;hard ROM entry point 0243 D940 8003 ROMSFT * LANG +&03 ;soft ROM entry point 0244 D940 0245 D940 8006 ROMTYP * LANG +&06 ;ROM type 0246 D940 8007 COPYRP * LANG +&07 ;relative offset (from LANG) to copyright string 0247 D940 8008 ROMVER * LANG +&08 ;version byte 0248 D940 8009 ROMMSG * LANG +&09 ;name 0249 D940 0250 D940 0251 D940 ; miscellaneous constants 0252 D940 ; 0253 D940 0000 ZERO * &00 0254 D940 0000 NULL * ZERO ;don't care value 0255 D940 0020 SPACE * &20 0256 D940 0040 AT * &40 0257 D940 0041 ALPHAA * "A" 0258 D940 0022 DQUOTE * """" 0259 D940 002A SPLAT * "*" 0260 D940 0060 POUND * &60 0261 D940 0262 D940 0263 D940 0264 D940 0007 BEL * &07 0265 D940 0266 D940 0009 MHT * &09 0267 D940 0009 TAB * MHT 0268 D940 000A MLF * &0A 0269 D940 000D MCR * &0D 0270 D940 0015 MNAK * &15 0271 D940 0272 D940 001B ESC * &1B 0273 D940 007F MDEL * &7F 0274 D940 0275 D940 0276 D940 ; real softkeys 0277 D940 ; Acorn macro assembler Page 46 MOS30 Manifests 0278 D940 0080 SOFTK0 * &0080 ;f0 (value must NOT be altered) 0279 D940 0081 SOFTK1 * SOFTK0 +&01 ;f1 0280 D940 0082 SOFTK2 * SOFTK1 +&01 ;f2 0281 D940 0083 SOFTK3 * SOFTK2 +&01 ;f3 0282 D940 0084 SOFTK4 * SOFTK3 +&01 ;f4 0283 D940 0085 SOFTK5 * SOFTK4 +&01 ;f5 0284 D940 0086 SOFTK6 * SOFTK5 +&01 ;f6 0285 D940 0087 SOFTK7 * SOFTK6 +&01 ;f7 0286 D940 0088 SOFTK8 * SOFTK7 +&01 ;f8 0287 D940 0089 SOFTK9 * SOFTK8 +&01 ;f9 0288 D940 0289 D940 0290 D940 ; pseudo softkeys, including cursor controls 0291 D940 ; 0292 D940 008A SOFTKA * SOFTK9 +&01 0293 D940 008B SOFTKB * SOFTKA +&01 ;COPY 0294 D940 008B MCOPY * SOFTKB 0295 D940 008C SOFTKC * SOFTKB +&01 ;cursor left arrow 0296 D940 008C CURLFT * SOFTKC 0297 D940 008D SOFTKD * SOFTKC +&01 ;cursor right arrow 0298 D940 008D CURRHT * SOFTKD 0299 D940 008E SOFTKE * SOFTKD +&01 ;cursor down 0300 D940 008E CURDWN * SOFTKE 0301 D940 008F SOFTKF * SOFTKE +&01 ;cursor up 0302 D940 008F CURUP * SOFTKF 0303 D940 00BF MAXSK * &BF ;maximum value of SHIFT/CTRL softkey code 0304 D940 00CA BREKEY * &CA ;softkey 10 feature 0305 D940 0306 D940 0307 D940 ; default auto-repeat rates 0308 D940 ; 0309 D940 0032 DAUTOD * 50 ;delay (centiseconds) 0310 D940 0008 DAUTOP * 8 ;period (centiseconds) 0311 D940 0312 D940 0313 D940 ; default RS423 baud rates 0314 D940 ; 0315 D940 0064 B9600 * &64 ;Tx9600 and Rx9600 0316 D940 0317 D940 0318 D940 ; RS423 printer timeout period 0319 D940 ; 0320 D940 00E7 PTIMUT * &E7 ;(-) 25/50 second 0321 D940 0322 D940 0323 D940 ; OS constants 0324 D940 0E00 OSHWM * &0E00 ;default high water mark 0325 D940 0D00 NMI * &0D00 0326 D940 0327 D940 0328 D940 ; buffer indices 0329 D940 ; 0330 D940 0000 BRDCH * &0000 ;RDCH (keyboard) 0331 D940 0001 BRSI * &0001 ;RS423 input 0332 D940 0001 INPUT * BRSI 0333 D940 0002 BRSO * &0002 ;RS423 output 0334 D940 0002 OUTPUT * BRSO 0335 D940 0003 BPRNT * &0003 ;print 0336 D940 0004 BSND1 * &0004 ;sound channel 1 0337 D940 0005 BSND2 * BSND1+&1 ;sound channel 2 0338 D940 0006 BSND3 * BSND2+&1 ;sound channel 3 0339 D940 0007 BSND4 * BSND3+&1 ;sound channel 4 0340 D940 0008 BSPCH * BSND4+&1 ;speech 0341 D940 0008 BUPB * BSPCH 0342 D940 0343 D940 0344 D940 ; keyboard status bits 0345 D940 ; 0346 D940 0008 SHFT * &08 ;SHIFT active 0347 D940 0010 CAPSL * &10 ;not CAPITALS lock 0348 D940 0020 SHFTL * &20 ;not SHIFT lock 0349 D940 0040 CTRL * &40 ;CTRL active 0350 D940 0080 INVERT * &80 ;SHIFT enable 0351 D940 00B7 CTLSHI * &B7 ;inverted (CTRL and SHIFT status bits) 0352 D940 0353 D940 0354 D940 ; keyboard matrix element values 0355 D940 ; 0356 D940 00C0 CPLKKY * &C0 ;CAPITALS lock key 0357 D940 00D0 SHLKKY * &D0 ;SHIFT lock key 0358 D940 0359 D940 0360 D940 ; FX numbers 0361 D940 ; 0362 D940 0088 FXCODE * &88 0363 D940 0089 FXMOTR * &89 0364 D940 008B FXOPT * &8B 0365 D940 008C FXTAPE * &8C 0366 D940 008D FXSROM * &8D 0367 D940 0090 FXTV * &90 0368 D940 0369 D940 0370 D940 ; MC6850 addresses 0371 D940 ; 0372 D940 FE08 RSCTL * ACIA 0373 D940 FE08 RSTAT * ACIA 0374 D940 FE09 RSDATA * ACIA +&01 0375 D940 0376 D940 0377 D940 ; miscellaneous 0378 D940 ; 0379 D940 0004 NADC * &04 ;number of ADC channels 0380 D940 0381 D940 0382 D940 ; 6522 addresses 0383 D940 ; 0384 D940 FE40 PBQ * VIAA 0385 D940 FE41 PAQ * VIAA +&01 0386 D940 FE42 DDRBQ * VIAA +&02 0387 D940 FE43 DDRAQ * VIAA +&03 0388 D940 FE44 TQCLQ * VIAA +&04 0389 D940 FE45 TQCHQ * VIAA +&05 0390 D940 FE46 TQLLQ * VIAA +&06 0391 D940 FE47 TQLHQ * VIAA +&07 0392 D940 FE48 TRCLQ * VIAA +&08 0393 D940 FE49 TRCHQ * VIAA +&09 0394 D940 FE4A SRQ * VIAA +&0A 0395 D940 FE4B ACRQ * VIAA +&0B 0396 D940 FE4C PCRQ * VIAA +&0C 0397 D940 000A CAPULS * &0A 0398 D940 000C CA2LO * &0C Acorn macro assembler Page 47 MOS30 Manifests 0399 D940 000E CA2HI * &0E 0400 D940 00A0 CBPULS * &A0 0401 D940 00C0 CB2LO * &C0 0402 D940 00E0 CB2HI * &E0 0403 D940 FE4D IFRQ * VIAA +&0D 0404 D940 FE4E IERQ * VIAA +&0E 0405 D940 FE4F PAPQ * VIAA +&0F 0406 D940 FE60 PBR * VIAB 0407 D940 FE61 PAR * VIAB +&01 0408 D940 FE62 DDRBR * VIAB +&02 0409 D940 FE63 DDRAR * VIAB +&03 0410 D940 FE64 TQCLR * VIAB +&04 0411 D940 FE65 TQCHR * VIAB +&05 0412 D940 FE66 TQLLR * VIAB +&06 0413 D940 FE67 TQLHR * VIAB +&07 0414 D940 FE68 TRCLR * VIAB +&08 0415 D940 FE69 TRCHR * VIAB +&09 0416 D940 FE6A SRR * VIAB +&0A 0417 D940 FE6B ACRR * VIAB +&0B 0418 D940 FE6C PCRR * VIAB +&0C 0419 D940 FE6D IFRR * VIAB +&0D 0420 D940 FE6E IERR * VIAB +&0E 0421 D940 FE6F PAPR * VIAB +&0F 0422 D940 0423 D940 0424 D940 ; interrupt flags in 6522 IER and IFR 0425 D940 ; 0426 D940 0002 CA1 * &0002 0427 D940 0001 CA2 * &0001 0428 D940 0010 CB1 * &0010 0429 D940 0008 CB2 * &0008 0430 D940 0040 TIMER1 * &0040 0431 D940 0020 TIMER2 * &0020 0432 D940 0433 D940 0434 D940 ; VIA pin assignments 0435 D940 ; 0436 D940 ; VIAA:- 0437 D940 ; PA7-PA0 keyboard 0438 D940 ; CA1 VSYNC interrupt 0439 D940 0002 VSYNC * CA1 0440 D940 ; CA2 keyboard interrupt ('any key down') 0441 D940 0001 KEYBD * CA2 0442 D940 ; PB7 VSP interrupt 0443 D940 ; PB6 VSP ready 0444 D940 ; PB5,PB4 paddle 0445 D940 ; PB3-PB0 addressable latch 0446 D940 ; PB3 data value 0447 D940 ; PB2-PB0 latch register 0448 D940 ; 0 sound enable 0449 D940 ; 1 speech RS 0450 D940 ; 2 speech WS 0451 D940 ; 3 keyboard disable 0452 D940 ; 4,5 hardware scroll 0453 D940 ; 6,7 ROM select 0454 D940 ; CB1 ADC 0455 D940 0010 ADC * CB1 0456 D940 ; CB2 light pen 0457 D940 0458 D940 ; VIAB:- 0459 D940 ; PA7-PA0 printer output 0460 D940 ; CA1 printer acknowledge 0461 D940 0002 PRNT * CA1 0462 D940 ; CA2 printer strobe 0463 D940 ; PB7-PB0 reserved for user 0464 D940 ; CB1 reserved for user 0465 D940 ; CB2 reserved for user 0466 D940 ; TIMER 1 = MAIN CLOCK 0467 D940 0040 CLOCK * TIMER1 0468 D940 0469 D940 0470 D940 ; page one is main system stack 0471 D940 ; 0472 D940 00FF STACK * &FF 0473 D940 0474 D940 0475 D940 0476 D940 ; BUFFERS 0477 D940 0478 D940 0479 D940 ; keyboard 0480 D940 ; 0481 D940 03E0 RDCHBF * &03E0 ;RDCH (keyboard) buffer 0482 D940 0020 RDCHSZ * &0020 0483 D940 0484 D940 0485 D940 ; sound 0486 D940 ; 0487 D940 0800 SNDWRK * &0800 ;sound workspace 0488 D940 0804 MACTIV * SNDWRK+&04 ;activation flags 0489 D940 0490 D940 0840 SNDBF1 * &0840 ;sound buffer channel 1 0491 D940 0010 SBSIZE * &0010 ;sound buffer size 0492 D940 0850 SNDBF2 * SNDBF1+SBSIZE ;sound buffer channel 2 0493 D940 0860 SNDBF3 * SNDBF2+SBSIZE ;sound buffer channel 3 0494 D940 0870 SNDBF4 * SNDBF3+SBSIZE ;sound buffer channel 4 0495 D940 0496 D940 0497 D940 ; printer 0498 D940 ; 0499 D940 0880 PRNBF * &0880 ;print buffer 0500 D940 0040 PRNSZ * &0040 0501 D940 0502 D940 0503 D940 ; envelopes 0504 D940 ; 0505 D940 08C0 ENVEL * &08C0 ;sound envelopes 0506 D940 0010 ENVSIZ * &0010 ;size of each envelope 0507 D940 0004 NENV * &0004 ;number of envelopes 0508 D940 0509 D940 0510 D940 ; RS423 output 0511 D940 ; 0512 D940 0900 RSROBF * &0900 ;RS423 output 0513 D940 00C0 RSROSZ * &00C0 0514 D940 0515 D940 0516 D940 ; speech 0517 D940 ; 0518 D940 09C0 SPCHBF * &09C0 ;speech buffer 0519 D940 0040 SPCHSZ * &0040 Acorn macro assembler Page 48 MOS30 Manifests 0520 D940 0521 D940 0522 D940 ; RS423 input 0523 D940 ; 0524 D940 0A00 RSRIBF * &0A00 ;RS423 input 0525 D940 0100 RSRISZ * &0100 0526 D940 0008 RSOVR * 8 ;handshake overflow allowance 0527 D940 0528 D940 0529 D940 ; soft key buffer 0530 D940 ; 0531 D940 0B00 SKPTR * &0B00 ;pointers to soft key strings 0532 D940 0010 NSOFTK * 16 0533 D940 0B01 SKBUF * SKPTR+&01 ;N.B. soft key pointers are relative to this origin 0534 D940 0B10 SKEND * SKPTR+NSOFTK ;logical end of string 0535 D940 00EF TOTSFT * SKPTR+&0100-SKEND-&01 ;soft key data byte size 0536 D940 0537 D940 0538 D940 LNK MOS32 0001 D940 0002 D940 ; -> MOS32 0003 D940 TTL MOS32 Initialisation and external interfaces 0004 D940 OPT MOS32 Acorn macro assembler Page 49 MOS32 Initialisation and external interfaces 0005 D940 ;(c) 1981 ACORN Computers Limited 0006 D940 ;BBC Microcomputer Machine Operating System (MOS) 0007 D940 ;Change record: 0008 D940 ;Author(s): 0009 D940 ;PB Paul Bond 0010 D940 ;MP Mike Prees 0011 D940 0012 D940 0013 D940 ; origin of real code 0014 D940 ORG ORIGIN ;MOS starts where VDU ends 0015 D940 0016 D940 0017 D940 IPAGE0 ;page zero values 0018 D940 ; externally accessed zero page values 0019 D940 ^ &00FF 0020 D940 ; 0021 D940 00FF ESCFLG # 0 ;Bit 7 of this is the escape flag 0022 D940 0023 D940 0024 D940 ; bit7 escape pending 0025 D940 ;= ZERO 0026 D940 0027 D940 00FF # -2 0028 D940 00FD REPTR # &00 ;pointer after BRK 0029 D940 ;= NULL /;hi-byte 0030 D940 ;= NULL ;lo-byte 0031 D940 0032 D940 00FD # -1 0033 D940 00FC TEMPA # &00 ;user IRQ routine save slot for register A 0034 D940 ;= NULL 0035 D940 0036 D940 00FC # -2 0037 D940 00FA SEIWK # &00 ;two work slots used whilst interrupts disabled 0038 D940 ; 0039 D940 00FA JMILO * SEIWK +&00 ;used by OSBYTE/OSWORD 0040 D940 00FB JMIHI * SEIWK +&01 ;used by OSBYTE/OSWORD 0041 D940 ; 0042 D940 00FA KEYSV * SEIWK +&00 ;work area for ... 0043 D940 00FB SKSZWK * SEIWK +&01 ; ... soft key compaction (also SKSIZE) 0044 D940 ; 0045 D940 00FA KTEMP * SEIWK +&00 ;work area for keyboard 0046 D940 ; 0047 D940 00FA BUFFLO * SEIWK +&00 ;work slots used by buffer management 0048 D940 00FB BUFFHI * SEIWK +&01 0049 D940 ; 0050 D940 00FA CRLO * SEIWK +&00 ;work slots used during ROM compare 0051 D940 00FB CRHI * SEIWK +&01 0052 D940 ; 0053 D940 00FA MASK * SEIWK +&00 ;work slots used by set Rx/Tx RS423 baud rates 0054 D940 00FB BAUD * SEIWK +&01 0055 D940 ; 0056 D940 00FA RSOP * SEIWK +&00 ;work slot used by RSUCTL 0057 D940 ; 0058 D940 00FA NOTEWK * SEIWK +&00 ;work slot used by NOTE 0059 D940 ; 0060 D940 00FA EVENTA * SEIWK +&00 ;work slot used by EVENT (hopefully no clashes) 0061 D940 ; 0062 D940 00FA PEEKLO * SEIWK +&00 ;work slot used by OSWORD read-byte/write-byte 0063 D940 00FB PEEKHI * SEIWK +&01 0064 D940 ; 0065 D940 00FA SPWK1 * SEIWK +&00 ;used by speech sprocessing 0066 D940 00FB SPWK2 * SEIWK +&01 ;used by TIMER2 (speech) interrupt routine 0067 D940 0068 D940 00FA # -1 0069 D940 00F9 SPARE0 # &00 ;**************** 0070 D940 ; = NULL 0071 D940 0072 D940 00F9 # -1 0073 D940 00F8 SPARE1 # &00 ;**************** 0074 D940 ;= NULL 0075 D940 0076 D940 00F8 # -2 0077 D940 00F6 ROMPTR # &00 ;pointer used by ROM filing system 0078 D940 ;= NULL 0079 D940 ;= NULL 0080 D940 0081 D940 00F6 # -1 0082 D940 00F5 SEROM # &00 ;serial ROM id 0083 D940 ;= NULL 0084 D940 0085 D940 00F5 # -1 0086 D940 00F4 ROMID # &00 ;currently selected ROM 0087 D940 0088 D940 ;= NULL 0089 D940 0090 D940 00F4 # -2 0091 D940 00F2 WORK # &00 ;miscellaneous pointer 0092 D940 ;= NULL 0093 D940 ;= NULL 0094 D940 0095 D940 00F2 # -2 0096 D940 ; WORD values may be shared with other sei-routines 0097 D940 00F0 WORDX # &00 0098 D940 00F0 BYTEX * WORDX 0099 D940 00F1 WORDY * WORDX +&01 0100 D940 00F1 BYTEY * WORDY 0101 D940 0102 D940 00F0 # -1 0103 D940 00EF WORDA # &00 0104 D940 00EF BYTEA * WORDA 0105 D940 ;= NULL 0106 D940 0107 D940 00EF # -1 0108 D940 00EE PAGE1M # &00 ;selected page for 1MHz bus 0109 D940 ;= ZERO 0110 D940 0111 D940 00EE # -1 0112 D940 00ED OKEY # &00 ;current key value 0113 D940 ;= ZERO 0114 D940 0115 D940 00ED # -1 0116 D940 00EC CKEY # &00 ;current key value 0117 D940 ;= ZERO 0118 D940 0119 D940 00EC # -1 0120 D940 00EB ESSEMA # &00 ;EXEC/SPOOL semaphore (used by CFS) 0121 D940 0122 D940 0123 D940 00EB # -1 0124 D940 00EA RSTUT # &00 ;RS423 printer timeouT 0125 D940 ;= ZERO Acorn macro assembler Page 50 MOS32 Initialisation and external interfaces 0126 D940 0127 D940 00EA # -2 0128 D940 00E8 RDLNBF # &00 ;buffer address used by OSWORD readline routine 0129 D940 0130 D940 00E8 # -1 0131 D940 00E7 ARCTR # &00 ;auto-repeat counter 0132 D940 ;= ZERO 0133 D940 0134 D940 00E7 # -1 0135 D940 00E6 WRKCLI # &00 ;shared work slot with interrupts enabled 0136 D940 ; 0137 D940 00E6 RDCTEM * WRKCLI ;used by RDCH 0138 D940 00E6 CLIRY * WRKCLI ;used by CLI decoder 0139 D940 ; 0140 D940 00E6 NUMBER * WRKCLI ;work slot for GETNUM 0141 D940 00E6 CSKEY * NUMBER ;current softkey number (must not share with KMASK or KQUOTE) 0142 D940 ; 0143 D940 00E6 FILEY * WRKCLI ;save area for register Y 0144 D940 00E6 EXECY * FILEY ;save area used by EXEC 0145 D940 0146 D940 00E6 SPOOLY * FILEY ;save area used by SPOOL 0147 D940 ;= NULL 0148 D940 0149 D940 00E6 # -1 0150 D940 00E5 FXREGX # &00 ;used by FX CLI command 0151 D940 00E5 KMASK # &00 ;used by GSREAD 0152 D940 ; must not be shared with CSKEY 0153 D940 ;= NULL 0154 D940 0155 D940 00E5 # -1 0156 D940 00E4 FXREGY # &00 ;used by FX CLI command 0157 D940 00E4 KQUOTE # &00 ;must not be shared with KMASK 0158 D940 ; must not be shared with CSKEY 0159 D940 ;= NULL 0160 D940 0161 D940 00E4 # -1 0162 D940 00E3 CFS1 # &00 ;reserved for CFS 0163 D940 0164 D940 00E3 # -1 0165 D940 ; 0166 D940 ; CFS workspace 0167 D940 ; ============= 0168 D940 ; 0169 D940 00E2 CFS0 # &00 ;reserved for CFS 0170 D940 00E2 CFSTAT * CFS0 0171 D940 ;PAGE ZERO 0172 D940 0173 D940 00B0 PZERO * &00B0 ;Start of p.0 workspace 0174 D940 0175 D940 00B0 BKADDR * PZERO ;4 BYTE BLOCK PTR. 0176 D940 00B4 HIADDR * BKADDR +&04 ;Top of data being saved, 0177 D940 ;Must be contiguous with BKADDR 0178 D940 0179 D940 00B4 BLOKNO * HIADDR 0180 D940 00B6 SRCHBK * BLOKNO +&02 ;Block numbers being searched for 0181 D940 ;Not used in SAVE, hence can overlap HIADDR 0182 D940 0183 D940 00B8 FTPTR * HIADDR +&04 ;Used in VSTRIN 0184 D940 00BA ERRSW * FTPTR +&02 ;In p.0 to save space 0185 D940 00BB USFLGS * ERRSW +&01 0186 D940 00BC TEMP * USFLGS +&01 0187 D940 00BD IBUF * TEMP +&01 0188 D940 00BE CHKSUM * IBUF +&01 0189 D940 00C0 IFLAG * CHKSUM +&02 0190 D940 00C1 HDRCRC * IFLAG +&01 0191 D940 00C2 ITYPE * HDRCRC +&01 0192 D940 00C3 CURDRV * ITYPE +&01 ;Currently selected cassette 0193 D940 00C4 IADDR * CURDRV +&01 0194 D940 00C6 SPEED * IADDR +&02 0195 D940 00C7 GAPTIM * SPEED +&01 0196 D940 00C8 GENPTR * GAPTIM +&01 ;Used in FILEGO/LOAD only 0197 D940 00CA TXFLAG * GENPTR +&02 ;"We are transmitting" flag 0198 D940 00CB CRCCNT * TXFLAG +&01 ;Used in CRC check 0199 D940 00CC FSIZE * CRCCNT + 1 ;File size to modify control block in LOAD 0200 D940 0201 D940 00E3 OPTS * CFS1 ;Retained over filing system change 0202 D940 ;************************************** 0203 D940 0204 D940 00E2 BPAGE0 # &00 0205 D940 0206 D940 0207 D940 0208 D940 IPAGE2 0209 D940 ; page two values 0210 D940 ^ &0200 0211 D940 0200 APAGE2 # &00 0212 D940 0200 USRVEC # &02 ;user vector 0213 D940 10 = BADFX 0214 D941 E3 = /(BADFX ) 0215 D942 0202 BRKVEC # &02 ;BRK handling 0216 D942 54 = DEFBRK 0217 D943 DC = /(DEFBRK ) 0218 D944 0204 IRQALL # &02 ;all IRQs indirect thru here 0219 D944 93 = DEFIRQ 0220 D945 DC = /(DEFIRQ ) 0221 D946 0206 IRQVEC # &02 ;unrecognised IRQ 0222 D946 89 = IRQTWO 0223 D947 DE = /(IRQTWO ) 0224 D948 0208 COMVEC # &02 ;command line intepreter 0225 D948 89 = CLINT 0226 D949 DF = /(CLINT ) 0227 D94A 020A BYTVEC # &02 ;MOS routine, 0 1 or 2 arguments 0228 D94A 72 = BYTE 0229 D94B E7 = /(BYTE ) 0230 D94C 020C WORVEC # &02 ;MOS routine, >2 arguments 0231 D94C EB = WORD 0232 D94D E7 = /(WORD ) 0233 D94E 020E WRCVEC # &02 ;write character 0234 D94E A4 = WRCH 0235 D94F E0 = /(WRCH ) 0236 D950 0210 RDCVEC # &02 ;read character 0237 D950 C5 = RDCH 0238 D951 DE = /(RDCH ) 0239 D952 CFSTAB 0240 D952 0212 FILVEC # &02 ;load/save memory image 0241 D952 7D = FILEGO 0242 D953 F2 = /(FILEGO ) 0243 D954 0214 ARGVEC # &02 ;read/set file attributes 0244 D954 8E = ARGGO 0245 D955 F1 = /(ARGGO ) 0246 D956 0216 BGTVEC # &02 ;get byte from random file Acorn macro assembler Page 51 MOS32 Initialisation and external interfaces 0247 D956 C9 = GETBYT 0248 D957 F4 = /(GETBYT ) 0249 D958 0218 BPTVEC # &02 ;put byte to random file 0250 D958 29 = PUTBYT 0251 D959 F5 = /(PUTBYT ) 0252 D95A 021A GPBVEC # &02 ;get/put bytes 0253 D95A A6 = RTS 0254 D95B FF = /(RTS ) 0255 D95C 021C FNDVEC # &02 ;open/close random file 0256 D95C CA = FIND 0257 D95D F3 = /(FIND ) 0258 D95E 021E FSCVEC # &02 ;file system control entry 0259 D95E B1 = FSFUNC 0260 D95F F1 = /(FSFUNC ) 0261 D960 0220 EVTVEC # &02 ;event interrupt 0262 D960 A6 = DEFEVT 0263 D961 FF = /(DEFEVT ) 0264 D962 0222 UPTVEC # &02 ;user print routine 0265 D962 ; default hangs printer 0266 D962 A6 = DEFUPT 0267 D963 FF = /(DEFUPT ) 0268 D964 0224 NETVEC # &02 ;ECONET effects 0269 D964 ; default hangs printer 0270 D964 A6 = DEFNET 0271 D965 FF = /(DEFNET ) 0272 D966 0226 VDUVEC # &02 ;VDU command indirection 0273 D966 0274 D966 A6 = RTS 0275 D967 FF = /(RTS ) 0276 D968 0228 KEYVEC # &02 ;keyboard control indirection 0277 D968 02 = DEFKEY 0278 D969 EF = /(DEFKEY ) 0279 D96A 022A INSVEC # &02 ;buffer insert indirection 0280 D96A B3 = INS 0281 D96B E4 = /(INS ) 0282 D96C 022C REMVEC # &02 ;buffer remove indirection 0283 D96C 64 = REM 0284 D96D E4 = /(REM ) 0285 D96E 022E CNPVEC # &02 ;buffer count / purge buffer indirection 0286 D96E D1 = CNP 0287 D96F E1 = /(CNP ) 0288 D970 0230 INDONE # &02 0289 D970 A6 = RTS 0290 D971 FF = /(RTS ) 0291 D972 0232 INDTWO # &02 0292 D972 A6 = RTS 0293 D973 FF = /(RTS ) 0294 D974 0234 INDTRH # &02 0295 D974 A6 = RTS 0296 D975 FF = /(RTS ) 0297 D976 0036 VLEN * @-APAGE2 0298 D976 ; 0299 D976 001B NP2IND * VLEN:SHR: 1 ;number of page 2 indirections 0300 D976 0051 ROMIVS * NP2IND* 3 ;page ROM indirection vector size 0301 D976 0D9F ROMVEC * &0DF0-ROMIVS ;paged ROM routine vectors 0302 D976 0303 D976 0304 D976 0236 VARS # &00 0305 D976 ; 0306 D976 0236 # &02 ;variables origin 0307 D976 90 = VBASE ;166 0308 D977 01 = /(VBASE ) 0309 D978 0310 D978 0238 # &02 ;origin of 3-byte ROM indirection vectors 0311 D978 9F = ROMVEC ;168 0312 D979 0D = /(ROMVEC ) 0313 D97A 0314 D97A 023A # &02 ;paged ROM info 0315 D97A A1 = ROMS ;170 0316 D97B 02 = /(ROMS ) 0317 D97C 0318 D97C 023C # &02 ;keyboard matrix info 0319 D97C 2B = KTBL ;172 0320 D97D F0 = /(KTBL ) 0321 D97E 0322 D97E 023E # &02 ;VDU module origin of variables 0323 D97E 00 = VARBLE ;174 0324 D97F 03 = /(VARBLE ) 0325 D980 0326 D980 0240 CYCLE # &01 ;filing system timeout byte 0327 D980 0328 D980 00 = NULL 0329 D981 0330 D981 0241 RDCHSW # &01 ;RDCH source switch (assumed not in page zero, see KTBL) 0331 D981 00 = ZERO ;177 BRDCH (zero) 0332 D982 0333 D982 0242 KSEMA # &01 ;keyboard semaphore 0334 D982 FF = &FF ;178 0335 D983 0336 D983 0243 IHWM # &01 0337 D983 0338 D983 00 = ZERO ;179 0339 D984 0340 D984 0244 HWM # &01 0341 D984 0342 D984 00 = NULL ;180 0343 D985 0344 D985 0245 RS8BIT # &01 0345 D985 01 = &01 ;181 1 => 8 bits, 0 => soft key processing 0346 D986 0347 D986 0348 D986 0246 FONTSW # &01 ;current state of font explosion/implosion 0349 D986 0350 D986 00 = ZERO ;182 0351 D987 ; 0352 D987 0247 SROMSW # &01 ;SEROM/cassette switch 0353 D987 0354 D987 00 = ZERO ;183 cassette by default 0355 D988 0356 D988 0357 D988 0248 VPREGA # &01 ;video ULA control register 0 0358 D988 00 = NULL ;184 0359 D989 ; 0360 D989 0249 VPREGB # &01 ;video ULA control register 1 0361 D989 00 = NULL ;185 0362 D98A 0363 D98A 0364 D98A 024A REPROM # &01 ;ROM id after BRK 0365 D98A 00 = NULL ;186 0366 D98B ; 0367 D98B 024B BROMID # &01 ;BASIC ROM id Acorn macro assembler Page 52 MOS32 Initialisation and external interfaces 0368 D98B FF = &FF ;187 0369 D98C 0370 D98C 0371 D98C 024C ADCHAN # &01 ;ADC channel number 0372 D98C 04 = NADC ;188 0373 D98D ; 0374 D98D 024D MAXADC # &01 ;maximum ADC channel in use 0375 D98D 04 = NADC ;189 0376 D98E ; 0377 D98E 024E ADCCNV # &01 0378 D98E 00 = ZERO ;190 ADC conversion type (12 bits) 0379 D98F 0380 D98F 0381 D98F 024F RSFLAG # &01 ;RS423 use flag 0382 D98F 0383 D98F ; 1xxx xxxx => dormant 0384 D98F ; 0xxx xxxx => busy 0385 D98F FF = &FF ;191 0386 D990 ; 0387 D990 0250 RSCTFL # &01 0388 D990 0389 D990 56 = RSCDEF ;192 0390 D991 0391 D991 0392 D991 ; 0393 D991 0251 FLCNT # &01 ;flash period counter 0394 D991 19 = &19 ;193 1/2 SECOND 0395 D992 ; 0396 D992 0252 FLASHB # &00 ;used by flash FX calls 0397 D992 0252 FLSPC # &01 ;flash space period 0398 D992 19 = &19 ;194 1/2 SECOND 0399 D993 0253 FLMRK # &01 ;flash mark period 0400 D993 19 = &19 ;195 1/2 SECOND 0401 D994 ; 0402 D994 0403 D994 0404 D994 ;**** FOLLOWING MUST BE CONTIGUOUS (c.f. *FX11 and *FX12) **** 0405 D994 0254 FARSET # &01 ;first auto-repeat reset 0406 D994 32 = DAUTOD ;196 0407 D995 0255 ARSET # &01 ;reset for above 0408 D995 08 = DAUTOP ;197 0409 D996 0410 D996 0411 D996 0256 EXECH # &01 ;*EXEC handle 0412 D996 0413 D996 00 = ZERO ;198 0414 D997 ; 0415 D997 0257 SPOOLH # &01 ;*SPOOL handle 0416 D997 0417 D997 00 = ZERO ;199 0418 D998 ; 0419 D998 0258 CRIT # &01 ;critical region indicator 0420 D998 0421 D998 00 = &00 ;200 not within critical region 0422 D999 ; 0423 D999 0259 NETKDS # &01 ;net keyboard disable 0424 D999 00 = ZERO ;201 default: not disabled 0425 D99A ; 0426 D99A 025A KSTAT # &01 ;keyboard status (see MOS56) 0427 D99A 20 = SHFTL ;202 0428 D99B ; 0429 D99B 025B RSHLVL # &01 ;RS423 handshake level 0430 D99B 09 = RSOVR+&01 ;203 0431 D99C ; 0432 D99C 025C RSSHUT # &01 ;suppress RS423 input 0433 D99C 00 = ZERO ;204 default: enable RS423 input 0434 D99D ; 0435 D99D 025D RSCASS # &01 ;cassette/RS423 serial processor select 0436 D99D 00 = ZERO ;205 $00 => select RS423, $40 => select cassette 0437 D99E ; 0438 D99E 025E NETIOC # &01 ;net interception of OS calls 0439 D99E 00 = ZERO ;206 default: not intercepted 0440 D99F ; 0441 D99F 025F NETRDC # &01 ;net interception of RDCH 0442 D99F 00 = ZERO ;207 default: not intercepted 0443 D9A0 ; 0444 D9A0 0260 NETWRC # &01 ;net interception of WRCH 0445 D9A0 00 = ZERO ;208 default: not intercepted 0446 D9A1 ; 0447 D9A1 0261 SHUTSP # &01 ;speech suppressor 0448 D9A1 50 = SPOPSP ;209 0449 D9A2 ; 0450 D9A2 0262 SHUTUP # &01 ;sound suppressor 0451 D9A2 00 = ZERO ;210 allow sound by default 0452 D9A3 ; 0453 D9A3 0263 BELLC # &01 ;bell channel 0454 D9A3 03 = &03 ;211 0455 D9A4 ; 0456 D9A4 0264 BELLI # &01 ;bell envelope and chord information 0457 D9A4 90 = &90 ;212 0458 D9A5 ; 0459 D9A5 0265 BELLN # &01 ;bell frequency 0460 D9A5 64 = &64 ;213 0461 D9A6 ; 0462 D9A6 0266 BELLD # &01 ;bell duration 0463 D9A6 06 = &06 ;214 0464 D9A7 ; 0465 D9A7 0267 QUIET # &01 0466 D9A7 81 = &81 ;215 suppress start-up message / !BOOT option 0467 D9A8 ; 0468 D9A8 0268 SOFKL # &01 ;soft key string length 0469 D9A8 00 = ZERO ;216 0470 D9A9 ; 0471 D9A9 0269 LINES # &01 ;used by VDU software 0472 D9A9 0473 D9A9 00 = ZERO ;217 used by VDU software in page mode 0474 D9AA ; 0475 D9AA 026A QPOSN # &01 ;VDU queue count 0476 D9AA 0477 D9AA 00 = ZERO ;218 0478 D9AB ; 0479 D9AB 026B TABCOD # &01 ;TAB key code 0480 D9AB 09 = TAB ;219 0481 D9AC ; 0482 D9AC 026C INTCH # &01 0483 D9AC 1B = ESC ;220 interrupt character (normally ESC) 0484 D9AD ; 0485 D9AD 026D SOFTLO # &00 0486 D9AD ;221 softkey 10 feature 0487 D9AD 026D EXBREK # &01 0488 D9AD 01 = &01 ;expand softkey Acorn macro assembler Page 53 MOS32 Initialisation and external interfaces 0489 D9AE ;222 reserved 0490 D9AE 026E # &01 0491 D9AE D0 = &D0 0492 D9AF ;223 reserved 0493 D9AF 026F # &01 0494 D9AF E0 = &E0 0495 D9B0 ;224 reserved 0496 D9B0 0270 # &01 0497 D9B0 F0 = &F0 0498 D9B1 ;225 0499 D9B1 ; 0 => enable softkey expansion on fnkey 0500 D9B1 ; N => return code N+i for fnkey(i), i=0..9 0501 D9B1 0271 # &01 0502 D9B1 01 = &01 ;return soft strings by default 0503 D9B2 ;226 0504 D9B2 ; 0 => enable softkey expansion on SHIFT/fnkey 0505 D9B2 ; N => return code N+i for SHIFT/fnkey(i), i=0..9 0506 D9B2 0272 # &01 0507 D9B2 80 = &80 ;return codes $80..$89 by default (user definable characters) 0508 D9B3 ;227 0509 D9B3 ; 0 => enable softkey expansion on CTRL/fnkey 0510 D9B3 ; N => return code N+i for CTRL/fnkey(i), i=0..9 0511 D9B3 0273 # &01 0512 D9B3 90 = &90 ;return codes $90..$99 by default (user definable characters) 0513 D9B4 ;228 0514 D9B4 ; 0 => enable softkey expansion on SHIFT/CTRL/fnkey 0515 D9B4 ; N => return code N+i for SHIFT/CTRL/fnkey(i), i=0..9 0516 D9B4 0274 # &01 0517 D9B4 00 = ZERO ;ingnore key combination by default 0518 D9B5 0519 D9B5 0275 ESCHAR # &01 ;make INTERRUPT CHARACTER return normal value 0520 D9B5 00 = ZERO ;229 <>0 => return normal value 0521 D9B6 0522 D9B6 0276 EAOPT # &01 ;suppress normal escape acknowledge actions 0523 D9B6 00 = ZERO ;230 suppress if <> 0 0524 D9B7 0525 D9B7 0277 B6522 # &01 ;$00 => no, $FF => second 6522 present 0526 D9B7 FFBYT 0527 D9B7 FF = &FF ;231 assume 6522B present 0528 D9B8 0529 D9B8 0278 C6850 # &01 ;$00 => no, $FF => 6850 present 0530 D9B8 FF = &FF ;232 assume 6850 present 0531 D9B9 0532 D9B9 0279 A6522 # &01 ;$00 => no, $FF => primary 6522 present 0533 D9B9 FF = &FF ;233 assume 6522A present 0534 D9BA 0535 D9BA 027A TUBEM # &01 ;$FF if tube present 0536 D9BA 027A TUBE * TUBEM 0537 D9BA 00 = ZERO ;234 assume tube not present 0538 D9BB 0539 D9BB 027B SPFLAG # &01 ;$FF if speech chip present 0540 D9BB 00 = ZERO ;235 0541 D9BC 0542 D9BC 027C WRCHSW # &01 ;OSWRCH destinations flag 0543 D9BC 0001 WRRS * &01 ;WRCH is RS423 0544 D9BC 0002 WRVDU * &02 ;WRCH is ***NOT*** VDU 0545 D9BC 0004 WRPREN * &04 ;0 => ENABLE PRINT 0546 D9BC 0008 WRPRNT * &08 ;WRCH is ***NOT*** print 0547 D9BC 0010 WRSPL * &10 ;WRCH is ***NOT*** spool 0548 D9BC 0040 WRVDU1 * &40 ;WRCH to printer only by VDU1 0549 D9BC 00 = ZERO ;236 WRCH is VDU/print/spool 0550 D9BD ; ******** DO NOT ALTER ******** 0551 D9BD 0552 D9BD 027D CURSED # &01 0553 D9BD 00 = ZERO ;237 0554 D9BE 0555 D9BE 007E MPAGE2 * @-APAGE2 0556 D9BE 0557 D9BE 027E SPARE8 # &03 0558 D9BE 00 = ZERO 0559 D9BF 00 = ZERO 0560 D9C0 00 = ZERO 0561 D9C1 ; 238, 239, 240 0562 D9C1 0563 D9C1 0281 UFX1 # &01 ;FX 1 value 0564 D9C1 00 = ZERO ;241 0565 D9C2 ; ******** DO NOT ALTER ******** 0566 D9C2 0567 D9C2 0282 SPREGA # &01 ;serial processor register contents 0568 D9C2 0569 D9C2 64 = B9600 ;242 0570 D9C3 0571 D9C3 0283 TIMESW # &01 ;TIME pointer, either 5 or 10 0572 D9C3 05 = &05 ;243 0573 D9C4 0574 D9C4 0284 USKFLG # &01 ;soft key consistency flag 0575 D9C4 FF = &FF ;244 =0 => soft keys consistent 0576 D9C5 0577 D9C5 0285 PRNTSW # &01 ;PRINT destination flag 0578 D9C5 0001 PCEN * &01 ;print is (C)ENTRONICS 0579 D9C5 0002 PRS * &02 ;print is (RS)232 0580 D9C5 0003 PUSE * &03 ;print is (user) routine 0581 D9C5 0004 PNET * &04 ;print is ECO(NET) 0582 D9C5 01 = PCEN ;245 0583 D9C6 ; ******** DO NOT ALTER ******** 0584 D9C6 0585 D9C6 0286 PIGNOR # &01 ;printer ignore character 0586 D9C6 0A = MLF ;246 support auto-linefeed printers by default 0587 D9C7 ; ******** DO NOT ALTER ******** 0588 D9C7 0589 D9C7 0087 PPAGE2 * @-APAGE2 0590 D9C7 0591 D9C7 0287 BREAKI # &03 ;used for interception of BREAK 0592 D9C7 00 = ZERO ;247 change to $4C to intercept BREAK 0593 D9C8 00 = ZERO ;248 0594 D9C9 00 = ZERO ;249 0595 D9CA 0596 D9CA 028A SPARE9 # &02 ;spare 0597 D9CA 00 = ZERO ;250 0598 D9CB 00 = ZERO ;251 0599 D9CC 0600 D9CC 028C LROMID # &01 ;current language ROM id 0601 D9CC FF = &FF ;252 0602 D9CD 0603 D9CD 008D NPAGE2 * @-APAGE2 0604 D9CD 0605 D9CD 028D TYPE # &01 ;restart type 0606 D9CD ;= ZERO ;253 0607 D9CD 0608 D9CD 028E MODELB # &01 0609 D9CD 028E MODEL * MODELB Acorn macro assembler Page 54 MOS32 Initialisation and external interfaces 0610 D9CD ;= ZERO ;254 0611 D9CD 0612 D9CD 028F OPTION # &01 ;start up options 0613 D9CD ;= ZERO ;255 0614 D9CD 0615 D9CD 0190 VBASE * @-&100 0616 D9CD 00A6 VORG * VARS-VBASE 0617 D9CD [ VARS-VBASE- 166=0 0618 D9CD | 0620 D9CD ] 0621 D9CD ; 0622 D9CD 0623 D9CD 0290 DPAGE2 # &00 0624 D9CD 0625 D9CD 0290 VERTIC # &01 ;VDU vertical adjust 0626 D9CD 0627 D9CD ;= ZERO 0628 D9CD 0629 D9CD 0291 INTERL # &01 ;interlace invert 0630 D9CD 0631 D9CD ;= ZERO 0632 D9CD 0633 D9CD ; time 0634 D9CD 0292 TIME1 # &05 ;first absolute time counter 0635 D9CD 0292 TIME * TIME1 0636 D9CD ;= ZERO 0637 D9CD ;= ZERO 0638 D9CD ;= ZERO 0639 D9CD ;= ZERO 0640 D9CD ;= ZERO 0641 D9CD 0297 TIME2 # &05 ;second absolute time counter 0642 D9CD ;= ZERO 0643 D9CD ;= ZERO 0644 D9CD ;= ZERO 0645 D9CD ;= ZERO 0646 D9CD ;= ZERO 0647 D9CD ; N.B. soft restart zeroes from here onwards 0648 D9CD 029C STPW # &05 ;stopwatch counter 0649 D9CD 029C CPAGE2 * STPW 0650 D9CD ;= ZERO 0651 D9CD ;= ZERO 0652 D9CD ;= ZERO 0653 D9CD ;= ZERO 0654 D9CD ;= ZERO 0655 D9CD 0656 D9CD 02A1 ROMS # NROM 0657 D9CD 0658 D9CD ;= ZERO (NROM times) 0659 D9CD 0660 D9CD ; work slots used by CLI 0661 D9CD 02B1 RDCTLO # &01 ;INKEY wait counter 1 0662 D9CD ;= ZERO 0663 D9CD 02B2 RDCTHI # &01 ;INKEY wait counter 2 0664 D9CD ;= ZERO 0665 D9CD 0666 D9CD ; work slots used by RDLN 0667 D9CD ; values must not be altered by any sei-routine 0668 D9CD 02B3 RDLNN # &01 0669 D9CD ;= NULL 0670 D9CD 02B4 RDLNLC # &01 0671 D9CD ;= NULL 0672 D9CD 02B5 RDLNHC # &01 0673 D9CD ;= NULL 0674 D9CD 0675 D9CD ; ADC control 0676 D9CD ; may not be shared 0677 D9CD 02B6 ADCLOV # NADC ;ADC lo byte values (0 to 3) 0678 D9CD ;= ZERO 0679 D9CD ;= ZERO 0680 D9CD ;= ZERO 0681 D9CD ;= ZERO 0682 D9CD 02BA ADCHIV # NADC ;ADC hi byte values (0 to 3) 0683 D9CD ;= ZERO 0684 D9CD ;= ZERO 0685 D9CD ;= ZERO 0686 D9CD ;= ZERO 0687 D9CD 02BE ADCFLG # &01 0688 D9CD ;= ZERO 0689 D9CD 0690 D9CD ; event interrupt vectors 0691 D9CD 000A NEVENT * &000A ;total number of events 0692 D9CD 02BF EVENTS # NEVENT ;event flags 0693 D9CD 0000 EVMPTY * &00 ;output buffer empty 0694 D9CD ;= ZERO 0695 D9CD 0001 EVFULL * &01 ;input buffer full 0696 D9CD ;= ZERO 0697 D9CD 0002 EVKYBD * &02 ;keyboard interrupt 0698 D9CD ;= ZERO 0699 D9CD 0003 EVADC * &03 ;ADC conversion complete 0700 D9CD ;= ZERO 0701 D9CD 0004 EVVSYN * &04 ;VSYNC 0702 D9CD ;= ZERO 0703 D9CD 0005 EVSWCH * &05 ;(timer) stopwatch 0704 D9CD ;= ZERO 0705 D9CD 0006 EVESC * &06 ;escape detected 0706 D9CD ;= ZERO 0707 D9CD 0007 EVRS * &07 ;RS423 Rx error 0708 D9CD ;= ZERO 0709 D9CD 0008 EVUSER * &08 ;user allocated event 0710 D9CD ;= ZERO 0711 D9CD 0712 D9CD ; miscellaneous 0713 D9CD 02C9 SOFKP # &01 ;pointer to soft key string 0714 D9CD ;= NULL 0715 D9CD ; 0716 D9CD 02CA FARCTR # &01 ;first auto-repeat count 0717 D9CD ;= NULL 0718 D9CD 0719 D9CD 02CB KSCSTA # &03 ;keyboard scan start address work vector 0720 D9CD ;= NULL 0721 D9CD 0722 D9CD ; values to be initialised to $FF 0723 D9CD 02CE FFBYTE # &00 0724 D9CD ; 0725 D9CD 02CE SSEMA # &01 ;sound semaphore 0726 D9CD ; 0727 D9CD ; buffer activity flags 0728 D9CD 02CF BACTIV # &00 0729 D9CD 02CF DUMMY # 3 ;Not used - necessary for padding (see PURGE) 0730 D9CD 02D2 PFLAG # &01 ;print flag 0731 D9CD ; 1xxx xxxx => dormant Acorn macro assembler Page 55 MOS32 Initialisation and external interfaces 0732 D9CD ; 0xxx xxxx => busy 0733 D9CD 02D3 SFLUSH # &04 ;sound flush flags 0734 D9CD 02D7 SPSTAT # &01 ;speech processor status 0735 D9CD ; 0736 D9CD ; buffer control 0737 D9CD ; buffer start page offsets 0738 D9CD 02D8 BFSTRT # BUPB+&01 0739 D9CD ; buffer end page offsets 0740 D9CD 02E1 BFEND # BUPB+&01 0741 D9CD ; 0742 D9CD 02EA CFSA # &03 0743 D9CD 0744 D9CD ; 0745 D9CD 02ED CFSD # &01 0746 D9CD 0747 D9CD 02EE FBLOCK # &12 ;load/save control block 0748 D9CD 0000 FSTR * &0000 ;pointer to filename (2 bytes) 0749 D9CD 0002 FLOAD * &0002 ;load address (4 bytes) 0750 D9CD 0006 FEXEC * &0006 ;execute address (4 bytes) 0751 D9CD 000A FFROM * &000A ;from address (4 bytes) 0752 D9CD 000E FTO * &000E ;to address (4 bytes) 0753 D9CD ;= 18*NULL 0754 D9CD 0755 D9CD 0300 ZPAGE2 # &00 0756 D9CD 0757 D9CD LNK MOS34 0001 D9CD 0002 D9CD ; MOS34 0003 D9CD TTL MOS34 Initialisation 0004 D9CD OPT MOS34 Acorn macro assembler Page 56 MOS34 Initialisation 0005 D9CD 0006 D9CD ;(c) 1981 ACORN Computers Limited 0007 D9CD ;BBC Microcomputer MOS 0008 D9CD 0009 D9CD ;Change record: 0010 D9CD ;100 15-Apr-82 PB Use PCEN=1 0011 D9CD ;039 15-Aug-81 PB Start of change to PROTON interface 0012 D9CD ;004 29-Jul-81 MP Prototype version 0013 D9CD 0014 D9CD ;Author(s): 0015 D9CD ;PB Paul Bond 0016 D9CD ;MP Mike Prees 0017 D9CD TTL Entry point after hardware break/reset 0018 D9CD OPT OPNEWP Acorn macro assembler Page 57 Entry point after hardware break/reset 0019 D9CD 0020 D9CD 0021 D9CD MRESET ;entered here after reset 0022 D9CD 0023 D9CD ; ensure NMIs are ignored as sson as possible 0024 D9CD ; 0025 D9CD A9 40 LDAIM &40 ;A := RTI opcode 0026 D9CF 8D 00 0D STA NMI 0027 D9D2 0028 D9D2 ; ensure interrupts disabled (useful for JMP -4 freaks) 0029 D9D2 ; 0030 D9D2 78 SEI 0031 D9D3 0032 D9D3 ; clear decimal mode 0033 D9D3 ; 0034 D9D3 D8 CLD 0035 D9D4 0036 D9D4 ; reset stack 0037 D9D4 ; 0038 D9D4 A2 FF LDXIM &FF 0039 D9D6 9A TXS 0040 D9D7 0041 D9D7 ; push hard reset status 0042 D9D7 ; 0043 D9D7 AD 4E FE LDA IERQ 0044 D9DA 0A ASLA 0045 D9DB 48 PHA ;A=0 => hard, A<>0 => soft 0046 D9DC F0 09 BEQ HRDRST ;[hard reset, A=0] 0047 D9DE ; 0048 D9DE ; prepare for possible soft reset 0049 D9DE ; 0050 D9DE ; check for critical region 0051 D9DE ; 0052 D9DE AD 58 02 LDA CRIT 0053 D9E1 4A LSRA 0054 D9E2 C9 01 CMPIM &01 0055 D9E4 D0 1D BNE SFTRST ;[not within a critical region] 0056 D9E6 ; A=1 0057 D9E6 4A LSRA 0058 D9E7 ; A=0 0059 D9E7 ; 0060 D9E7 ; within a critical region - clear store 0061 D9E7 ; 0062 D9E7 HRDRST ;hard reset 0063 D9E7 ; A=0 0064 D9E7 ; hard reset 0065 D9E7 ; clear store 0066 D9E7 A2 04 LDXIM &04 ;start clearing at page 4 0067 D9E9 86 01 STX &0001 0068 D9EB 85 00 STA &0000 0069 D9ED A8 TAY ;Y := 0 0070 D9EE ; clear store to $00 (no blobs on screen) 0071 D9EE CLEAR 0072 D9EE 91 00 STAIY &0000 0073 D9F0 C5 01 CMP &0001 0074 D9F2 F0 09 BEQ CLEAR0 ;[16K RAM] 0075 D9F4 C8 INY 0076 D9F5 D0 F7 BNE CLEAR 0077 D9F7 ; Y=0 0078 D9F7 C8 INY 0079 D9F8 ; Y=1 0080 D9F8 E8 INX 0081 D9F9 E6 01 INC &0001 0082 D9FB 10 F1 BPL CLEAR 0083 D9FD ; 32K RAM 0084 D9FD ; 0085 D9FD CLEAR0 0086 D9FD ; $0001 = $80 (model B) or $40 (model A) 0087 D9FD 8E 8E 02 STX MODELB 0088 DA00 ; 0089 DA00 ; force soft keys reset 0090 DA00 8E 84 02 STX USKFLG ;USKFLG := non-zero 0091 DA03 ; 0092 DA03 SFTRST 0093 DA03 ; 0094 DA03 ; initialise addressable latch outputs hi 0095 DA03 ; 0096 DA03 A2 0F LDXIM &0F ;for latch driving 0097 DA05 8E 42 FE STX DDRBQ ;set PB3-PB0 as outputs to drive addressable latch 0098 DA08 ; 0099 DA08 IALTCH 0100 DA08 CA DEX 0101 DA09 8E 40 FE STX PBQ ;first store value = $0E, last store value = $08 0102 DA0C E0 09 CPXIM &09 0103 DA0E B0 F8 BCS IALTCH 0104 DA10 ; fall thru when X=$08 0105 DA10 0106 DA10 0107 DA10 ; check for hard restart 0108 DA10 ; 0109 DA10 ; read start-up options 0110 DA10 ; 0111 DA10 E8 INX ;X := $09, scan down from last start-up option 0112 DA11 ; 0113 DA11 RDOPT1 0114 DA11 8A TXA ;save X in A 0115 DA12 20 2A F0 JSR KC ;read state of matrix element addressed by X (A maintained) 0116 DA15 ; 0117 DA15 ; N.B. does not corrupt A 0118 DA15 ; 0119 DA15 E0 80 CPXIM &80 ;C=0 => option open, C=1 => option closed 0120 DA17 66 FC ROR TEMPA ;rotate state of start-up option into TEMPA byte 0121 DA19 AA TAX ;restore X 0122 DA1A CA DEX 0123 DA1B D0 F4 BNE RDOPT1 ;execute loop 9 times 0124 DA1D ; 0125 DA1D ; N.B. exits with X=0, SHIFT key has not been scanned 0126 DA1D ; state of CTRL key has been rotated into TEMPA 0127 DA1D ; 0128 DA1D 8E 8D 02 STX TYPE ;restart type := 0 0129 DA20 26 FC ROL TEMPA ;C = state of CTRL key, TEMPA = start-up options 0130 DA22 20 EB EE JSR KBDIS ;disable keyboard (and resume hardware scan) 0131 DA25 ; 0132 DA25 6A RORA ;C=1 => CTRL pressed (KBDIS does PHP ... PLA) 0133 DA26 ; 0134 DA26 A2 9C LDXIM CPAGE2 ;(do not set to reset timer if soft restart) 0135 DA28 A0 8D LDYIM NPAGE2 ;reset BREAKI if power up 0136 DA2A 68 PLA ;pull hard restart status 0137 DA2B F0 09 BEQ POWER ;[power up] 0138 DA2D ; 0139 DA2D A0 7E LDYIM MPAGE2 ;prepare for BREAK Acorn macro assembler Page 58 Entry point after hardware break/reset 0140 DA2F 90 11 BCC SOFT ;[CTRL not pressed - force soft reset, b1b0(TYPE) := 0] 0141 DA31 ; 0142 DA31 ; b1b0(TYPE) := 2 0143 DA31 ; 0144 DA31 A0 87 LDYIM PPAGE2 ;CTRL/BREAK 0145 DA33 EE 8D 02 INC TYPE 0146 DA36 ; 0147 DA36 POWER ;power up, b1b0(TYPE) := 1 0148 DA36 ;HARD ;hard restart 0149 DA36 EE 8D 02 INC TYPE 0150 DA39 ; 0151 DA39 ; initialise OPTION 0152 DA39 ; 0153 DA39 A5 FC LDA TEMPA 0154 DA3B 49 FF EORIM &FF ;invert VDU mode selection 0155 DA3D 8D 8F 02 STA OPTION 0156 DA40 ; 0157 DA40 A2 90 LDXIM DPAGE2 ;set to reset timer 0158 DA42 0159 DA42 0160 DA42 SOFT 0161 DA42 ; initialise other page two locations to zero/$FF 0162 DA42 ; N.B. X has been set to an appropriate value 0163 DA42 A9 00 LDAIM ZERO 0164 DA44 IP0SX 0165 DA44 E0 CE CPXIM FFBYTE 0166 DA46 90 02 BCC Z0BYTE 0167 DA48 A9 FF LDAIM &FF 0168 DA4A Z0BYTE 0169 DA4A 9D 00 02 STAAX &0200 0170 DA4D E8 INX 0171 DA4E D0 F4 BNE IP0SX 0172 DA50 ; N.B. A=$FF, X=0 0173 DA50 8D 63 FE STA DDRAR ;set all outputs on printer data direction register (6522B) 0174 DA53 0175 DA53 0176 DA53 ; initialise page zero locations to zero 0177 DA53 ; 0178 DA53 8A TXA ;A := 0 0179 DA54 A2 E2 LDXIM BPAGE0 0180 DA56 IP0SW 0181 DA56 95 00 STAAX ZERO 0182 DA58 E8 INX 0183 DA59 D0 FB BNE IP0SW 0184 DA5B ; X=0 0185 DA5B 0186 DA5B 0187 DA5B ; initialise page two specific values 0188 DA5B ; 0189 DA5B IP2SV 0190 DA5B B9 3F D9 LDAAY IPAGE2 -&01 0191 DA5E 99 FF 01 STAAY APAGE2 -&01 0192 DA61 88 DEY 0193 DA62 D0 F7 BNE IP2SV 0194 DA64 ; Y=0 0195 DA64 0196 DA64 0197 DA64 ; make old key space in case CFS auto-boot selected 0198 DA64 ; 0199 DA64 A9 62 LDAIM &62 0200 DA66 85 ED STA OKEY 0201 DA68 ; X=0, Y=0 0202 DA68 0203 DA68 0204 DA68 ; setup MC6850 0205 DA68 ; 0206 DA68 20 0A FB JSR MC6850 ;N.B. does not corrupt X or Y 0207 DA6B ; X=0, Y=0 0208 DA6B 0209 DA6B 0210 DA6B ; clear any 6522 interrupt status 0211 DA6B ; 0212 DA6B A9 7F LDAIM &7F 0213 DA6D E8 INX ;X=1 0214 DA6E IFRIER ;X=1 initialises IERQ&IERR, X=0 initialises IFRQ&IFRR 0215 DA6E 9D 4D FE STAAX IFRQ 0216 DA71 9D 6D FE STAAX IFRR 0217 DA74 CA DEX 0218 DA75 10 F7 BPL IFRIER ;[execute loop once more with X=0] 0219 DA77 ; X=$FF 0220 DA77 ; 0221 DA77 [ FALSE=0 0224 DA77 ] 0225 DA77 0226 DA77 ; TEMPA is now 0 0227 DA77 ; if an interrupt occurs it will adopt the value $7F 0228 DA77 ; 0229 DA77 ; allow test equipment to interrupt if present 0230 DA77 ; 0231 DA77 58 CLI 0232 DA78 ; ** TEST EQUIPMENT INTERRUPT MAY OCCUR HERE ** 0233 DA78 78 SEI 0234 DA79 ; 0235 DA79 24 FC BIT TEMPA 0236 DA7B 50 03 BVC NOTST1 0237 DA7D ; C=0 0238 DA7D 20 55 F0 JSR JMITST ;enter test routine (first call) 0239 DA80 NOTST1 0240 DA80 0241 DA80 0242 DA80 [ FALSE=0 0261 DA80 ] 0262 DA80 0263 DA80 0264 DA80 ; initialise 6522s 0265 DA80 ; 0266 DA80 A2 F2 LDXIM &F2 ;enable TIMER1(clock,40), TIMER2(speech,20) 0267 DA82 ; CB1(ADC,10), CA1(VSYNC,02) and NOT[CA2(keyboard,01)] 0268 DA82 8E 4E FE STX IERQ 0269 DA85 0270 DA85 0271 DA85 ; initialise peripheral control register 0272 DA85 ; 0273 DA85 A2 04 LDXIM &04 0274 DA87 8E 4C FE STX PCRQ ;select CA2 positive active edge 0275 DA8A 0276 DA8A 0277 DA8A ; setup centisecond timer 0278 DA8A ; 0279 DA8A A9 60 LDAIM &60 ;TIMER1 continuous, TIMER2 count pulses on PB6 0280 DA8C 8D 4B FE STA ACRQ Acorn macro assembler Page 59 Entry point after hardware break/reset 0281 DA8F 0282 DA8F 0283 DA8F ; N.B. ACRR zeroed by reset 0284 DA8F ; 0285 DA8F ; set timer hi-byte 0286 DA8F ; 0287 DA8F A9 0E LDAIM &0E ;timer 1 period = 998 usec 0288 DA91 8D 46 FE STA TQLLQ 0289 DA94 8D 6C FE STA PCRR ;set CA2 hi (for printer) 0290 DA97 ; 0291 DA97 ; start conversion on analog/digital chip 0292 DA97 ; 0293 DA97 8D C0 FE STA ADCCTL ;12 bits from chip channel 2 0294 DA9A 0295 DA9A 0296 DA9A ; check whether 6522B present 0297 DA9A ; 0298 DA9A CD 6C FE CMP PCRR 0299 DA9D F0 03 BEQ B6522E ;[6522B exists] 0300 DA9F ; 0301 DA9F ; 6522B does not exist 0302 DA9F ; 0303 DA9F EE 77 02 INC B6522 ;B6522 := $00 0304 DAA2 B6522E 0305 DAA2 ; 0306 DAA2 ; set timer lo-byte 0307 DAA2 ; 0308 DAA2 A9 27 LDAIM &27 0309 DAA4 8D 47 FE STA TQLHQ 0310 DAA7 8D 45 FE STA TQCHQ 0311 DAAA 0312 DAAA 0313 DAAA ; kill sound 0314 DAAA ; 0315 DAAA 20 60 EC JSR SNDRST 0316 DAAD 0317 DAAD 0318 DAAD ; ensure motor off 0319 DAAD ; reinitialise serproc 0320 DAAD ; 0321 DAAD AD 82 02 LDA SPREGA 0322 DAB0 29 7F ANDIM &7F 0323 DAB2 20 A7 E6 JSR STASP ;STA SPREGA, STA SERPRC 0324 DAB5 ; X, Y corrupted 0325 DAB5 0326 DAB5 0327 DAB5 ; conditionally reset soft keys 0328 DAB5 ; soft keys are reset 0329 DAB5 ; (a) after a hard reset 0330 DAB5 ; (b) if reset occurred during a critical update of the soft keys 0331 DAB5 ; 0332 DAB5 AE 84 02 LDX USKFLG 0333 DAB8 F0 03 BEQ SKOK 0334 DABA 20 C8 E9 JSR RSOFT ;reset soft keys, sets X=0 0335 DABD SKOK 0336 DABD ; X=0 0337 DABD 0338 DABD 0339 DABD ; compare ROMs 0340 DABD ; 0341 DABD CRX 0342 DABD 20 16 DC JSR STXROM ;select ROM 0343 DAC0 ; 0344 DAC0 ; check for copyright string 0345 DAC0 ; 0346 DAC0 A2 03 LDXIM &03 0347 DAC2 AC 07 80 LDY COPYRP 0348 DAC5 CRCPYR 0349 DAC5 B9 00 80 LDAAY LANG 0350 DAC8 DD 0C DF CMPAX COPYR 0351 DACB D0 2E BNE CRBAD 0352 DACD C8 INY 0353 DACE CA DEX 0354 DACF 10 F4 BPL CRCPYR 0355 DAD1 ; 0356 DAD1 ; ROM has copyright string 0357 DAD1 ; 0358 DAD1 A6 F4 LDX ROMID 0359 DAD3 A4 F4 LDY ROMID 0360 DAD5 CRY 0361 DAD5 C8 INY 0362 DAD6 C0 10 CPYIM NROM 0363 DAD8 B0 25 BCS CRNX ;[Y > number of ROMs] 0364 DADA 98 TYA 0365 DADB 49 FF EORIM &FF 0366 DADD 85 FA STA CRLO 0367 DADF A9 7F LDAIM &7F ;N.B. this is LANG / - 1 0368 DAE1 85 FB STA CRHI 0369 DAE3 CRLOOP 0370 DAE3 8C 30 FE STY ROM ;select second (Y) ROM 0371 DAE6 B1 FA LDAIY CRLO 0372 DAE8 8E 30 FE STX ROM ;select first (X) ROM 0373 DAEB D1 FA CMPIY CRLO 0374 DAED D0 E6 BNE CRY ;[ROMs do not match] 0375 DAEF E6 FA INC CRLO 0376 DAF1 D0 F0 BNE CRLOOP 0377 DAF3 E6 FB INC CRHI 0378 DAF5 A5 FB LDA CRHI 0379 DAF7 C9 84 CMPIM &84 ;compare only first 1K of ROMs 0380 DAF9 90 E8 BCC CRLOOP 0381 DAFB ; ROMs match 0382 DAFB CRBAD 0383 DAFB A6 F4 LDX ROMID 0384 DAFD 10 0D BPL CRNX1 ;[ALWAYS jump] 0385 DAFF ; NEVER fall thru 0386 DAFF ; 0387 DAFF CRNX 0388 DAFF AD 06 80 LDA ROMTYP 0389 DB02 9D A1 02 STAAX ROMS ;store type of recognised ROM 0390 DB05 ; check for BASIC ROM 0391 DB05 ;***** N.B. WHITE BASIC MAY NEED 'ANDIM $FE' ***** 0392 DB05 29 8F ANDIM &8F 0393 DB07 D0 03 BNE CRNX1 ;[not a BASIC ROM] 0394 DB09 ; BASIC ROM - remember ROM id for *BASIC command 0395 DB09 8E 4B 02 STX BROMID 0396 DB0C CRNX1 0397 DB0C E8 INX 0398 DB0D E0 10 CPXIM NROM 0399 DB0F 90 AC BCC CRX ;[X a valid ROM number] 0400 DB11 ; X=NROM 0401 DB11 ; Acorn macro assembler Page 60 Entry point after hardware break/reset 0402 DB11 ; if speech chip ready is still high then the chip has not been fitted 0403 DB11 ; 0404 DB11 2C 40 FE BIT PBQ 0405 DB14 30 11 BMI START1 ;[chip does not exist] 0406 DB16 ; X=NROM 0407 DB16 ; speech chip present 0408 DB16 ; 0409 DB16 CE 7B 02 DEC SPFLAG ;SPFLAG := $FF 0410 DB19 ; X=NROM 0411 DB19 ; reset speech processor 0412 DB19 ; 0413 DB19 ; write NROM * $FF (reset) to speech processor 0414 DB19 SPRST1 0415 DB19 A0 FF LDYIM SPOPRT 0416 DB1B 20 7F EE JSR WSPECH ;N.B. corrupts A and Y 0417 DB1E CA DEX 0418 DB1F D0 F8 BNE SPRST1 0419 DB21 ; X=0 0420 DB21 ; 0421 DB21 8E 48 FE STX TRCLQ 0422 DB24 8E 49 FE STX TRCHQ ;enable interrupt after one negative pulse on PB6 (speech int) 0423 DB27 START1 0424 DB27 0425 DB27 0426 DB27 AD 8F 02 LDA OPTION ;initialise graphics mode from start-up options 0427 DB2A 20 00 C3 JSR VDINIT ;initialise VDU module 0428 DB2D 0429 DB2D 0430 DB2D ; set up reset soft key (fA) 0431 DB2D ; 0432 DB2D A0 CA LDYIM BREKEY 0433 DB2F 20 F1 E4 JSR RDCHS ;set to expand softkeyA immediately 0434 DB32 ; C=0 cos buffer empty 0435 DB32 ; 0436 DB32 ; let user intercept BREAK 0437 DB32 ; 0438 DB32 ; C=0 0439 DB32 20 D9 EA JSR BREAK 0440 DB35 ; 0441 DB35 ; initialise CFS state 0442 DB35 ; 0443 DB35 20 40 F1 JSR INIT 0444 DB38 ; 0445 DB38 ; check for tube 0446 DB38 ; 0447 DB38 A9 81 LDAIM &81 0448 DB3A 8D E0 FE STA TREG0 0449 DB3D AD E0 FE LDA TREG0 0450 DB40 6A RORA 0451 DB41 90 0A BCC NOTUBE ;[tube not present] 0452 DB43 ; 0453 DB43 ; tube present 0454 DB43 ; 0455 DB43 A2 FF LDXIM SVTUBE 0456 DB45 20 68 F1 JSR SVOP ;initialise tube 0457 DB48 D0 03 BNE NOTUBE ;[tube software not present] 0458 DB4A CE 7A 02 DEC TUBEM ;TUBEM := $FF 0459 DB4D NOTUBE 0460 DB4D ; 0461 DB4D ; initialise service ROMs before writing to screen 0462 DB4D ; 0463 DB4D A0 0E LDYIM /(OSHWM ) ;Y := default high water mark 0464 DB4F ; 0465 DB4F A2 01 LDXIM SVSTAT ;offer static area 0466 DB51 20 68 F1 JSR SVOP 0467 DB54 ; 0468 DB54 A2 02 LDXIM SVDYN ;offer dynamic area 0469 DB56 20 68 F1 JSR SVOP 0470 DB59 ; 0471 DB59 8C 43 02 STY IHWM ;save adjusted high water mark 0472 DB5C 8C 44 02 STY HWM ;save adjusted high water mark 0473 DB5F ; 0474 DB5F ; allow tube post-initialisation (e.g. exploding font) 0475 DB5F ; 0476 DB5F A2 FE LDXIM SVTPIN ;******** ASSUMED = $FE ******** 0477 DB61 AC 7A 02 LDY TUBEM ;pass tube flag as argument 0478 DB64 20 68 F1 JSR SVOP 0479 DB67 ; A=$00 (tube present) 0480 DB67 ; A=$FF (tube not present) 0481 DB67 ; 0482 DB67 ; conditionally output start-up message 0483 DB67 ; 'BBC Computer' 0484 DB67 ; 0485 DB67 2D 67 02 AND QUIET ;may be set by paged ROM 0486 DB6A 10 1B BPL ENTER ;[shshh ... you know who] 0487 DB6C ; 0488 DB6C ; output start up message 0489 DB6C ; 0490 DB6C A0 02 LDYIM MSGBBC-&01 0491 DB6E 20 A9 DE JSR WRSTR 0492 DB71 ; 0493 DB71 ; indicate model type 0494 DB71 ; 0495 DB71 AD 8D 02 LDA TYPE 0496 DB74 F0 0C BEQ Z ;[soft restart] 0497 DB76 ; 0498 DB76 ; hard restart 0499 DB76 ; complete message 0500 DB76 ; 0501 DB76 A0 16 LDYIM MSG32K-&01 0502 DB78 2C 8E 02 BIT MODELB 0503 DB7B 30 02 BMI B ;[model B] 0504 DB7D ; 0505 DB7D ; model A 0506 DB7D ; 0507 DB7D A0 11 LDYIM MSG16K-&01 0508 DB7F B 0509 DB7F 20 A9 DE JSR WRSTR 0510 DB82 Z 0511 DB82 A0 1B LDYIM MSG2CR-&01 0512 DB84 20 A9 DE JSR WRSTR 0513 DB87 ; 0514 DB87 ENTER ;initialise TAPE/DISC 0515 DB87 ; 0516 DB87 ; let user intercept BREAK after filing system initialisation 0517 DB87 ; 0518 DB87 38 SEC 0519 DB88 20 D9 EA JSR BREAK 0520 DB8B ; 0521 DB8B ; service ROMs again 0522 DB8B ; test for auto-boot condition (SHIFT and startup option bit3) Acorn macro assembler Page 61 Entry point after hardware break/reset 0523 DB8B ; 0524 DB8B 20 D9 E9 JSR MOSTST ;test shift 0525 DB8E 08 PHP 0526 DB8F 68 PLA ;b7(A) => SHIFT pressed 0527 DB90 4A LSRA 0528 DB91 4A LSRA 0529 DB92 4A LSRA 0530 DB93 4A LSRA 0531 DB94 4D 8F 02 EOR OPTION 0532 DB97 29 08 ANDIM &08 ;use bit3 0533 DB99 A8 TAY ;Y=0 => auto-boot, Y<>0 => do not auto-boot 0534 DB9A A2 03 LDXIM SVBOOT ;offer bootstrap 0535 DB9C 20 68 F1 JSR SVOP 0536 DB9F F0 1D BEQ SLANG ;[file system booted] 0537 DBA1 ; 0538 DBA1 ; file system not booted - try to auto-boot from SEROM 0539 DBA1 ; 0540 DBA1 98 TYA 0541 DBA2 D0 14 BNE NOAUTO ;[do not auto boot] 0542 DBA4 ; 0543 DBA4 ; auto-boot from SEROM 0544 DBA4 ; 0545 DBA4 A9 8D LDAIM FXSROM 0546 DBA6 20 35 F1 JSR CROM ;'*ROM' 0547 DBA9 A2 D2 LDXIM SLBOOT 0548 DBAB A0 EA LDYIM /(SLBOOT ) 0549 DBAD CE 67 02 DEC QUIET ;flag as loading auto-boot program 0550 DBB0 20 F7 FF JSR OSCLI ;'/!BOOT' 0551 DBB3 EE 67 02 INC QUIET ;flag as not loading auto-boot program 0552 DBB6 ; if an error occurs whilst running the !BOOT program 0553 DBB6 ; then the MOS jumps to EBRK (early BRK) 0554 DBB6 D0 06 BNE DNRFS ;[ALWAYS jump, do not reset filing system] 0555 DBB8 ; 0556 DBB8 NOAUTO 0557 DBB8 EBRK ;unexpected (early) BRK (e.g. 'File not found') 0558 DBB8 ; 0559 DBB8 ; initialise cassette filing system (CFS) 0560 DBB8 ; 0561 DBB8 A9 00 LDAIM ZERO ;select CFS 0562 DBBA AA TAX ;X:=0, select default baudrate (1200 baud) 0563 DBBB 20 37 F1 JSR TAPE12 ;initialise CFS 0564 DBBE ; 0565 DBBE DNRFS ;do not reset filing system 0566 DBBE ; 0567 DBBE SLANG ;select a language ROM to enter 0568 DBBE AD 8D 02 LDA TYPE 0569 DBC1 D0 05 BNE SLANG1 ;[hard restart - use same language as last time] 0570 DBC3 ; 0571 DBC3 ; soft restart - ensure language exists 0572 DBC3 ; 0573 DBC3 AE 8C 02 LDX LROMID 0574 DBC6 10 1E BPL ILR2 ;[language does exist] 0575 DBC8 ; 0576 DBC8 SLANG1 ;find first language ROM 0577 DBC8 ; 0578 DBC8 A2 0F LDXIM NROM-&1 0579 DBCA ILR1 0580 DBCA BD A1 02 LDAAX ROMS 0581 DBCD 2A ROLA 0582 DBCE 30 16 BMI ILR2 ;[found language ROM] 0583 DBD0 ; 0584 DBD0 CA DEX 0585 DBD1 10 F7 BPL ILR1 ;[continue search for language ROM] 0586 DBD3 ; 0587 DBD3 A9 00 LDAIM LGNONE 0588 DBD5 2C 7A 02 BIT TUBEM 0589 DBD8 30 2E BMI TLANG ;[tube active] 0590 DBDA ; neither language nor tube present 0591 DBDA 00 BRK 0592 DBDB F9 = NOLROM 0593 DBDC 4C 61 6E = "Language?" 0594 DBE5 00 = ZERO 0595 DBE6 ; 0596 DBE6 ILR2 0597 DBE6 18 CLC ;indicate to tube that this is a restart 0598 DBE7 SELANG ;FX entry point, entered with C=1 (for tube) 0599 DBE7 ; found language ROM 0600 DBE7 ; select language ROM 0601 DBE7 08 PHP ;save entry type (present in C) 0602 DBE8 8E 8C 02 STX LROMID 0603 DBEB 20 16 DC JSR STXROM 0604 DBEE ; output ROM message 0605 DBEE A9 80 LDAIM /(LANG ) 0606 DBF0 A0 08 LDYIM ROMMSG-&1 0607 DBF2 20 AB DE JSR WRSTRA 0608 DBF5 ; N.B. Y offset left pointing to copyright message 0609 DBF5 84 FD STY REPTR +&00 0610 DBF7 20 E7 FF JSR OSNEWL 0611 DBFA 20 E7 FF JSR OSNEWL 0612 DBFD ; 0613 DBFD ; enter language 0614 DBFD ; 0615 DBFD 28 PLP ;restore entry type into C 0616 DBFE A9 01 LDAIM LGENTR ;entry reason 0617 DC00 2C 7A 02 BIT TUBEM 0618 DC03 30 03 BMI TLANG ;[tube active] 0619 DC05 4C 00 80 JMP ROMHRD ;ROM entry 0620 DC08 TLANG 0621 DC08 4C 00 04 JMP TBLANG ;tube entry 0622 DC0B 0623 DC0B 0624 DC0B LNK MOS36 0001 DC0B ; > MOS36 0002 DC0B TTL MOS36 Int servicing 0003 DC0B OPT MOS36 Acorn macro assembler Page 62 MOS36 Int servicing 0004 DC0B 0005 DC0B ;(c) 1981 ACORN Computers Limited 0006 DC0B ;BBC MOS 0007 DC0B ;Change record: 0008 DC0B 0009 DC0B ;Author(s): 0010 DC0B ;PB Paul Bond 0011 DC0B 0012 DC0B ; interrupt service mainline 0013 DC0B ; priority sequence:- 0014 DC0B ; [6850] 0015 DC0B ; 1. RS423 0016 DC0B ; [6522a] 0017 DC0B ; 2. VSYNC 0018 DC0B ; 3. centisecond timer 0019 DC0B ; 4. ADC 0020 DC0B ; 5. keyboard 0021 DC0B ; [6522b] 0022 DC0B ; 6. printer (parallel interface) 0023 DC0B 0024 DC0B 0025 DC0B RPROM ;read byte from paged ROM 0026 DC0B ; read byte at ROMPTR in ROM Y into A 0027 DC0B A6 F4 LDX ROMID 0028 DC0D 84 F4 STY ROMID 0029 DC0F 8C 30 FE STY ROM 0030 DC12 A0 00 LDYIM ZERO 0031 DC14 B1 F6 LDAIY ROMPTR 0032 DC16 STXROM 0033 DC16 86 F4 STX ROMID 0034 DC18 8E 30 FE STX ROM 0035 DC1B 60 RTS 0036 DC1C 0037 DC1C 0038 DC1C 0039 DC1C IRQ ;entered at IRQ or BRK 0040 DC1C 85 FC STA TEMPA 0041 DC1E 68 PLA 0042 DC1F 48 PHA ;A := processor status 0043 DC20 29 10 ANDIM &10 0044 DC22 D0 03 BNE BRK 0045 DC24 6C 04 02 JMI IRQALL ;indirect thru 'all IRQs' routine 0046 DC27 ; (defaults to DEFIRQ) 0047 DC27 ; 0048 DC27 BRK 0049 DC27 8A TXA 0050 DC28 48 PHA ;save X 0051 DC29 BA TSX 0052 DC2A BD 03 01 LDAAX &0100+&03 ;get address low 0053 DC2D D8 CLD 0054 DC2E 38 SEC 0055 DC2F E9 01 SBCIM &01 0056 DC31 85 FD STA REPTR +&00 0057 DC33 BD 04 01 LDAAX &0100+&04 ;get address high 0058 DC36 E9 00 SBCIM ZERO 0059 DC38 85 FE STA REPTR +&01 0060 DC3A ; record ROM source of BRK 0061 DC3A A5 F4 LDA ROMID 0062 DC3C 8D 4A 02 STA REPROM 0063 DC3F ; offer BRK to service ROMs 0064 DC3F 86 F0 STX BYTEX ;provide clean way for service ROM to access relevant stack area 0065 DC41 A2 06 LDXIM SVBRK 0066 DC43 20 68 F1 JSR SVOP 0067 DC46 ; force language ROM (may be BASIC in pre-interface days) 0068 DC46 AE 8C 02 LDX LROMID 0069 DC49 20 16 DC JSR STXROM ;reset to language ROM 0070 DC4C ; 0071 DC4C ; restore X 0072 DC4C ; 0073 DC4C 68 PLA 0074 DC4D AA TAX 0075 DC4E ; 0076 DC4E ; restore A 0077 DC4E ; 0078 DC4E A5 FC LDA TEMPA 0079 DC50 ; 0080 DC50 ; enable interrupts and let user process BRK 0081 DC50 ; 0082 DC50 58 CLI 0083 DC51 6C 02 02 JMI BRKVEC ;process BRK, N.B. default is DEFBRK 0084 DC54 ; 0085 DC54 DEFBRK ;default BRK routine outputs error message 0086 DC54 ; assume still decimal mode 0087 DC54 A0 00 LDYIM ZERO 0088 DC56 20 B1 DE JSR WRSTR1 ;output error message 0089 DC59 ; check whether within auto-boot program 0090 DC59 AD 67 02 LDA QUIET 0091 DC5C 6A RORA 0092 DC5D STOP 0093 DC5D B0 FE BCS STOP ;hang if not within auto-boot program 0094 DC5F 20 E7 FF JSR OSNEWL 0095 DC62 20 E7 FF JSR OSNEWL ;place 2*CR/LF after error message 0096 DC65 4C B8 DB JMP EBRK ;system continue 0097 DC68 0098 DC68 0099 DC68 0100 DC68 TTL IRQ processing 0101 DC68 OPT OPNEWP Acorn macro assembler Page 63 IRQ processing 0102 DC68 0103 DC68 0104 DC68 TXDINT ;disable Tx interrupt 0105 DC68 ; 0106 DC68 ; RS423 printer selected but printer buffer empty 0107 DC68 ; 0108 DC68 38 SEC 0109 DC69 6E 4F 02 ROR RSFLAG ;flag RS423 available 0110 DC6C ; 0111 DC6C ; no more characters to print 0112 DC6C ; 0113 DC6C ; disable RS423 Tx 0114 DC6C ; find whether to set RTS hi or lo 0115 DC6C ; 0116 DC6C ; check whether RS423 Rx enabled 0117 DC6C ; 0118 DC6C 2C 50 02 BIT RSCTFL 0119 DC6F 10 07 BPL RLO ;[Rx disabled] 0120 DC71 ; 0121 DC71 ; Rx enabled 0122 DC71 ; 0123 DC71 ; check bytes in RS423 input buffer 0124 DC71 ; 0125 DC71 20 41 E7 JSR CNTRS 0126 DC74 ; 0127 DC74 ; C=0 => overflow, C=1 => no overflow 0128 DC74 ; check whether within overflow region 0129 DC74 ; 0130 DC74 A2 00 LDXIM RHITXD 0131 DC76 B0 02 BCS RSOK ;[not overflowing] 0132 DC78 ; 0133 DC78 ; within overflow region 0134 DC78 ; 0135 DC78 RLO ;set RTS lo, Tx interrupt disabled (unfortunately) 0136 DC78 A2 40 LDXIM RLOTXD 0137 DC7A ; 0138 DC7A RSOK ;set RTS hi/lo, Tx interrupt disabled 0139 DC7A 4C 7A E1 JMP RSED ;disable Tx interrupts AND return from interrupt 0140 DC7D 0141 DC7D 0142 DC7D RX68 ;RS423 Rx interrupt 0143 DC7D ; 0144 DC7D ; A = 0|0|PE|OVRN|FE|CTS|DCD|TDRE 0145 DC7D ; 0146 DC7D AC 09 FE LDY RSDATA ;read data byte to clear interrupt 0147 DC80 29 3A ANDIM &3A ;CTS & TDRE are not relevant to Rx 0148 DC82 D0 34 BNE RX68BD ;[bad Rx, PE|OVRN|FE|DCD] 0149 DC84 ; 0150 DC84 ; good reception - move byte into RS423 input buffer 0151 DC84 ; 0152 DC84 AE 5C 02 LDX RSSHUT 0153 DC87 D0 09 BNE NRSI ;[suppress RS423 input] 0154 DC89 ; 0155 DC89 ; X=0 0156 DC89 ; 0157 DC89 E8 INX ;X = BRSI = $01 0158 DC8A 20 F3 E4 JSR RNSRT ;insert character into RS423 buffer 0159 DC8D ; 0160 DC8D ; check number of characters in buffer 0161 DC8D ; 0162 DC8D 20 41 E7 JSR CNTRS 0163 DC90 ; 0164 DC90 ; check whether running into overflow area 0165 DC90 ; 0166 DC90 90 E6 BCC RLO ;[running into overflow area, set RTS lo, Tx interrupt disabled] 0167 DC92 NRSI ;suppress RS423 input 0168 DC92 60 RTS 0169 DC93 0170 DC93 0171 DC93 DEFIRQ ;default IRQ routine 0172 DC93 D8 CLD 0173 DC94 A5 FC LDA TEMPA 0174 DC96 48 PHA 0175 DC97 8A TXA 0176 DC98 48 PHA 0177 DC99 98 TYA 0178 DC9A 48 PHA 0179 DC9B ; 0180 DC9B ; schedule return from interrupt 0181 DC9B ; 0182 DC9B A9 DE LDAIM /(IRQ0-&01) 0183 DC9D 48 PHA 0184 DC9E A9 81 LDAIM IRQ0-&01 0185 DCA0 48 PHA 0186 DCA1 ; 0187 DCA1 ; indicate in DEFIRQ 0188 DCA1 ; 0189 DCA1 B8 CLV 0190 DCA2 ; 0191 DCA2 IRQ68 ;check for interrupt from 6850 0192 DCA2 ; 0193 DCA2 [ $Tutu 0196 DCA2 | 0197 DCA2 AD 08 FE LDA RSTAT 0198 DCA5 ] 0199 DCA5 70 02 BVS RSTIME ;[timer interrupt] 0200 DCA7 ; 0201 DCA7 10 5D BPL IRQA ;[not a 6850 interrupt, N.B. possibly timer interrupt entry] 0202 DCA9 ; 0203 DCA9 RSTIME ;timer interrupt 0204 DCA9 ; 0205 DCA9 ; 6850 interrupt 0206 DCA9 ; 0207 DCA9 ; use RSTUT to decide where to route the interrupt 0208 DCA9 ; 0209 DCA9 A6 EA LDX RSTUT 0210 DCAB CA DEX 0211 DCAC 30 30 BMI NOTCFS ;[RS423 not managed by CFS] 0212 DCAE ; 0213 DCAE ; inform CFS of the interrupt 0214 DCAE ; 0215 DCAE 70 2D BVS RTS68 ;[ignore timer interrupt entry] 0216 DCB0 4C 88 F5 JMP IRUPT ;let CFS handle interrupt AND return from interrupt 0217 DCB3 0218 DCB3 0219 DCB3 MDCD ;neither Rx not Tx interrupt => DCD interrupt 0220 DCB3 ; 0221 DCB3 AC 09 FE LDY RSDATA ;clear DCD interrupt 0222 DCB6 2A ROLA ;DCD -> lo-bit 0223 DCB7 0A ASLA ;restore status byte 0224 DCB8 ; Acorn macro assembler Page 64 IRQ processing 0225 DCB8 RX68BD ;bad RS423 Rx 0226 DCB8 ; 0227 DCB8 ; A = 0|0|PE|OVRN|FE|0|DCD|0 0228 DCB8 ; C=1 0229 DCB8 ; 0230 DCB8 ; signal RS423 error 0231 DCB8 ; 0232 DCB8 AA TAX ;X := status 0233 DCB9 98 TYA ;A := character 0234 DCBA A0 07 LDYIM EVRS ;RS423 error event 0235 DCBC 4C 94 E4 JMP EVENT ;signal event AND return from interrupt 0236 DCBF 0237 DCBF 0238 DCBF TDRE ;Tx interrupt 0239 DCBF ; 0240 DCBF ; RS423 is not claimed by CFS, so we are either 0241 DCBF ; writing or printing to RS423 0242 DCBF ; 0243 DCBF ; extract character from RS423 Tx buffer 0244 DCBF ; 0245 DCBF A2 02 LDXIM BRSO 0246 DCC1 20 60 E4 JSR REMOV 0247 DCC4 90 10 BCC TXCH ;[character to transmit] 0248 DCC6 ; X=BRSO 0249 DCC6 ; 0250 DCC6 ; check for print to RS423 0251 DCC6 ; 0252 DCC6 AD 85 02 LDA PRNTSW 0253 DCC9 C9 02 CMPIM PRS 0254 DCCB D0 9B BNE TXDINT ;[RS423 printer not selected] 0255 DCCD ; X=BRSO 0256 DCCD ; 0257 DCCD ; remove possible character from print buffer 0258 DCCD ; 0259 DCCD E8 INX ;X = BRSO+1 = BPRNT 0260 DCCE 20 60 E4 JSR REMOV ;remove character from printer buffer 0261 DCD1 6E D2 02 ROR PFLAG ;update printer flag 0262 DCD4 30 92 BMI TXDINT ;[no character to print] 0263 DCD6 ; 0264 DCD6 TXCH ;transmit character in A 0265 DCD6 ; 0266 DCD6 8D 09 FE STA RSDATA ;transmit character 0267 DCD9 ; 0268 DCD9 ; set RS423 printer timeout active 0269 DCD9 ; 0270 DCD9 A9 E7 LDAIM PTIMUT 0271 DCDB 85 EA STA RSTUT 0272 DCDD ; 0273 DCDD 0274 DCDD RTS68 0275 DCDD UNK0 0276 DCDD 60 RTS ;return from interrupt 0277 DCDE 0278 DCDE 0279 DCDE NOTCFS ;RS423 not managed by CFS 0280 DCDE ; 0281 DCDE 2D 78 02 AND C6850 ;suppress bits according to user tastes 0282 DCE1 4A LSRA ;C=Rx 0283 DCE2 90 07 BCC NOTRX ;[not Rx int] 0284 DCE4 70 05 BVS NOTRX ;[do not allow Rx by polling] 0285 DCE6 ; 0286 DCE6 AC 50 02 LDY RSCTFL 0287 DCE9 30 92 BMI RX68 ;[recieve interrupts enabled] 0288 DCEB ; 0289 DCEB NOTRX 0290 DCEB 4A LSRA ;C=Tx, N=Rx 0291 DCEC 6A RORA ;C=DCD, N=Tx 0292 DCED B0 C4 BCS MDCD ;[DCD interrupt] 0293 DCEF ; 0294 DCEF 30 CE BMI TDRE ;[TDRE] 0295 DCF1 ; 0296 DCF1 70 EA BVS RTS68 ;[timer interrupt entry] 0297 DCF3 ; 0298 DCF3 ; not timer interrupt entry 0299 DCF3 ; 0300 DCF3 UNKIRQ ;unknown interrupt 0301 DCF3 ; 0302 DCF3 A2 05 LDXIM SVINT 0303 DCF5 20 68 F1 JSR SVOP ;allow FS ROMs to process interrupt 0304 DCF8 F0 E3 BEQ UNK0 ;[service ROM dealt with interrupt] 0305 DCFA ; 0306 DCFA ; pull return address 0307 DCFA ; 0308 DCFA 68 PLA 0309 DCFB 68 PLA 0310 DCFC ; 0311 DCFC ; restore X and Y for user interrupt routine 0312 DCFC ; 0313 DCFC 68 PLA 0314 DCFD A8 TAY 0315 DCFE 68 PLA 0316 DCFF AA TAX 0317 DD00 68 PLA 0318 DD01 85 FC STA TEMPA 0319 DD03 6C 06 02 JMI IRQVEC ;assume that user will clear the interrupt 0320 DD06 ; (defaults to IRQTWO) 0321 DD06 0322 DD06 0323 DD06 0324 DD06 IRQA ;check for interrupt from primary 6522 0325 DD06 ; 0326 DD06 AD 4D FE LDA IFRQ ;A = IFR [IRQ,TIMER1,TIMER2,CB1,CB2,SHIFTREG,CA1,CA2] 0327 DD09 10 3C BPL IRQB ;[not a VIAA interrupt] 0328 DD0B ; 0329 DD0B ; 0330 DD0B 2D 79 02 AND A6522 ;suppress bits according to user tastes 0331 DD0E 2D 4E FE AND IERQ ;N.B. only look at enabled interrupts 0332 DD11 ; 0333 DD11 ; 0334 DD11 6A RORA ;A = IFR >> 1 0335 DD12 6A RORA ;A = IFR >> 2, C = CA1, N = CA2 0336 DD13 90 54 BCC ITIME2 ;[not VSYNC interrupt] 0337 DD15 ; 0338 DD15 ; VSYNC interrupt 0339 DD15 ; N.B. C=1 0340 DD15 ; 0341 DD15 CE 40 02 DEC CYCLE ;update CFS timeout byte 0342 DD18 A5 EA LDA RSTUT ;decrement RS423 printer timeout 0343 DD1A 10 02 BPL NPRST 0344 DD1C E6 EA INC RSTUT 0345 DD1E ; Acorn macro assembler Page 65 IRQ processing 0346 DD1E NPRST ;no RS423 printer timeout 0347 DD1E ; 0348 DD1E AD 51 02 LDA FLCNT 0349 DD21 F0 1A BEQ IVS1 ;[flash disabled] 0350 DD23 CE 51 02 DEC FLCNT 0351 DD26 D0 15 BNE IVS1 ;[flash count not exhausted] 0352 DD28 ; 0353 DD28 ; flash count exhausted 0354 DD28 ; reset FLCNT 0355 DD28 ; 0356 DD28 AE 52 02 LDX FLSPC 0357 DD2B AD 48 02 LDA VPREGA 0358 DD2E 4A LSRA ;C = flash bit 0359 DD2F 90 03 BCC FLASH1 ;[flash bit = 0] 0360 DD31 ; flash bit = 1 0361 DD31 AE 53 02 LDX FLMRK 0362 DD34 FLASH1 0363 DD34 ; 0364 DD34 2A ROLA ;A = VPREGA 0365 DD35 49 01 EORIM &01 ;invert flash bit 0366 DD37 20 00 EA JSR MVPRC0 ;update video processor and register image 0367 DD3A 8E 51 02 STX FLCNT ;update flash count 0368 DD3D ; 0369 DD3D IVS1 0370 DD3D A0 04 LDYIM EVVSYN 0371 DD3F 20 94 E4 JSR EVENT 0372 DD42 ; 0373 DD42 A9 02 LDAIM VSYNC 0374 DD44 4C 6E DE JMP IVIAA0 ;clear interrupt and return 0375 DD47 0376 DD47 0377 DD47 0378 DD47 IRQB ;check for interrupt from secondary 6522 0379 DD47 ; 0380 DD47 AD 6D FE LDA IFRR ;A = IFR, C = ?, N = IRQ 0381 DD4A 10 A7 BPL UNKIRQ ;[not a VIAB interrupt] 0382 DD4C ; 0383 DD4C ; 0384 DD4C 2D 77 02 AND B6522 ;suppress bits if secondary 6522 not present 0385 DD4F 2D 6E FE AND IERR ;only look at enabled interrupts 0386 DD52 6A RORA ;A = IFR >> 1 0387 DD53 6A RORA ;A = IFR >> 2, C = CA1 0388 DD54 90 9D BCC UNKIRQ ;[not a printer interrupt] 0389 DD56 ; 0390 DD56 IPRNT ;printer interrupt 0391 DD56 ; 0392 DD56 ; acknowledge interrupt 0393 DD56 ; N.B. clear before sending next character since printer 0394 DD56 ; may acknowledge quickly and we could miss the interrupt 0395 DD56 AC 85 02 LDY PRNTSW 0396 DD59 88 DEY ;******** ASSUMES PCEN = 1 ******** 0397 DD5A D0 97 BNE UNKIRQ ;[ignore printer interrupt cos centronics not selected] 0398 DD5C ; 0399 DD5C A9 02 LDAIM PRNT 0400 DD5E 8D 6D FE STA IFRR ;acknowledge interrupt 0401 DD61 8D 6E FE STA IERR ;disable printer interrupt 0402 DD64 ; (will be enabled again by STROBE if another character is sent 0403 DD64 ; using the parallel port) 0404 DD64 ; 0405 DD64 A2 03 LDXIM BPRNT ;X := print bufferid 0406 DD66 4C 3A E1 JMP STROBE ;if character read then print it AND return from interrupt 0407 DD69 0408 DD69 0409 DD69 ITIME2 ;check for TIMER2 interrupt 0410 DD69 ; 0411 DD69 2A ROLA ;A = IFR >> 1 0412 DD6A 2A ROLA ;A = IFR 0413 DD6B 2A ROLA ;:A = IFR << 1, N = TIMER1 0414 DD6C 2A ROLA ;A = IFR << 2, N = TIMER2, C = TIMER1 0415 DD6D 10 5B BPL ITIME1 ;[not TIMER2, check for TIMER1 interrupt] 0416 DD6F ; 0417 DD6F ; timer 2 interrupt 0418 DD6F ; acknowledge interrupt 0419 DD6F ; 0420 DD6F ; and 0421 DD6F ; 0422 DD6F ; set speech RDY to interrupt again 0423 DD6F ; 0424 DD6F A9 20 LDAIM TIMER2 0425 DD71 A2 00 LDXIM ZERO 0426 DD73 ; N.B. minimise time between next two instructions 0427 DD73 8D 4D FE STA IFRQ ;clear interrupt 0428 DD76 8E 49 FE STX TRCHQ ;set to interrupt on speech chip INT 0429 DD79 ; 0430 DD79 ; process speech request 0431 DD79 ; 0432 DD79 PRSPRQ ;process speech request 0433 DD79 ; 0434 DD79 ; set speak external repeat counter to 4 0435 DD79 ; 0436 DD79 A2 08 LDXIM BSPCH 0437 DD7B 86 FB STX SPWK2 ;**** ASSUMES BSPCH=8 **** 0438 DD7D ; 0439 DD7D SPEREP ;repeat poke of speak external data 0440 DD7D ; 0441 DD7D ; inspect speech buffer 0442 DD7D ; 0443 DD7D 20 5B E4 JSR EXAM 0444 DD80 ; 0445 DD80 ; record buffer status - MI => dormant, PL => busy 0446 DD80 ; 0447 DD80 6E D7 02 ROR SPSTAT 0448 DD83 30 44 BMI NSPECH ;[buffer empty] 0449 DD85 ; 0450 DD85 A8 TAY 0451 DD86 F0 05 BEQ SPOK ;[speak external data] 0452 DD88 ; 0453 DD88 ; new command - ensure not talking 0454 DD88 ; 0455 DD88 20 6D EE JSR RSPECH 0456 DD8B 30 3C BMI NSPECH ;[talking active] 0457 DD8D ; 0458 DD8D ; new command and not talking 0459 DD8D ; 0460 DD8D SPOK ;speak external data 0461 DD8D ; 0462 DD8D ; get command byte from speech buffer 0463 DD8D ; 0464 DD8D 20 60 E4 JSR REMOV 0465 DD90 ; 0466 DD90 ; codeword in A Acorn macro assembler Page 66 IRQ processing 0467 DD90 ; 0468 DD90 85 F5 STA SEROM 0469 DD92 ; 0470 DD92 ; pull data 0471 DD92 ; 0472 DD92 20 60 E4 JSR REMOV 0473 DD95 85 F7 STA ROMPTR+&01 ;hi-address / hi-data 0474 DD97 20 60 E4 JSR REMOV 0475 DD9A 85 F6 STA ROMPTR+&00 ;lo-address / lo-data 0476 DD9C ; 0477 DD9C ; switch on codeword 0478 DD9C ; 0479 DD9C A4 F5 LDY SEROM 0480 DD9E F0 1B BEQ ISP2 ;[command=0, do not treat codeword as a command] 0481 DDA0 10 16 BPL ISP3 ;[command>0, speech command without address] 0482 DDA2 ; 0483 DDA2 ; command with address 0484 DDA2 ; command either speak(address) OR read-and-branch(address) 0485 DDA2 ; 0486 DDA2 ; check for read and branch request 0487 DDA2 ; 0488 DDA2 24 F5 BIT SEROM 0489 DDA4 70 05 BVS RAB ;[read and branch] 0490 DDA6 ; 0491 DDA6 ; speak(address) 0492 DDA6 ; load address into speech processor 0493 DDA6 ; 0494 DDA6 ; V=0 0495 DDA6 20 BB EE JSR SPLOAD ;N.B. does PHP...PLP 0496 DDA9 50 07 BVC ISPX ;[ALWAYS jump] 0497 DDAB ; 0498 DDAB RAB ;read and branch (speak indirect) 0499 DDAB ; 0500 DDAB ; multiply offset by two 0501 DDAB ; 0502 DDAB 06 F6 ASL ROMPTR+&00 0503 DDAD 26 F7 ROL ROMPTR+&01 0504 DDAF ; 0505 DDAF ; reselect address 0506 DDAF ; 0507 DDAF 20 3B EE JSR SPLIND ;load address indirect 0508 DDB2 ; 0509 DDB2 ISPX 0510 DDB2 AC 61 02 LDY SHUTSP ;command defaults to speech 0511 DDB5 4C 7F EE JMP WSPECH ;send command AND return 0512 DDB8 ; 0513 DDB8 ; 0514 DDB8 ISP3 ;treat codeword as a command 0515 DDB8 ; 0516 DDB8 20 7F EE JSR WSPECH ;issue codeword command 0517 DDBB ; 0518 DDBB ISP2 ;write argument data bytes 0519 DDBB ; 0520 DDBB A4 F6 LDY ROMPTR+&00 0521 DDBD 20 7F EE JSR WSPECH 0522 DDC0 A4 F7 LDY ROMPTR+&01 0523 DDC2 20 7F EE JSR WSPECH 0524 DDC5 ; 0525 DDC5 ; repeat poke of speak external data up to 4 times (8 bytes) 0526 DDC5 ; 0527 DDC5 46 FB LSR SPWK2 0528 DDC7 D0 B4 BNE SPEREP ;[try poking more speak external data] 0529 DDC9 ; 0530 DDC9 NSPECH 0531 DDC9 60 RTS 0532 DDCA 0533 DDCA 0534 DDCA 0535 DDCA ITIME1 ;check for TIMER1 interrupt 0536 DDCA ; 0537 DDCA 90 7B BCC IADC ;[not TIMER1, check for ADC interrupt] 0538 DDCC ; C=1 0539 DDCC ; 0540 DDCC ; main clock interrupt 0541 DDCC ; 0542 DDCC ; clear interrupt 0543 DDCC ; 0544 DDCC A9 40 LDAIM CLOCK 0545 DDCE 8D 4D FE STA IFRQ ;acknowledge clock interrupt 0546 DDD1 ; C=1 0547 DDD1 ; 0548 DDD1 ; increment absolute time 0549 DDD1 ; 0550 DDD1 AD 83 02 LDA TIMESW 0551 DDD4 AA TAX ;X -> current timer 0552 DDD5 49 0F EORIM &0F 0553 DDD7 48 PHA 0554 DDD8 A8 TAY ;Y -> other timer 0555 DDD9 ; C=1 0556 DDD9 ;****SEC ;N.B. add 1 to timer 0557 DDD9 ; 0558 DDD9 IT1 0559 DDD9 BD 91 02 LDAAX TIME -&01 0560 DDDC 69 00 ADCIM ZERO 0561 DDDE 99 91 02 STAAY TIME -&01 0562 DDE1 CA DEX 0563 DDE2 F0 03 BEQ IT2 0564 DDE4 88 DEY 0565 DDE5 D0 F2 BNE IT1 0566 DDE7 IT2 0567 DDE7 ; 0568 DDE7 68 PLA 0569 DDE8 8D 83 02 STA TIMESW ;switch timers 0570 DDEB ; 0571 DDEB ; 0572 DDEB A2 05 LDXIM &05 0573 DDED IVIAA5 0574 DDED FE 9B 02 INCAX STPW -&01 0575 DDF0 D0 08 BNE IINKEY 0576 DDF2 CA DEX 0577 DDF3 D0 F8 BNE IVIAA5 0578 DDF5 ; 0579 DDF5 ; stopwatch timeout 0580 DDF5 ; 0581 DDF5 A0 05 LDYIM EVSWCH 0582 DDF7 20 94 E4 JSR EVENT 0583 DDFA ; 0584 DDFA IINKEY ;decrement INKEY counter 0585 DDFA ; 0586 DDFA AD B1 02 LDA RDCTLO 0587 DDFD D0 08 BNE IIN1 ;[just decrement lo] Acorn macro assembler Page 67 IRQ processing 0588 DDFF ; lo zero 0589 DDFF AD B2 02 LDA RDCTHI 0590 DE02 F0 06 BEQ IIN0 ;[counter zero] 0591 DE04 ; decrement lo and hi 0592 DE04 CE B2 02 DEC RDCTHI 0593 DE07 IIN1 ;just decrement lo 0594 DE07 CE B1 02 DEC RDCTLO 0595 DE0A IIN0 ;counter zero 0596 DE0A 0597 DE0A [ $Tutu ; no sound, no speech shit wanted - nothing from this point on 0601 DE0A | 0602 DE0A ; 0603 DE0A ; 0604 DE0A ; check sound sema to ensure exclusive access to sound code 0605 DE0A ; 0606 DE0A 2C CE 02 BIT SSEMA 0607 DE0D ] 0608 DE0D 10 0B BPL SINUSE ;[sound software in use] 0609 DE0F ; 0610 DE0F ; sound software available 0611 DE0F ; 0612 DE0F EE CE 02 INC SSEMA ;claim sound sema 0613 DE12 58 CLI ;enable interrupts during sound processing 0614 DE13 20 47 EB JSR SNDIRQ 0615 DE16 78 SEI ;disable interrupts after sound processing 0616 DE17 CE CE 02 DEC SSEMA ;release sound sema 0617 DE1A SINUSE 0618 DE1A ; 0619 DE1A ; give speech a chance 0620 DE1A ; 0621 DE1A ; check buffer 0622 DE1A ; 0623 DE1A 2C D7 02 BIT SPSTAT 0624 DE1D 30 0C BMI SPBUSY ;[speech buffer empty] 0625 DE1F ; 0626 DE1F ; read speech chip status 0627 DE1F ; 0628 DE1F 20 6D EE JSR RSPECH ;N.B. does not alter A if speech chip not present 0629 DE22 ; 0630 DE22 ; A>=$80 => busy 0631 DE22 ; 0632 DE22 ; N.B. if speech chip does not exist then 25% chance that PRSPRQ will 0633 DE22 ; be called, this will just result in a no-operation effect 0634 DE22 ; 0635 DE22 49 A0 EORIM &A0 0636 DE24 C9 60 CMPIM &60 0637 DE26 90 03 BCC SPBUSY ;[100, 101 or 111] 0638 DE28 ; 0639 DE28 20 79 DD JSR PRSPRQ ;process speech request 0640 DE2B ; 0641 DE2B SPBUSY ;speech chip busy 0642 DE2B ; 0643 DE2B ; check RS423 for possible Tx 0644 DE2B ; 0645 DE2B 2C B7 D9 BIT FFBYT ;indicate timer interrupt call 0646 DE2E 20 A2 DC JSR IRQ68 0647 DE31 ; 0648 DE31 ; check keyboard if keys active 0649 DE31 ; 0650 DE31 A5 EC LDA CKEY 0651 DE33 05 ED ORA OKEY 0652 DE35 2D 42 02 AND KSEMA ;check for keyboard critical region 0653 DE38 F0 04 BEQ ICLK0 ;[no keys active, clear timer interrupt] 0654 DE3A 38 SEC 0655 DE3B 20 65 F0 JSR JMIKYV ;key(s) active, process timer interrupt 0656 DE3E ; ******** MAY ENABLE INTERRUPTS (EXITS DISABLED) ******** 0657 DE3E ; 0658 DE3E ICLK0 0659 DE3E ; give user print routine a chance 0660 DE3E 20 9B E1 JSR UPTINT 0661 DE41 ; 0662 DE41 ; the ADC is connected on CB1 0663 DE41 ; when port B is read (by keyboard routines) any 0664 DE41 ; interrupt is lost, and the ADC must be restarted 0665 DE41 ; 0666 DE41 2C C0 FE BIT ADCCTL 0667 DE44 70 04 BVS IADCB ;[ADC not busy] 0668 DE46 60 RTS ;return from interrupt 0669 DE47 0670 DE47 0671 DE47 IADC ;check for ADC interrupt 0672 DE47 ; 0673 DE47 2A ROLA ;A = IFR << 3, N = CB1 0674 DE48 10 28 BPL IKEYBD ;[not an ADC intterupt] 0675 DE4A ; 0676 DE4A ; ADC interrupt 0677 DE4A ; check ADC enabled 0678 DE4A ; 0679 DE4A IADCB 0680 DE4A AE 4C 02 LDX ADCHAN 0681 DE4D F0 1D BEQ IADC0 ;[ADC disabled] 0682 DE4F ; 0683 DE4F ; read conversion lo byte 0684 DE4F ; 0685 DE4F AD C2 FE LDA ADCLO 0686 DE52 9D B5 02 STAAX ADCLOV -&01 0687 DE55 ; 0688 DE55 ; read conversion hi byte 0689 DE55 ; 0690 DE55 AD C1 FE LDA ADCHI 0691 DE58 9D B9 02 STAAX ADCHIV -&01 0692 DE5B ; 0693 DE5B ; set latest conversion number 0694 DE5B ; 0695 DE5B 8E BE 02 STX ADCFLG 0696 DE5E ; 0697 DE5E ; signal ADC conversion event, X = channel number 0698 DE5E ; 0699 DE5E A0 03 LDYIM EVADC 0700 DE60 20 94 E4 JSR EVENT 0701 DE63 ; 0702 DE63 ; step to next channel 0703 DE63 ; 0704 DE63 CA DEX 0705 DE64 D0 03 BNE IADC2 ;[channel >= 1] 0706 DE66 ; 0707 DE66 ; channel counter underflow 0708 DE66 ; reload channel counter 0709 DE66 ; 0710 DE66 AE 4D 02 LDX MAXADC 0711 DE69 IADC2 Acorn macro assembler Page 68 IRQ processing 0712 DE69 ; 0713 DE69 ; initiate next conversion 0714 DE69 ; X = channel number 0715 DE69 ; 0716 DE69 20 8F DE JSR ADCBGX ;begin conversion, sets ADCHAN=X 0717 DE6C IADC0 0718 DE6C A9 10 LDAIM ADC 0719 DE6E IVIAA0 ;return from VIAA interrupt 0720 DE6E 8D 4D FE STA IFRQ ;clear interrupt state 0721 DE71 60 RTS ;return from interrupt 0722 DE72 0723 DE72 0724 DE72 IKEYBD ;keyboard interrupt check 0725 DE72 ; 0726 DE72 2A ROLA ;A = IFR << 4 0727 DE73 2A ROLA ;A = IFR << 5 0728 DE74 2A ROLA ;A = IFR << 6 0729 DE75 2A ROLA ;A = IFR << 7, N = CA2 0730 DE76 10 07 BPL JUNKIRQ ;[not keyboard interrupt] 0731 DE78 ; 0732 DE78 ; C=0 because no VSYNC 0733 DE78 ; 0734 DE78 20 65 F0 JSR JMIKYV ;find and set up new current key (enter with C=0) 0735 DE7B ; ******** MAY ENABLE INTERRUPTS (EXITS DISABLED) ******** 0736 DE7B A9 01 LDAIM KEYBD 0737 DE7D D0 EF BNE IVIAA0 ;[ALWAYS jump] 0738 DE7F ; 0739 DE7F 4C F3 DC JUNKIRQ JMP UNKIRQ ;IRQ not identified 0740 DE82 0741 DE82 0742 DE82 0743 DE82 IRQ0 ;return from interrupt restoring registers 0744 DE82 68 PLA 0745 DE83 A8 TAY 0746 DE84 68 PLA 0747 DE85 AA TAX 0748 DE86 68 PLA 0749 DE87 85 FC STA TEMPA 0750 DE89 ; 0751 DE89 IRQTWO 0752 DE89 A5 FC LDA TEMPA 0753 DE8B 40 RTI 0754 DE8C 0755 DE8C 0756 DE8C ADCBEG ;begin forced ADC conversion 0757 DE8C ; 0758 DE8C ; X = external channel number 0759 DE8C ; Y = 0 0760 DE8C ; 0761 DE8C 8C BE 02 STY ADCFLG ;clear conversion number 0762 DE8F ; 0763 DE8F ADCBGX ;begin ADC conversion 0764 DE8F ; 0765 DE8F ; X = external channel number 0766 DE8F ; Y corrupted 0767 DE8F ; 0768 DE8F E0 05 CPXIM NADC +&01 0769 DE91 90 02 BCC ADCBG1 ;[valid channel number] 0770 DE93 A2 04 LDXIM NADC ;force valid channel number 0771 DE95 ADCBG1 ;channel number now valid (but possibly 0) 0772 DE95 ; 0773 DE95 8E 4C 02 STX ADCHAN 0774 DE98 AC 4E 02 LDY ADCCNV ;normally 0, 8 or 12 (0 has same effect as 12) 0775 DE9B 88 DEY 0776 DE9C 98 TYA 0777 DE9D 29 08 ANDIM &08 ;extract conversion type 0778 DE9F 18 CLC 0779 DEA0 6D 4C 02 ADC ADCHAN 0780 DEA3 ; C=0 0781 DEA3 E9 00 SBCIM ZERO ;subtract 1, add in INTERNAL channel number (1->0 ... 4->3) 0782 DEA5 8D C0 FE STA ADCCTL ;start conversion 0783 DEA8 ; 0784 DEA8 ; if X was 0 on entry then a conversion is initiated on channel 3 0785 DEA8 ; of the opposite conversion type to that expected, but the result 0786 DEA8 ; of this conversion will be ignored 0787 DEA8 ; 0788 DEA8 60 RTS 0789 DEA9 0790 DEA9 0791 DEA9 WRSTR ;write string 0792 DEA9 ; 0793 DEA9 A9 C3 LDAIM /MSG 0794 DEAB WRSTRA 0795 DEAB 85 FE STA REPTR +&01 0796 DEAD A9 00 LDAIM ZERO 0797 DEAF 85 FD STA REPTR +&00 0798 DEB1 WRSTR1 0799 DEB1 C8 INY 0800 DEB2 B1 FD LDAIY REPTR 0801 DEB4 20 E3 FF JSR OSASCI ;write message character 0802 DEB7 AA TAX 0803 DEB8 D0 F7 BNE WRSTR1 ;[ALWAYS jump, step to next message character] 0804 DEBA ; terminator found 0805 DEBA 60 RTS 0806 DEBB 0807 DEBB 0808 DEBB LNK MOS38 0001 DEBB ; > MOS38 0002 DEBB TTL MOS38 CLI 0003 DEBB OPT MOS38 Acorn macro assembler Page 69 MOS38 CLI 0004 DEBB ;(c) 1981 ACORN 0005 DEBB ;BBC MOS 0006 DEBB ;Change record: 0007 DEBB ;004 29-Jul-81 MP Prototype version 0008 DEBB ;Author(s): 0009 DEBB ;PB Paul Bond 0010 DEBB ;MP Mike Prees 0011 DEBB 0012 DEBB 0013 DEBB ; RDCH 0014 DEBB INKEY 0015 DEBB 8E B1 02 STX RDCTLO ;set INKEY counter 0016 DEBE 8C B2 02 STY RDCTHI 0017 DEC1 A9 FF LDAIM &FF ;indicate INKEY operational 0018 DEC3 D0 02 BNE RDCH5 ;[ALWAYS JUMP] 0019 DEC5 RDCH ;default OSRDCH 0020 DEC5 A9 00 LDAIM ZERO ;indicate not INKEY 0021 DEC7 RDCH5 0022 DEC7 85 E6 STA RDCTEM 0023 DEC9 ; save X and Y 0024 DEC9 8A TXA 0025 DECA 48 PHA 0026 DECB 98 TYA 0027 DECC 48 PHA 0028 DECD ; check for exec file 0029 DECD AC 56 02 LDY EXECH 0030 DED0 F0 14 BEQ RDCHQ ;[no exec file] 0031 DED2 ; 0032 DED2 38 SEC 0033 DED3 66 EB ROR ESSEMA ;enter critical region 0034 DED5 20 D7 FF JSR OSBGET ;get a byte from exec file 0035 DED8 08 PHP 0036 DED9 46 EB LSR ESSEMA ;exit critical region 0037 DEDB 28 PLP 0038 DEDC 90 25 BCC RDCH3 ;[return character] 0039 DEDE ; 0040 DEDE ; end of exec file: close exec file 0041 DEDE ; Y = handle 0042 DEDE A9 00 LDAIM ZERO 0043 DEE0 8D 56 02 STA EXECH ;cancel exec file handle 0044 DEE3 20 CE FF JSR OSFIND ;close exec file 0045 DEE6 RDCHQ ;read character 0046 DEE6 24 FF BIT ESCFLG 0047 DEE8 30 16 BMI RDCH1 ;[ESCAPE detected] 0048 DEEA ; 0049 DEEA AE 41 02 LDX RDCHSW ;set to read ch from selected buffer 0050 DEED 20 77 E5 JSR RDCHG ;get ch from kybd input buffer 0051 DEF0 90 11 BCC RDCHN ;[character available] 0052 DEF2 ; 0053 DEF2 ; C=1 0054 DEF2 ; 0055 DEF2 24 E6 BIT RDCTEM 0056 DEF4 50 F0 BVC RDCHQ ;[INKEY not operational] 0057 DEF6 ; 0058 DEF6 AD B1 02 LDA RDCTLO 0059 DEF9 0D B2 02 ORA RDCTHI 0060 DEFC D0 E8 BNE RDCHQ ;[INKEY counter <> 0] 0061 DEFE ; 0062 DEFE ;INKEY count exhausted 0063 DEFE ; 0064 DEFE B0 05 BCS RDCH2 ;[ALWAYS jump, return A=$FF, C=1] 0065 DF00 ; 0066 DF00 RDCH1 ;ESCAPE detected 0067 DF00 38 SEC ;indicate escape detected 0068 DF01 A9 1B LDAIM ESC 0069 DF03 RDCHN ;C=0 => 'real' character 0070 DF03 RDCH3 ;C=1 => escape detected OR INKEY count expired 0071 DF03 85 E6 STA RDCTEM ;save character read 0072 DF05 RDCH2 ;entry point used when INKEY count exhausted (N.B. RDCTEM=$FF) 0073 DF05 68 PLA ;restore X and Y 0074 DF06 A8 TAY 0075 DF07 68 PLA 0076 DF08 AA TAX 0077 DF09 A5 E6 LDA RDCTEM ;A := character 0078 DF0B 60 RTS 0079 DF0C COPYR ;DO NOT MOVE (must precede COMTAB with bytes < $80) 0080 DF0C 29 = ")" 0081 DF0D 43 = "C" 0082 DF0E 28 = "(" 0083 DF0F 00 = ZERO 0084 DF10 ; command level interpreter 0085 DF10 COMTAB ;table of MOS commands 0086 DF10 ; this table uses the fact that all routine address hi-bytes 0087 DF10 ; will have the top bit set 0088 DF10 ; N.B. addresses are stored hi-byte followed by lo-byte 0089 DF10 ; hi-byte is assumed to be >=$80 0090 DF10 ; code following address is A reg on entry to address 0091 DF10 ; A+ => enter with XY -> line 0092 DF10 ; A- => enter with Y = offset 0093 DF10 ; . 0094 DF10 2E = "." 0095 DF11 E0 31 & /JMIFSC 0096 DF13 05 = FSCAT ;enter with XY -> line 0097 DF14 0098 DF14 ; FX 0099 DF14 46 58 = "FX" 0100 DF16 E3 42 & /FX 0101 DF18 FF = &FF ;enter with Y = offset 0102 DF19 0103 DF19 ; BASIC 0104 DF19 42 41 53 = "BASIC" 0105 DF1E E0 18 & /BASIC 0106 DF20 00 = NULL ;don't care 0107 DF21 0108 DF21 ; CAT 0109 DF21 43 41 54 = "CAT" 0110 DF24 E0 31 & /JMIFSC 0111 DF26 05 = FSCAT ;enter with XY -> line 0112 DF27 0113 DF27 ; CODE 0114 DF27 43 4F 44 = "CODE" 0115 DF2B E3 48 & /FXN 0116 DF2D 88 = FXCODE ;enter with Y = offset 0117 DF2E 0118 DF2E ; EXEC 0119 DF2E 45 58 45 = "EXEC" 0120 DF32 F6 8D & /EXEC 0121 DF34 0122 DF34 00 = ZERO ;enter with XY -> line 0123 DF35 0124 DF35 ; HELP Acorn macro assembler Page 70 MOS38 CLI 0125 DF35 48 45 4C = "HELP" 0126 DF39 F0 B9 & /HELP 0127 DF3B 0128 DF3B FF = &FF ;enter with Y = offset 0129 DF3C 0130 DF3C ; KEY 0131 DF3C 4B 45 59 = "KEY" 0132 DF3F E3 27 & /KEY 0133 DF41 0134 DF41 FF = &FF ;enter with Y = offset 0135 DF42 0136 DF42 ; LOAD 0137 DF42 4C 4F 41 = "LOAD" 0138 DF46 E2 3C & /LOAD 0139 DF48 0140 DF48 00 = &00 ;enter with XY -> line 0141 DF49 0142 DF49 ; LINE 0143 DF49 4C 49 4E = "LINE" 0144 DF4D E6 59 & /JMIUSR 0145 DF4F 01 = &01 ;enter with A=$01, XY -> line 0146 DF50 0147 DF50 ; MOTOR 0148 DF50 4D 4F 54 = "MOTOR" 0149 DF55 E3 48 & /FXN 0150 DF57 0151 DF57 89 = FXMOTR ;enter with Y = offset 0152 DF58 0153 DF58 ; OPT 0154 DF58 4F 50 54 = "OPT" 0155 DF5B E3 48 & /FXN 0156 DF5D 0157 DF5D 8B = FXOPT ;enter with Y = offset 0158 DF5E 0159 DF5E ; RUN 0160 DF5E 52 55 4E = "RUN" 0161 DF61 E0 31 & /JMIFSC 0162 DF63 0163 DF63 04 = FSRUN ;enter with XY -> line 0164 DF64 0165 DF64 ; ROM 0166 DF64 52 4F 4D = "ROM" 0167 DF67 E3 48 & /FXN 0168 DF69 0169 DF69 8D = FXSROM ;don't care 0170 DF6A 0171 DF6A ; SAVE 0172 DF6A 53 41 56 = "SAVE" 0173 DF6E E2 3E & /SAVE 0174 DF70 0175 DF70 00 = ZERO ;enter with XY -> line 0176 DF71 0177 DF71 ; SPOOL 0178 DF71 53 50 4F = "SPOOL" 0179 DF76 E2 81 & /SPOOL 0180 DF78 0181 DF78 00 = ZERO ;enter with XY -> line 0182 DF79 0183 DF79 ; TAPE 0184 DF79 54 41 50 = "TAPE" 0185 DF7D E3 48 & /FXN 0186 DF7F 0187 DF7F 8C = FXTAPE ;don't care 0188 DF80 0189 DF80 ; TV 0190 DF80 54 56 = "TV" 0191 DF82 E3 48 & /FXN 0192 DF84 0193 DF84 90 = FXTV ;enter with Y = offset 0194 DF85 0195 DF85 ; default if first character is not alpha, |, . or / 0196 DF85 E0 31 & /JMIFSC 0197 DF87 0198 DF87 03 = FSNAME ;enter with XY -> line 0199 DF88 00 = ZERO ;end of table 0200 DF89 0201 DF89 0202 DF89 CLINT 0203 DF89 86 F2 STX WORK +&00 0204 DF8B 84 F3 STY WORK +&01 0205 DF8D ; report *command to filing system 0206 DF8D A9 08 LDAIM FSCLI 0207 DF8F 20 31 E0 JSR JMIFSC 0208 DF92 ; check line is terminated by CR 0209 DF92 A0 00 LDYIM ZERO 0210 DF94 B1 F2 CLICHK LDAIY WORK 0211 DF96 C9 0D CMPIM MCR 0212 DF98 F0 04 BEQ CLILOK ;[terminator present] 0213 DF9A C8 INY 0214 DF9B D0 F7 BNE CLICHK 0215 DF9D ; no terminator within 256 bytes so ignore line 0216 DF9D 60 RTS 0217 DF9E ; 0218 DF9E A0 FF CLILOK LDYIM &FF ;start scan from beginning of input buffer 0219 DFA0 ; N.B. Y will now be incremented to ZERO by SKIPSN 0220 DFA0 CLIR ;skip leading spaces and asterisks 0221 DFA0 20 39 E0 JSR SKIPSN ;skip spaces/asterisk and spaces 0222 DFA3 F0 72 BEQ CLIRTS ;[reached end-of-line, ignore line] 0223 DFA5 C9 2A CMPIM SPLAT 0224 DFA7 F0 F7 BEQ CLIR ;[asterisk, ignore] 0225 DFA9 20 3A E0 JSR SKIPSP ;skip spaces 0226 DFAC F0 69 BEQ CLIRTS ;[reached end-of-line, ignore line] 0227 DFAE ; ignore comment line 0228 DFAE C9 7C CMPIM "|" 0229 DFB0 F0 65 BEQ CLIRTS ;[*| command] 0230 DFB2 ; check for override 0231 DFB2 C9 2F CMPIM "/" 0232 DFB4 D0 08 BNE NOTSL ;[not /] 0233 DFB6 ; */name 0234 DFB6 C8 INY ;skip past / 0235 DFB7 20 09 E0 JSR CLIXY ;make XY -> after / 0236 DFBA A9 02 LDAIM FSNOTA 0237 DFBC D0 73 BNE JMIFSC ;[ALWAYS JUMP] 0238 DFBE NOTSL 0239 DFBE ; save pointer to rest of line 0240 DFBE 84 E6 STY CLIRY 0241 DFC0 ; reached command name 0242 DFC0 ; look for name in table 0243 DFC0 A2 00 LDXIM ZERO ;set X to scan command table 0244 DFC2 F0 13 BEQ DOT ;[ALWAYS JUMP] 0245 DFC4 ; Acorn macro assembler Page 71 MOS38 CLI 0246 DFC4 ; this code should intercept all strange commands, 0247 DFC4 ; including NULs and top-bit-set characters 0248 DFC4 ; 0249 DFC4 CLISCN 0250 DFC4 5D 10 DF EORAX COMTAB ;compare 0251 DFC7 29 DF ANDIM &DF ;equate cases 0252 DFC9 D0 17 BNE CLINXC ;[mismatch, try next CLI command name] 0253 DFCB ; 0254 DFCB ; match so far, C=1 0255 DFCB ; 0256 DFCB C8 INY ;step to next user character 0257 DFCC 18 CLC ;force following BCS to fail first time thru 0258 DFCD CLISTP 0259 DFCD B0 25 BCS CLIMCH ;[forced match by .] 0260 DFCF E8 INX ;step to next/first CLI command character 0261 DFD0 B1 F2 LDAIY WORK ;get next user character 0262 DFD2 20 E3 E4 JSR CAPS 0263 DFD5 90 ED BCC CLISCN ;[alpha] 0264 DFD7 ; 0265 DFD7 ; user command name delimited by non-letter 0266 DFD7 ; 0267 DFD7 DOT 0268 DFD7 ; match on full name ? 0269 DFD7 BD 10 DF LDAAX COMTAB ;get next CLI command character 0270 DFDA 30 16 BMI CLIMFN ;[match on full name] 0271 DFDC ; 0272 DFDC ; not a match on full name, check for forced match 0273 DFDC ; 0274 DFDC B1 F2 LDAIY WORK ;get this user character 0275 DFDE C9 2E CMPIM "." ;force match ? 0276 DFE0 F0 04 BEQ CLINXS ;[forced match, search for terminator, C=1] 0277 DFE2 ; 0278 DFE2 ; not forced match, skip to next CLI command name 0279 DFE2 ; 0280 DFE2 CLINXC 0281 DFE2 18 CLC 0282 DFE3 A4 E6 LDY CLIRY ;restore Y (Y points to user command name) 0283 DFE5 ; 0284 DFE5 ; skip to next CLI command name 0285 DFE5 ; 0286 DFE5 88 DEY ;adjust for following INY 0287 DFE6 ; C=0 0288 DFE6 CLINXS ;C=1 0289 DFE6 C8 INY 0290 DFE7 E8 INX 0291 DFE8 CLISKP 0292 DFE8 E8 INX ;N.B. X points to character +2 after one to be compared 0293 DFE9 BD 0E DF LDAAX COMTAB -&02 0294 DFEC F0 33 BEQ CLIEND ;[no more CLI command names] 0295 DFEE 10 F8 BPL CLISKP ;[not reached address hi-byte] 0296 DFF0 30 DB BMI CLISTP ;[ALWAYS jump, compare next CLI command name] 0297 DFF2 ; NEVER fall thru 0298 DFF2 ; 0299 DFF2 CLIMFN ;full name match 0300 DFF2 ; adjust for following DEXs 0301 DFF2 E8 INX 0302 DFF3 E8 INX 0303 DFF4 CLIMCH ;match 0304 DFF4 CA DEX 0305 DFF5 CA DEX 0306 DFF6 ; found CLI command match 0307 DFF6 ; construct JMI hi-byte value to command processing code 0308 DFF6 48 PHA 0309 DFF7 ; construct JMI lo-byte value to command processing code 0310 DFF7 BD 11 DF LDAAX COMTAB +&01 0311 DFFA 48 PHA 0312 DFFB ; skip spaces after command name 0313 DFFB 20 3A E0 JSR SKIPSP 0314 DFFE 18 CLC ;C=0 used by FXN entry 0315 DFFF 08 PHP ;status used by EXEC and SPOOL 0316 E000 ; (optionally) make XY -> rest of line 0317 E000 20 04 E0 JSR CLIXYA 0318 E003 40 RTI ;enter command processing routine 0319 E004 0320 E004 0321 E004 CLIXYA ;conditionally make XY -> rest of line 0322 E004 BD 12 DF LDAAX COMTAB +&02 0323 E007 30 0E BMI CLIXY0 ;[keep Y = offset of rest of line from WORK] 0324 E009 CLIXY ;make XY -> rest of command line 0325 E009 98 TYA ;A = offset of rest of line 0326 E00A BC 12 DF LDYAX COMTAB +&02 ;Y := function code 0327 E00D CLIXY2 0328 E00D 18 CLC 0329 E00E 65 F2 ADC WORK ;N.B. C=1 => carry 0330 E010 AA TAX ;X = lo-byte of pointer to rest of line 0331 E011 98 TYA ;A = function code 0332 E012 A4 F3 LDY WORK +&01 0333 E014 90 01 BCC CLIXY1 ;[no carry] 0334 E016 ; carry 0335 E016 C8 INY 0336 E017 CLIXY1 ;N.B. Y = hi-byte of pointer to rest of line 0337 E017 CLIXY0 0338 E017 CLIRTS 0339 E017 SVACK ;command accepted by service ROM 0340 E017 60 RTS 0341 E018 0342 E018 0343 E018 BASIC ;select BASIC language ROM 0344 E018 AE 4B 02 LDX BROMID 0345 E01B 30 04 BMI NBASIC ;[no BASIC ROM] 0346 E01D 38 SEC ;used by tube 0347 E01E 4C E7 DB JMP SELANG ;enter BASIC ROM (N.B. C=1) 0348 E021 NBASIC ;BASIC ROM not present so offer to service ROMs 0349 E021 CLIEND ;entered here if command not recognised or does not exist 0350 E021 ; offer command to service ROMs 0351 E021 A4 E6 LDY CLIRY ;restore Y offset to point to command name 0352 E023 A2 04 LDXIM SVNAME 0353 E025 20 68 F1 JSR SVOP 0354 E028 F0 ED BEQ SVACK ;[accepted by service ROM] 0355 E02A ; command not accepted by a service ROM 0356 E02A ; so pass command to filing system 0357 E02A A5 E6 LDA CLIRY ;A = offset to command name 0358 E02C 20 0D E0 JSR CLIXY2 ;make XY -> rest of line 0359 E02F A9 03 LDAIM FSNAME 0360 E031 JMIFSC 0361 E031 0362 E031 6C 1E 02 JMI FSCVEC 0363 E034 ; 0364 E034 ; 0365 E034 OPT 0366 E034 0A ASLA ;lsb(A) := 0 Acorn macro assembler Page 72 MOS38 CLI 0367 E035 ;* LDAIM $00 0368 E035 EOF 0369 E035 29 01 ANDIM &01 ;$00 => OPT, $01 => EOF 0370 E037 10 F8 BPL JMIFSC ;[ALWAYS JUMP, present option to file system AND return] 0371 E039 0372 E039 0373 E039 ; ignore space characters 0374 E039 C8 SKIPSN INY ;skip current character 0375 E03A B1 F2 SKIPSP LDAIY WORK 0376 E03C C9 20 CMPIM SPACE 0377 E03E F0 F9 BEQ SKIPSN ;[character is space, ignore] 0378 E040 C9 0D SKPSP1 CMPIM MCR 0379 E042 ; Z=1 next character is CR 0380 E042 ; Z=0 next character is not CR 0381 E042 60 RTS 0382 E043 SKPCM ;C=0 => check for line end 0383 E043 ;C=1 => skip optional comma and check for line end 0384 E043 90 F5 BCC SKIPSP 0385 E045 SKPCOM 0386 E045 ; skip spaces and an optional comma 0387 E045 20 3A E0 JSR SKIPSP 0388 E048 C9 2C CMPIM "," 0389 E04A D0 F4 BNE SKPSP1 0390 E04C C8 INY ;N.B. force Z=0 (i.e. non-zero result) 0391 E04D 60 RTS 0392 E04E ; get decimal number 0393 E04E GETNUM 0394 E04E 20 3A E0 JSR SKIPSP ;skip leading spaces, A := delimiter 0395 E051 20 7D E0 JSR TSTNUM 0396 E054 90 37 BCC TSTNR ;[not a digit] 0397 E056 GN0 0398 E056 85 E6 STA NUMBER ;NUMBER := accumulated number so far 0399 E058 20 7C E0 JSR TSTNUX ;read digit skipping current character 0400 E05B 90 19 BCC GTNS ;[non-digit serves as terminator] 0401 E05D AA TAX ;save last digit read 0402 E05E A5 E6 LDA NUMBER 0403 E060 0A ASLA ;times 2 0404 E061 B0 2A BCS TSTNR ;[overflow] 0405 E063 0A ASLA ;times 4 0406 E064 B0 27 BCS TSTNR ;[overflow] 0407 E066 ; N.B. C=0 0408 E066 65 E6 ADC NUMBER ;times 5 0409 E068 B0 23 BCS TSTNR ;[overflow] 0410 E06A 0A ASLA ;times 10 0411 E06B B0 20 BCS TSTNR ;[overflow] 0412 E06D 85 E6 STA NUMBER ;NUMBER := NUMBER * 10 0413 E06F 8A TXA ;A := most recently read digit 0414 E070 ; N.B. C=0 0415 E070 65 E6 ADC NUMBER ;NUMBER := accumulated value 0416 E072 B0 19 BCS TSTNR ;[overflow] 0417 E074 90 E0 BCC GN0 ;[read next digit, if any] 0418 E076 GTNS 0419 E076 A6 E6 LDX NUMBER 0420 E078 C9 0D CMPIM MCR 0421 E07A 38 SEC 0422 E07B ; return with: 0423 E07B ; C=1 => valid number, Z=1/0 => delimiter is/is_not CR, number in X 0424 E07B 60 RTS 0425 E07C 0426 E07C ; check character is a digit 0427 E07C TSTNUX 0428 E07C C8 INY ;skip current character 0429 E07D TSTNUM 0430 E07D B1 F2 LDAIY WORK ;get next character 0431 E07F C9 3A CMPIM &3A ;N.B. $3A = '9' + 1 0432 E081 B0 0A BCS TSTNR ;[bad digit, > '9'] 0433 E083 C9 30 CMPIM "0" 0434 E085 90 06 BCC TSTNR ;[bad digit, < '0'] 0435 E087 29 0F ANDIM &0F ;convert to number (do not corrupt V) 0436 E089 ; N.B. C=1 0437 E089 60 RTS 0438 E08A 0439 E08A TSTNRX 0440 E08A 20 45 E0 JSR SKPCOM 0441 E08D TSTNR 0442 E08D 18 CLC 0443 E08E ; C=0 bad number, A = delimiting character 0444 E08E 60 RTS 0445 E08F 0446 E08F TSTHEX ;test for, and convert, hex digit 0447 E08F 20 7D E0 JSR TSTNUM 0448 E092 B0 0E BCS TSTH0 ;[is a number, therefore a valid hex digit] 0449 E094 29 DF ANDIM &DF ;force upper case 0450 E096 C9 47 CMPIM "G" 0451 E098 B0 F0 BCS TSTNRX ;[>'F' so fail] 0452 E09A C9 41 CMPIM "A" 0453 E09C 90 EC BCC TSTNRX ;[<'A' so fail] 0454 E09E 08 PHP ;save V 0455 E09F E9 37 SBCIM ALPHAA -&0A ;convert to hex 0456 E0A1 28 PLP ;restore V 0457 E0A2 ; C=1 0458 E0A2 TSTH0 ;C=1 0459 E0A2 C8 INY 0460 E0A3 60 RTS 0461 E0A4 0462 E0A4 0463 E0A4 WRCH ;system write character 0464 E0A4 48 PHA ;save character on stack 0465 E0A5 8A TXA ;save registers 0466 E0A6 48 PHA 0467 E0A7 98 TYA 0468 E0A8 48 PHA 0469 E0A9 BA TSX 0470 E0AA BD 03 01 LDAAX &0103 ;restore character 0471 E0AD 48 PHA 0472 E0AE ; A = character 0473 E0AE 0474 E0AE ; examine WRCH selection(s) 0475 E0AE ; 0476 E0AE 2C 60 02 BIT NETWRC 0477 E0B1 10 08 BPL WRCNTN ;[WRCH not to net] 0478 E0B3 ; WRCH to net 0479 E0B3 ; A = character 0480 E0B3 A8 TAY ;send character in Y 0481 E0B4 A9 04 LDAIM NTWRCH 0482 E0B6 20 7E E5 JSR JMINET ;WRCH thru net 0483 E0B9 B0 52 BCS WRCHNN ;[immediate return to caller] 0484 E0BB ; 0485 E0BB ; continue within WRCH 0486 E0BB ; 0487 E0BB WRCNTN Acorn macro assembler Page 73 MOS38 CLI 0488 E0BB 0489 E0BB 18 CLC ;in case VDU not selected 0490 E0BC A9 02 LDAIM WRVDU 0491 E0BE 2C 7C 02 BIT WRCHSW 0492 E0C1 D0 05 BNE WRCHNV ;[WRCH not to VDU] 0493 E0C3 ; WRCH to VDU 0494 E0C3 68 PLA 0495 E0C4 48 PHA ;A := character 0496 E0C5 20 C0 C4 JSR VDU 0497 E0C8 ; C=0 => VDU says do not print character 0498 E0C8 WRCHNV ;WRCH not to VDU 0499 E0C8 0500 E0C8 ; C=0 => VDU (if selected) says do not print character 0501 E0C8 ; check who controls printing 0502 E0C8 A9 08 LDAIM WRPRNT 0503 E0CA 2C 7C 02 BIT WRCHSW 0504 E0CD D0 02 BNE WRCHNC ;[printing not controlled by VDU] 0505 E0CF ; printing controlled by VDU 0506 E0CF 90 05 BCC WRCHNP ;[VDU says do not print character] 0507 E0D1 WRCHNC ;conditionally print character 0508 E0D1 68 PLA 0509 E0D2 48 PHA ;A := character 0510 E0D3 20 14 E1 JSR MPRINT ;conditionally print character 0511 E0D6 WRCHNP ;do not print character 0512 E0D6 0513 E0D6 ; check for output to RS423 0514 E0D6 ; 0515 E0D6 [ FALSE=0 0519 E0D6 | 0520 E0D6 AD 7C 02 LDA WRCHSW 0521 E0D9 6A RORA ;**************** ASSUME WRRS = 1 **************** 0522 E0DA 90 1B BCC WRCHNR ;[RS423 disabled] 0523 E0DC ] 0524 E0DC 0525 E0DC ; WRCH via RS423 0526 E0DC A4 EA LDY RSTUT 0527 E0DE 88 DEY 0528 E0DF 10 16 BPL WRCHNR ;[RS423 managed by CFS, ignore WRCH request] 0529 E0E1 68 PLA 0530 E0E2 48 PHA ;A := character 0531 E0E3 ; 0532 E0E3 08 PHP 0533 E0E4 78 SEI 0534 E0E5 A2 02 LDXIM BRSO 0535 E0E7 48 PHA 0536 E0E8 20 5B E4 JSR EXAM 0537 E0EB 90 03 BCC WRCNP1 ;[buffer not empty] 0538 E0ED ; RS423 output buffer empty 0539 E0ED 20 70 E1 JSR RSBUSY ;enable RS423 Tx interrupts 0540 E0F0 WRCNP1 0541 E0F0 68 PLA 0542 E0F1 A2 02 LDXIM BRSO 0543 E0F3 20 F8 E1 JSR WRITE ;insert character into RS423 output buffer, waiting if necessary 0544 E0F6 ; N.B. WRITE disables interrupts 0545 E0F6 ; character not inserted if ESCAPE detected 0546 E0F6 28 PLP 0547 E0F7 ; 0548 E0F7 WRCHNR ;not via RS423 0549 E0F7 0550 E0F7 ; check for spooling enabled 0551 E0F7 ; check whether spooling active 0552 E0F7 A9 10 LDAIM WRSPL 0553 E0F9 2C 7C 02 BIT WRCHSW 0554 E0FC D0 0F BNE WRCHNS ;[spooling disabled] 0555 E0FE ; spool character 0556 E0FE AC 57 02 LDY SPOOLH 0557 E101 F0 0A BEQ WRCHNS ;[spooling not active] 0558 E103 ; spooling active 0559 E103 ; write byte to spool file 0560 E103 68 PLA 0561 E104 48 PHA ;A := character 0562 E105 ; 0563 E105 38 SEC 0564 E106 66 EB ROR ESSEMA ;enter critical region 0565 E108 20 D4 FF JSR OSBPUT 0566 E10B 46 EB LSR ESSEMA ;exit critical region 0567 E10D WRCHNS ;no spooling 0568 E10D 0569 E10D WRCHNN 0570 E10D ; exit restoring registers 0571 E10D 68 PLA ;pull redundant byte 0572 E10E 68 PLA 0573 E10F A8 TAY 0574 E110 68 PLA 0575 E111 AA TAX 0576 E112 68 PLA ;restore character 0577 E113 60 RTS 0578 E114 0579 E114 MPRINT ;conditionally print character in A 0580 E114 ; N.B. character should never be NUL 0581 E114 ; decide whether to ignore character 0582 E114 2C 7C 02 BIT WRCHSW 0583 E117 70 20 BVS PRINT0 ;[only print thru VDU1] 0584 E119 CD 86 02 CMP PIGNOR 0585 E11C F0 1B BEQ PRINT0 ;[match on printer ignore character] 0586 E11E ; 0587 E11E ; 0588 E11E ; ====== 0589 E11E ; PRINT 0590 E11E ; ====== 0591 E11E ; 0592 E11E ; Print a character via VDU 1 0593 E11E ; 0594 E11E ; ENTRY:- A = Character 0595 E11E ; 0596 E11E ; EXIT:- A,X,Y corrupt 0597 E11E ; Flags preserved 0598 E11E ; 0599 E11E PRINT ;used by VDU (SOH), uses fact of exit with C=0 0600 E11E 08 PHP 0601 E11F 78 SEI 0602 E120 ; N.B. if print sink is 0 then character will 0603 E120 ; eventually be ignored by STROBE 0604 E120 ; 0605 E120 AA TAX ;save print character 0606 E121 ; 0607 E121 ; test whether printer enabled 0608 E121 ; 0609 E121 A9 04 LDAIM WRPREN 0610 E123 2C 7C 02 BIT WRCHSW 0611 E126 D0 10 BNE PRINT4 ;[printer disabled] Acorn macro assembler Page 74 MOS38 CLI 0612 E128 ; 0613 E128 8A TXA ;restore print character 0614 E129 A2 03 LDXIM BPRNT ;X := print bufferid 0615 E12B 20 F8 E1 JSR WRITE ;write character to buffer, waiting if necessary 0616 E12E B0 08 BCS PRINT3 ;[ESCAPE detected] 0617 E130 ; 0618 E130 ; test printer status; interrupts disabled 0619 E130 ; 0620 E130 2C D2 02 BIT PFLAG 0621 E133 10 03 BPL PRINT3 ;[printer busy] 0622 E135 ; 0623 E135 ; printer dormant 0624 E135 ; send the first character 0625 E135 ; 0626 E135 20 3A E1 JSR STROBE ;send character to selected printer 0627 E138 ; 0628 E138 PRINT3 ;printer busy 0629 E138 PRINT4 ;return enabling interrupts 0630 E138 28 PLP ;restore interrupt state, set C=0 (fact used by VDU) 0631 E139 ; 0632 E139 PRINT0 0633 E139 60 RTS 0634 E13A 0635 E13A 0636 E13A STROBE ;send character to selected printer 0637 E13A ; **************************************** 0638 E13A ; MUST BE ENTERED WITH INTERRUPTS DISABLED 0639 E13A ; ********************************** 0640 E13A ; determine print sink 0641 E13A AD 85 02 LDA PRNTSW 0642 E13D F0 6E BEQ PURGE ;[ignore print request] 0643 E13F ; print sink determined by PRNTSW 0644 E13F ; 0: infinite print sink 0645 E13F ; 1: centronics 0646 E13F ; 2: RS423 output 0647 E13F ; 3: user print routine 0648 E13F ; 4: net printer server 0649 E13F C9 01 CMPIM PCEN 0650 E141 D0 21 BNE STROB1 ;[not centronics] 0651 E143 ; centronics interface 0652 E143 ; this code must be executed with interrupts disabled 0653 E143 ; otherwise a CA1 interrupt coinciding with the STA PAR 0654 E143 ; would result in a spurious interrupt which would not 0655 E143 ; be recognised, resulting in a 'Bad IRQ' state 0656 E143 20 60 E4 JSR REMOV ;remove character from print buffer 0657 E146 6E D2 02 ROR PFLAG 0658 E149 30 45 BMI STROB0 ;[no more characters to print] 0659 E14B A0 82 LDYIM &82 0660 E14D 8C 6E FE STY IERR ;enable parallel port printer interrupt 0661 E150 ; write character 0662 E150 8D 61 FE STA PAR 0663 E153 ; pulse strobe line 0664 E153 AD 6C FE LDA PCRR 0665 E156 29 F1 ANDIM &F1 ;********** DO NOT CHANGE 0666 E158 09 0C ORAIM CA2LO ;********** DO NOT CHANGE 0667 E15A 8D 6C FE STA PCRR ;CA2 strobe lo (signal inverted by h/w) 0668 E15D 09 0E ORAIM CA2HI ;********** DO NOT CHANGE 0669 E15F 8D 6C FE STA PCRR ;CA2 strobe hi (signal inverted by h/w) 0670 E162 ; N.B. leave signal hi 0671 E162 D0 2C BNE STROB0 ;[ALWAYS jump, exit] 0672 E164 0673 E164 STROB1 ;not centronics 0674 E164 ; X = bufferid 0675 E164 C9 02 CMPIM PRS 0676 E166 D0 29 BNE STROB3 ;[not RS423] 0677 E168 ; printer is RS423 0678 E168 A4 EA LDY RSTUT 0679 E16A 88 DEY 0680 E16B 10 40 BPL STCRS ;[RS423 printer managed by CFS, ignore print request] 0681 E16D ; print to RS423 0682 E16D 4E D2 02 LSR PFLAG ;flag printer busy 0683 E170 ; 0684 E170 RSBUSY 0685 E170 4E 4F 02 LSR RSFLAG ;flag RS423 busy 0686 E173 ; 0687 E173 RSETX ;enable RS423 Tx interrupts 0688 E173 20 41 E7 JSR CNTRS 0689 E176 90 18 BCC RSOVF ;[RS423 input buffer overflow] 0690 E178 ; 0691 E178 A2 20 LDXIM RHITXE ;set RTS hi, Tx interrupt enabled 0692 E17A ; 0693 E17A RSED ;alter Tx control register to X 0694 E17A A0 9F LDYIM &9F ;field is b6-b5 0695 E17C ; 0696 E17C RS423 0697 E17C 08 PHP 0698 E17D 78 SEI 0699 E17E 98 TYA ;A := mask 0700 E17F ; ***************************************** 0701 E17F ; MUST BE EXECUTED WITH INTERRUPTS DISABLED 0702 E17F ; ***************************************** 0703 E17F ; A = mask (altered) 0704 E17F ; X = new value 0705 E17F 86 FA STX RSOP ;save new value of field 0706 E181 2D 50 02 AND RSCTFL ;copy status and clear field for new status 0707 E184 45 FA EOR RSOP ;add in new status 0708 E186 AE 50 02 LDX RSCTFL ;X := old value 0709 E189 STARSC ;used by MC6850 N.B. does PLP RTS 0710 E189 0711 E189 8D 50 02 STA RSCTFL ;update record of status 0712 E18C 8D 08 FE STA RSCTL ;update 6850 0713 E18F 28 PLP 0714 E190 RSOVF ;RS423 input buffer overflow 0715 E190 STROB0 0716 E190 60 RTS 0717 E191 0718 E191 STROB3 ;not RS423 0719 E191 0720 E191 18 CLC 0721 E192 0722 E192 ; C=0 0723 E192 ; user or net print 0724 E192 ; X=print_bufferid 0725 E192 ; character in printer buffer 0726 E192 A9 01 LDAIM UPWRCH 0727 E194 20 A2 E1 JSR mUPT ;call print routine (returns with carry meaningful) 0728 E197 PFREE ;indicate printer dormant (OSBYTE call used by UPT routine) 0729 E197 6E D2 02 ROR PFLAG ;set printer status according to user print routine 0730 E19A ; C=0 => printer busy 0731 E19A ; C=1 => printer free 0732 E19A ; (default user print routine is DEFUPT) Acorn macro assembler Page 75 MOS38 CLI 0733 E19A UPTRTS 0734 E19A 60 RTS 0735 E19B 0736 E19B 0737 E19B UPTINT ;timer interrupt 0738 E19B 2C D2 02 BIT PFLAG 0739 E19E 30 FA BMI UPTRTS ;[printer dormant] 0740 E1A0 ; 0741 E1A0 ; give a hand to polled printers 0742 E1A0 A9 00 LDAIM UPTIME 0743 E1A2 ; 0744 E1A2 MUPT ;call user print routine (also used by VDU software) 0745 E1A2 ; A = reason code ($02/$03) 0746 E1A2 A2 03 LDXIM BPRNT ;X := print buffer id 0747 E1A4 ; 0748 E1A4 UPTX ;entered by *FX5 0749 E1A4 AC 85 02 LDY PRNTSW ;Y := current print selection 0750 E1A7 20 7E E5 JSR JMINET ;call net print routine 0751 E1AA 6C 22 02 JMI UPTVEC ;call user print routine AND return 0752 E1AD 0753 E1AD 0754 E1AD STROB4 ;not user print 0755 E1AD STCRS ;RS423 managed by cassette 0756 E1AD ; ignore print request by purging buffer AND return 0757 E1AD PURGE 0758 E1AD ; purge buffer given by index in X 0759 E1AD ; this routine does not corrupt A or X 0760 E1AD 18 CLC 0761 E1AE ; 0762 E1AE PURGEX ;entered by OSWORD sound routine with C=1 0763 E1AE 48 PHA ;save A 0764 E1AF 08 PHP ;save interrupt state 0765 E1B0 78 SEI 0766 E1B1 ; 0767 E1B1 ; kill sound channel if sound buffer 0768 E1B1 B0 08 BCS PURNSB ;[OSWORD call so do not kill sound] 0769 E1B3 BD AD E9 LDAAX BUFTYP 0770 E1B6 10 03 BPL PURNSB ;[not a sound buffer] 0771 E1B8 ; kill sound on channel X 0772 E1B8 20 A2 EC JSR SCRST 0773 E1BB PURNSB 0774 E1BB ; 0775 E1BB ; flag buffer dormant 0776 E1BB 38 SEC 0777 E1BC 7E CF 02 RORAX BACTIV 0778 E1BF ; 0779 E1BF ; check for input buffer 0780 E1BF E0 02 CPXIM OUTPUT 0781 E1C1 B0 08 BCS PURGE3 ;[output buffer] 0782 E1C3 ; 0783 E1C3 ; input buffer, kill soft key expansion and VDU queueing 0784 E1C3 ; 0785 E1C3 A9 00 LDAIM ZERO 0786 E1C5 8D 68 02 STA SOFKL ;kill soft key expansion 0787 E1C8 8D 6A 02 STA QPOSN ;kill VDU queueing 0788 E1CB ; 0789 E1CB PURGE3 0790 E1CB ; 0791 E1CB 20 3B E7 JSR JMIPUR ;use indirection with V=1 (defaults to CNP) 0792 E1CE ; 0793 E1CE 28 PLP ;restore interrupt state 0794 E1CF 68 PLA ;restore A 0795 E1D0 60 RTS 0796 E1D1 ; 0797 E1D1 ; 0798 E1D1 CNP ;count buffer entries / purge buffer 0799 E1D1 [ $Tutu 0802 E1D1 | 0803 E1D1 50 07 BVC COUNT ;[count buffer entries] 0804 E1D3 ] 0805 E1D3 ; 0806 E1D3 ; purge buffer 0807 E1D3 ; 0808 E1D3 ; reset buffer pointers 0809 E1D3 ; set buffer start = buffer end 0810 E1D3 BD D8 02 LDAAX BFSTRT 0811 E1D6 9D E1 02 STAAX BFEND 0812 E1D9 60 RTS 0813 E1DA ; 0814 E1DA ; 0815 E1DA COUNT 0816 E1DA 08 PHP 0817 E1DB 78 SEI 0818 E1DC ; 0819 E1DC 08 PHP ;save count type 0820 E1DD ; 0821 E1DD 38 SEC 0822 E1DE BD E1 02 LDAAX BFEND 0823 E1E1 FD D8 02 SBCAX BFSTRT 0824 E1E4 B0 04 BCS BUFNX1 0825 E1E6 ; adjust for overflow 0826 E1E6 38 SEC 0827 E1E7 FD 47 E4 SBCAX BFORG 0828 E1EA BUFNX1 0829 E1EA ; 0830 E1EA 28 PLP ;restore count type 0831 E1EB ; 0832 E1EB 90 06 BCC BFCNT0 ;[input buffer] 0833 E1ED ; 0834 E1ED ; output buffer 0835 E1ED ; adjust to give remaining entries 0836 E1ED 18 CLC 0837 E1EE 7D 47 E4 ADCAX BFORG 0838 E1F1 49 FF EORIM &FF 0839 E1F3 ; 0840 E1F3 BFCNT0 0841 E1F3 A0 00 LDYIM ZERO 0842 E1F5 AA TAX 0843 E1F6 ; 0844 E1F6 28 PLP 0845 E1F7 60 RTS 0846 E1F8 0847 E1F8 0848 E1F8 LNK MOS40 0001 E1F8 0002 E1F8 ; MOS40 0003 E1F8 TTL MOS40 Machine operating system internal commands 0004 E1F8 OPT MOS40 Acorn macro assembler Page 76 MOS40 Machine operating system internal commands 0005 E1F8 ;(c) 1981 ACORN Computers Limited 0006 E1F8 ;BBC Microcomputer Machine Operating System (MOS) 0007 E1F8 ;Change record: 0008 E1F8 ;033 12-Aug-81 PB Reset SKNEND code, check KEY line termination 0009 E1F8 ;032 12-Aug-81 PB Extracted from CLI code 0010 E1F8 ;Author(s): 0011 E1F8 ;PB Paul Bond 0012 E1F8 ;MP Mike Prees 0013 E1F8 0014 E1F8 0015 E1F8 WRITE 0016 E1F8 WRITE1 0017 E1F8 78 SEI ;another critical region 0018 E1F9 20 B0 E4 JSR INSRT ;attempt to add character to print queue 0019 E1FC 90 0F BCC WRITE0 ;[character inserted into printer buffer] 0020 E1FE ; printer buffer full 0021 E1FE ; C=1 0022 E1FE 20 EA E9 JSR LEDSON ;conditionally set LEDs and test escape condition 0023 E201 ; N.B. does not corrupt C or X 0024 E201 ; C=1 0025 E201 ; reset LEDs 0026 E201 08 PHP 0027 E202 48 PHA 0028 E203 20 EB EE JSR KBDIS 0029 E206 68 PLA 0030 E207 28 PLP 0031 E208 ; 0032 E208 30 03 BMI WRITE0 ;[escape detected] 0033 E20A 58 CLI ;enable interrupts to allow printer buffer to purge. 0034 E20B ; Interrupts are enabled at this part of the loop, 0035 E20B ; rather than at the begining (which would save 2 bytes of code) 0036 E20B ; in order to ensure that if the print routine is called with 0037 E20B ; interrupts disabled, then interrupts are not enabled if there is 0038 E20B ; room in the print buffer. 0039 E20B B0 EB BCS WRITE1 ;[ALWAYS jump, wait for room in printer buffer, C=1] 0040 E20D WRITE0 0041 E20D 60 RTS 0042 E20E 0043 E20E 0044 E20E CLRFB ;clear file control block 0045 E20E 48 PHA 0046 E20F A9 00 LDAIM ZERO 0047 E211 9D EE 02 STAAX FBLOCK 0048 E214 9D EF 02 STAAX FBLOCK +&01 0049 E217 9D F0 02 STAAX FBLOCK +&02 0050 E21A 9D F1 02 STAAX FBLOCK +&03 0051 E21D 68 PLA 0052 E21E 60 RTS 0053 E21F ROL4 ;rotate hex digit into 4-byte address 0054 E21F 84 E6 STY FILEY 0055 E221 ; move nibble into high nibble 0056 E221 2A ROLA 0057 E222 2A ROLA 0058 E223 2A ROLA 0059 E224 2A ROLA 0060 E225 A0 04 LDYIM &04 0061 E227 ROL4A ;rotate bit into address 0062 E227 2A ROLA ;C=bit 0063 E228 3E EE 02 ROLAX FBLOCK 0064 E22B 3E EF 02 ROLAX FBLOCK +&01 0065 E22E 3E F0 02 ROLAX FBLOCK +&02 0066 E231 3E F1 02 ROLAX FBLOCK +&03 0067 E234 B0 31 BCS MBADHX ;[overflow] 0068 E236 ; C=0 0069 E236 88 DEY 0070 E237 D0 EE BNE ROL4A ;execute loop four times 0071 E239 ; C=0 0072 E239 A4 E6 LDY FILEY 0073 E23B ; C=0 0074 E23B 60 RTS 0075 E23C 0076 E23C 0077 E23C LOAD ;LOAD [load address] 0078 E23C A9 FF LDAIM &FF 0079 E23E SAVE ;(A=$00) SAVE [exechex] [loadhex] 0080 E23E 86 F2 STX WORK 0081 E240 84 F3 STY WORK +&01 0082 E242 8E EE 02 STX FBLOCK+FSTR+&0 0083 E245 8C EF 02 STY FBLOCK+FSTR+&1 0084 E248 48 PHA 0085 E249 ; clear load address 0086 E249 A2 02 LDXIM FLOAD 0087 E24B 20 0E E2 JSR CLRFB 0088 E24E ; set lsb exec address = $FF (preparing for possible LOAD) 0089 E24E A0 FF LDYIM &FF 0090 E250 8C F4 02 STY FBLOCK+FEXEC ;'use file load address' 0091 E253 ; set to read characters from WORK buffer 0092 E253 C8 INY ;Y:=0 0093 E254 ; skip filename 0094 E254 20 1D EA JSR GSINTC 0095 E257 20 2F EA LS2 JSR GSREAD 0096 E25A 90 FB BCC LS2 ;[string character] 0097 E25C ; determine command type 0098 E25C 68 PLA 0099 E25D 48 PHA 0100 E25E F0 62 BEQ SAVEX ;[SAVE command] 0101 E260 ; LOAD command 0102 E260 ; 0103 E260 ; read load address 0104 E260 ; N.B. X=FLOAD 0105 E260 20 AD E2 JSR LSA 0106 E263 B0 3B BCS LOADX1 ;hex present 0107 E265 F0 3E BEQ LS0 ;[just CR terminator] 0108 E267 MBADHX ;report error 'Bad address' 0109 E267 00 BRK 0110 E268 FC = BADADR 0111 E269 42 61 64 = "Bad address" 0112 E274 00 = ZERO ;message terminator 0113 E275 0114 E275 0115 E275 SHUTES ;shut EXEC and SPOOL files 0116 E275 0117 E275 ; 0118 E275 ; inform paged ROMs of intentions 0119 E275 ; 0120 E275 A2 10 LDXIM SVSHES 0121 E277 20 68 F1 JSR SVOP 0122 E27A F0 23 BEQ SPOOL0 ;[claimed, do not close files] 0123 E27C ; 0124 E27C ; deal with EXEC file 0125 E27C ; Acorn macro assembler Page 77 MOS40 Machine operating system internal commands 0126 E27C 20 8B F6 JSR ECLOSE ;Close EXEC file 0127 E27F ; 0128 E27F ; close SPOOL file AND return 0129 E27F ; 0130 E27F A9 00 LDAIM ZERO ;Z=1, A=$00 0131 E281 ; 0132 E281 SPOOL ;SPOOL 0133 E281 ; XY -> filename 0134 E281 ; A = $00 0135 E281 ; EQ -> spool off 0136 E281 ;remember whether to just turn spooling off 0137 E281 08 PHP 0138 E282 ; close old spool file 0139 E282 84 E6 STY SPOOLY ;save Y 0140 E284 AC 57 02 LDY SPOOLH 0141 E287 8D 57 02 STA SPOOLH ;clear spooling 0142 E28A F0 03 BEQ SPOOL2 ;[not currently spooling] 0143 E28C ; A=0 0144 E28C 20 CE FF JSR OSFIND ;close spool file 0145 E28F SPOOL2 0146 E28F A4 E6 LDY SPOOLY ;restore Y 0147 E291 28 PLP 0148 E292 F0 0B BEQ SPOOL0 ;[just close spool file] 0149 E294 ; open given spool file 0150 E294 A9 80 LDAIM &80 ;open file for output 0151 E296 20 CE FF JSR OSFIND 0152 E299 A8 TAY 0153 E29A F0 74 BEQ BADFX ;[open failure] 0154 E29C 8D 57 02 STA SPOOLH 0155 E29F SPOOL0 ;Z=1 0156 E29F 60 RTS 0157 E2A0 0158 E2A0 0159 E2A0 LOADX1 ;explicit load address given 0160 E2A0 D0 6E BNE BADFX ;[no CR terminator] 0161 E2A2 EE F4 02 INC FBLOCK+FEXEC ;use explicit load address 0162 E2A5 LS0 ;load file 0163 E2A5 A2 EE LDXIM FBLOCK 0164 E2A7 A0 02 LDYIM /(FBLOCK ) 0165 E2A9 68 PLA 0166 E2AA 4C DD FF JMP OSFILE 0167 E2AD ; 0168 E2AD 20 3A E0 LSA JSR SKIPSP 0169 E2B0 20 8F E0 JSR TSTHEX 0170 E2B3 90 0C BCC LSA0 ;[hex not present, return V=1] 0171 E2B5 ; 0172 E2B5 ; clear field 0173 E2B5 ; 0174 E2B5 20 0E E2 JSR CLRFB 0175 E2B8 ; 0176 E2B8 ; read address 0177 E2B8 ; 0178 E2B8 20 1F E2 LSA1 JSR ROL4 0179 E2BB 20 8F E0 JSR TSTHEX 0180 E2BE B0 F8 BCS LSA1 0181 E2C0 38 SEC ;return C=1 0182 E2C1 LSA0 ;Z=1 => CR terminator 0183 E2C1 60 RTS 0184 E2C2 ; 0185 E2C2 ; 0186 E2C2 SAVEX ;SAVE command 0187 E2C2 ; 0188 E2C2 ; read FROM address 0189 E2C2 ; 0190 E2C2 A2 0A LDXIM FFROM 0191 E2C4 20 AD E2 JSR LSA 0192 E2C7 90 47 BCC BADFX 0193 E2C9 ; 0194 E2C9 ; read TO address 0195 E2C9 ; check if preceeded by '+' 0196 E2C9 ; 0197 E2C9 B8 CLV 0198 E2CA B1 F2 LDAIY WORK 0199 E2CC C9 2B CMPIM "+" 0200 E2CE D0 04 BNE SAVEX3 ;['+' not present] 0201 E2D0 2C B7 D9 BIT FFBYT ;V=1 0202 E2D3 C8 INY ;skip '+' symbol 0203 E2D4 SAVEX3 0204 E2D4 A2 0E LDXIM FTO 0205 E2D6 20 AD E2 JSR LSA ;N.B. does not corrupt V 0206 E2D9 90 35 BCC BADFX ;[to address not given] 0207 E2DB ; C=1 0208 E2DB 08 PHP ;Z => no exec address 0209 E2DC ; if '+' was specified then the TO address was really 0210 E2DC ; a length specification 0211 E2DC 50 0F BVC SAVEX4 ;['+' not specified] 0212 E2DE ; convert length to end address 0213 E2DE ; N.B. C=1 0214 E2DE 00FC MINUS4 * &00FC 0215 E2DE A2 FC LDXIM MINUS4 0216 E2E0 18 CLC 0217 E2E1 SAVEX5 0218 E2E1 BD FC 01 LDAAX FBLOCK+FFROM-MINUS4 0219 E2E4 7D 00 02 ADCAX FBLOCK+FTO-MINUS4 0220 E2E7 9D 00 02 STAAX FBLOCK+FTO-MINUS4 0221 E2EA E8 INX 0222 E2EB D0 F4 BNE SAVEX5 ;[execute loop four times] 0223 E2ED SAVEX4 ;copy 'from' address to execute and load fields 0224 E2ED A2 03 LDXIM &03 0225 E2EF SAVEX1 0226 E2EF BD F8 02 LDAAX FBLOCK+FFROM 0227 E2F2 9D F4 02 STAAX FBLOCK+FEXEC 0228 E2F5 9D F0 02 STAAX FBLOCK+FLOAD 0229 E2F8 CA DEX 0230 E2F9 10 F4 BPL SAVEX1 0231 E2FB ; check if exec address present 0232 E2FB 28 PLP 0233 E2FC F0 A7 BEQ LS0 ;[no exec address] 0234 E2FE ; read exec address 0235 E2FE A2 06 LDXIM FEXEC 0236 E300 20 AD E2 JSR LSA 0237 E303 90 0B BCC BADFX ;[expected exec address not found] 0238 E305 F0 9E BEQ LS0 ;[no following load address] 0239 E307 ; read load address 0240 E307 A2 02 LDXIM FLOAD 0241 E309 20 AD E2 JSR LSA 0242 E30C 90 02 BCC BADFX ;[expected load address not found] 0243 E30E F0 95 BEQ LS0 ;[good line termination] 0244 E310 BADFX 0245 E310 MBDCMD 0246 E310 00 BRK ;report error 'Bad command' Acorn macro assembler Page 78 MOS40 Machine operating system internal commands 0247 E311 FE = BADCMD 0248 E312 42 61 64 = "Bad command" 0249 E31D 00 BADKEY BRK ;report error 'Bad KEY' / end of preceeding error message 0250 E31E FB = BADKY 0251 E31F 42 61 64 = "Bad key" 0252 E326 00 = ZERO ;message terminator 0253 E327 0254 E327 0255 E327 KEY ;KEY 0256 E327 20 4E E0 JSR GETNUM 0257 E32A 90 F1 BCC BADKEY ;[bad soft key number (>255)] 0258 E32C ; A = character delimiting number 0259 E32C ; X = NUMBER = CSKEY = key number 0260 E32C ; Y = soft key number argument 0261 E32C ; check soft key number range 0262 E32C E0 10 CPXIM NSOFTK 0263 E32E B0 ED BCS BADKEY ;[soft_key_number > number of soft keys - 1] 0264 E330 ; key number in range 0 to NSOFTK-1 0265 E330 ; 0266 E330 [ FALSE=0 0269 E330 ] 0270 E330 ; 0271 E330 20 45 E0 JSR SKPCOM ;skip optional spaces and an optional comma 0272 E333 08 PHP ;save line end status 0273 E334 AE 10 0B LDX SKEND ;Y points to unused portion of soft key buffer area 0274 E337 ; (set to reset SKNEND as it might have been set as a result 0275 E337 ; of a 'KEY in use' error) 0276 E337 98 TYA 0277 E338 48 PHA 0278 E339 20 D1 E3 JSR SKGCR ;delete soft key (uses value in X) 0279 E33C ; on exit X = SKEND 0280 E33C 68 PLA 0281 E33D A8 TAY 0282 E33E 28 PLP ;restore line end status 0283 E33F D0 36 BNE CLI1 ;[not end of line] 0284 E341 ; end of line - specified soft key value value has been deleted so return 0285 E341 60 RTS 0286 E342 0287 E342 0288 E342 0289 E342 FX ;*FX x,y 0290 E342 20 4E E0 JSR GETNUM ;read FX function code 0291 E345 90 C9 BCC BADFX ;[bad FX number] 0292 E347 ; 0293 E347 ; N.B. C=1 0294 E347 ; push function code 0295 E347 ; 0296 E347 8A TXA 0297 E348 FXN ;entry point used by CLI, C=0 0298 E348 48 PHA 0299 E349 A9 00 LDAIM ZERO ;set default argument values 0300 E34B 85 E5 STA FXREGX 0301 E34D 85 E4 STA FXREGY 0302 E34F ; 0303 E34F ; check for line end 0304 E34F ; 0305 E34F 20 43 E0 JSR SKPCM ;N.B. C=0 => just check for line end 0306 E352 ; 0307 E352 ; C=1 => skip an optional comma and check for line end 0308 E352 ; 0309 E352 F0 18 BEQ FX1 ;[line end, just a function code] 0310 E354 ; 0311 E354 ; try reading another argument 0312 E354 ; 0313 E354 20 4E E0 JSR GETNUM 0314 E357 90 B7 BCC BADFX ;[bad FX number] 0315 E359 ; 0316 E359 ; N.B. C=1 0317 E359 ; 0318 E359 86 E5 STX FXREGX 0319 E35B ; 0320 E35B ; check for line end 0321 E35B ; 0322 E35B 20 45 E0 JSR SKPCOM 0323 E35E F0 0C BEQ FX1 0324 E360 ; 0325 E360 ; try reading another argument 0326 E360 ; 0327 E360 20 4E E0 JSR GETNUM 0328 E363 90 AB BCC BADFX ;[bad FX number] 0329 E365 86 E4 STX FXREGY 0330 E367 ; 0331 E367 ; ensure line end 0332 E367 ; 0333 E367 20 3A E0 JSR SKIPSP 0334 E36A D0 A4 BNE BADFX ;[bad command termination] 0335 E36C ; 0336 E36C FX1 0337 E36C A4 E4 LDY FXREGY ;load OSBYTE arguments 0338 E36E A6 E5 LDX FXREGX 0339 E370 68 PLA 0340 E371 20 F4 FF JSR OSBYTE 0341 E374 70 9A BVS BADFX ;[unrecognised FX code] 0342 E376 60 RTS 0343 E377 0344 E377 0345 E377 CLI1 0346 E377 38 SEC 0347 E378 20 1E EA JSR GSINTS ;initialise for reading quoted string 0348 E37B CLIWP 0349 E37B 20 2F EA JSR GSREAD ;read string character 0350 E37E B0 08 BCS CLIY ;end of string 0351 E380 E8 INX 0352 E381 F0 9A BEQ BADKEY ;[buffer full, (N.B. buffer assumed to be 256 bytes long)] 0353 E383 ; buffer not full 0354 E383 9D 00 0B STAAX SKBUF -&01 ;store character in soft key buffer 0355 E386 ;(N.B. note offset of -1) 0356 E386 90 F3 BCC CLIWP ;[ALWAYS jump, go process next character] 0357 E388 ; SOFT KEY FINAL CHECK TO SEE IF ANY OTHER KEY SHARES SAME 0358 E388 ; VALUE POINTER - IF IT DOES THEN SET IT EQUAL TO SKEND 0359 E388 CLIY 0360 E388 D0 93 BNE BADKEY ;[string not terminated by CR] 0361 E38A ; N.B. new buffer end in X 0362 E38A 08 PHP 0363 E38B 78 SEI ;** DISABLE INTERRUPTS ** 0364 E38C 20 D1 E3 JSR SKGCR ;delete old soft key and replace with new value (uses value in X) 0365 E38F ;N.B. sets Y to specified soft key number 0366 E38F A2 10 LDXIM NSOFTK ;X to be roving soft key number 0367 E391 CLIYP 0368 E391 E4 E6 CPX CSKEY 0369 E393 F0 0E BEQ CLIYQ ;[do not process specified soft key] Acorn macro assembler Page 79 MOS40 Machine operating system internal commands 0370 E395 BD 00 0B LDAAX SKPTR 0371 E398 D9 00 0B CMPAY SKPTR ;compare soft key buffer pointers 0372 E39B D0 06 BNE CLIYQ ;[pointers differ] 0373 E39D AD 10 0B LDA SKEND 0374 E3A0 9D 00 0B STAAX SKPTR ;update soft key buffer pointer 0375 E3A3 CLIYQ 0376 E3A3 CA DEX 0377 E3A4 10 EB BPL CLIYP ;[go process next soft key] 0378 E3A6 28 PLP ;** ENABLE INTERRUPTS ** 0379 E3A7 60 RTS 0380 E3A8 0381 E3A8 0382 E3A8 SKSIZE ;A := size of soft key given by Y 0383 E3A8 ; ** THIS MODULE DISABLES INTERRUPTS ** 0384 E3A8 ; this routine is called by soft key set (via *KEY command) 0385 E3A8 ; and soft key read (via RDCH processing). 0386 E3A8 ; the choice is to duplicate the code, using a distinct work slot, 0387 E3A8 ; or share the code within a critical region in order that SKSZWK 0388 E3A8 ; may be shared 0389 E3A8 08 PHP ;save interrupt state 0390 E3A9 78 SEI ;** DISABLE INTERRUPTS ** 0391 E3AA AD 10 0B LDA SKEND 0392 E3AD 38 SEC 0393 E3AE F9 00 0B SBCAY SKPTR 0394 E3B1 85 FB STA SKSZWK ;SKSZWK := number of bytes to end of buffer 0395 E3B3 8A TXA 0396 E3B4 48 PHA ;push X 0397 E3B5 A2 10 LDXIM NSOFTK ;X is roving soft key number 0398 E3B7 SKS1 0399 E3B7 BD 00 0B LDAAX SKPTR 0400 E3BA 38 SEC 0401 E3BB F9 00 0B SBCAY SKPTR ;A := length of soft key w.r.t. specified soft key 0402 E3BE 90 08 BCC SKS2 ;[ignore negative length] 0403 E3C0 F0 06 BEQ SKS2 ;[ignore zero length] 0404 E3C2 C5 FB CMP SKSZWK 0405 E3C4 B0 02 BCS SKS2 ;[this length >= past lengths] 0406 E3C6 85 FB STA SKSZWK ;remember new minimum length 0407 E3C8 CA SKS2 DEX 0408 E3C9 10 EC BPL SKS1 ;[go process next soft key] 0409 E3CB 68 PLA 0410 E3CC AA TAX ;restore X 0411 E3CD A5 FB LDA SKSZWK 0412 E3CF 28 PLP ;** RESTORE INTERRUPT STATE ** 0413 E3D0 ; A := length of soft key string 0414 E3D0 ; Y := soft key number given on entry 0415 E3D0 60 RTS 0416 E3D1 0417 E3D1 0418 E3D1 ; SOFT KEY BUFFER GARBAGE COLLECTION ROUTINE.STRING 0419 E3D1 ; FOR KEY NUMBER GIVEN IN 'CSKEY' IS DELETED & ALL 0420 E3D1 ; POINTERS ADJUSTED ACC 0421 E3D1 SKGCR ;delete (and insert) key value(s) 0422 E3D1 ;** THIS MODULE DISABLES INTERRUPTS ** 0423 E3D1 08 PHP ;** SAVE INTERRUPT STATE OF CALLER ** 0424 E3D2 78 SEI ;** DISABLE INTERRUPTS ** 0425 E3D3 ; save new end address 0426 E3D3 8A TXA 0427 E3D4 48 PHA 0428 E3D5 A4 E6 LDY CSKEY ;Y is specified soft key number 0429 E3D7 20 A8 E3 JSR SKSIZE ;A := length of soft key string 0430 E3DA ; NOW SKSZWK = LENGTH OF CURRENT SK STRING 0431 E3DA ; SO SETUP FOR DELETING THIS STRING. 0432 E3DA B9 00 0B LDAAY SKPTR 0433 E3DD A8 TAY ;Y points to specified soft key string 0434 E3DE 18 CLC 0435 E3DF 65 FB ADC SKSZWK 0436 E3E1 AA TAX ;X points to start of byte area to be moved down 0437 E3E2 85 FA STA KEYSV 0438 E3E4 ; TO AVOID MASHING POINTER STRUCTURE IF 0439 E3E4 ; MACHINE CRASHES ELSEWHERE,IT IS ESSENTIAL 0440 E3E4 ; THAT INTERRUPTS ARE *OFF* FOR THIS NEXT BIT 0441 E3E4 ; before altering the data structure, check that a soft key 0442 E3E4 ; is not being used by RDCH 0443 E3E4 AD 68 02 LDA SOFKL ;A := length of soft key in use by RDCH 0444 E3E7 F0 0D BEQ SK3 ;[no soft key in use] 0445 E3E9 ; soft key being 'unwound' by RDCH 0446 E3E9 ; N.B. altering the data structure would confuse RDCH 0447 E3E9 00 BRK ;report error 'KEY in use' 0448 E3EA FA = KEYUSE 0449 E3EB 4B 65 79 = "Key in use" 0450 E3F5 00 = ZERO ;end of error message 0451 E3F6 0452 E3F6 SK3 0453 E3F6 CE 84 02 DEC USKFLG ;indicate update of soft keys in progress (USKFLG<>0) 0454 E3F9 68 PLA ;A := new end of buffer 0455 E3FA 38 SEC 0456 E3FB E5 FA SBC KEYSV 0457 E3FD 85 FA STA KEYSV ;KEYSV := number of bytes to copy 0458 E3FF F0 0C BEQ SKGCV ;[zero bytes to copy] 0459 E401 SKGCS 0460 E401 BD 01 0B LDAAX SKBUF ;*MOVE 0461 E404 99 01 0B STAAY SKBUF ;*CHARACTERS 0462 E407 C8 INY 0463 E408 E8 INX 0464 E409 C6 FA DEC KEYSV 0465 E40B D0 F4 BNE SKGCS ;[more bytes to copy] 0466 E40D ; NOW ADJUST ALL POINTERS WHICH ARE GREATER 0467 E40D ; THAN THE ONE AT CSKEY. 0468 E40D SKGCV 0469 E40D ; save new end address 0470 E40D 98 TYA 0471 E40E 48 PHA 0472 E40F A4 E6 LDY CSKEY ;Y is specified soft key number 0473 E411 A2 10 LDXIM NSOFTK ;X is roving soft key number, including end pointer 0474 E413 SKGCT 0475 E413 BD 00 0B LDAAX SKPTR 0476 E416 D9 00 0B CMPAY SKPTR 0477 E419 90 07 BCC SKGCU ;[current pointer precedes specified pointer] 0478 E41B [ TRUE=0 0479 E41B F0 05 BEQ SKGCU ;[current pointer equals specified pointer] 0480 E41D ] 0481 E41D ; current pointer is beyond specified pointer 0482 E41D ; if pointers are equal then specified soft key was null ... 0483 E41D ; ... therefore its size was zero and a drop thru is a no-operation 0484 E41D ; C=1 0485 E41D E5 FB SBC SKSZWK ;C already 1 0486 E41F 9D 00 0B STAAX SKPTR ;adjust current buffer pointer 0487 E422 SKGCU 0488 E422 CA DEX 0489 E423 10 EE BPL SKGCT ;[go process next soft key] 0490 E425 ; NOW UPDATE CURRENT KEY POINTER Acorn macro assembler Page 80 MOS40 Machine operating system internal commands 0491 E425 AD 10 0B LDA SKEND 0492 E428 99 00 0B STAAY SKPTR ;adjust specified soft key pointer to point to end of buffer 0493 E42B 68 PLA ;A := new end address 0494 E42C 8D 10 0B STA SKEND ;make end buffer pointers equal 0495 E42F AA TAX ;X := new end of buffer pointer 0496 E430 EE 84 02 INC USKFLG ;indicate update of soft keys over (USKFLG=0) 0497 E433 28 PLP ;** RESTORE INTERRUPT STATE OF CALLER ** 0498 E434 ; X = SKEND 0499 E434 ; Y = specified soft key number 0500 E434 60 RTS 0501 E435 LNK MOS42 0001 E435 0002 E435 ; > MOS42 0003 E435 TTL MOS42 Buffer management 0004 E435 OPT MOS42 Acorn macro assembler Page 81 MOS42 Buffer management 0005 E435 ;(c) 1981 ACORN Computers Limited 0006 E435 ;BBC Microcomputer Machine Operating System (MOS) 0007 E435 ;Change record: 0008 E435 ;201 01-May-82 PB EVENT restores A 0009 E435 ;004 29-Jul-81 MP Prototype version 0010 E435 ;Author(s): 0011 E435 ;PB Paul Bond 0012 E435 ;MP Mike Prees 0013 E435 ; buffer address table (hi byte) 0014 E435 BFADHI 0015 E435 03 = /(RDCHBF+RDCHSZ-&0100 ) 0016 E436 0A = /(RSRIBF+RSRISZ-&0100 ) 0017 E437 08 = /(RSROBF+RSROSZ-&0100 ) 0018 E438 07 = /(PRNBF+PRNSZ-&0100 ) 0019 E439 07 = /(SNDBF1+SBSIZE-&0100 ) 0020 E43A 07 = /(SNDBF2+SBSIZE-&0100 ) 0021 E43B 07 = /(SNDBF3+SBSIZE-&0100 ) 0022 E43C 07 = /(SNDBF4+SBSIZE-&0100 ) 0023 E43D 09 = /(SPCHBF+SPCHSZ-&0100 ) 0024 E43E ; buffer address table (lo byte) 0025 E43E BFADLO 0026 E43E 00 = RDCHBF+RDCHSZ-&0100 ;RDCH (keyboard) buffer 0027 E43F 00 = RSRIBF+RSRISZ-&0100 ;RS423 input 0028 E440 C0 = RSROBF+RSROSZ-&0100 ;RS423 output 0029 E441 C0 = PRNBF+PRNSZ-&0100 ;print 0030 E442 50 = SNDBF1+SBSIZE-&0100 ;sound channel 1 0031 E443 60 = SNDBF2+SBSIZE-&0100 ;sound channel 2 0032 E444 70 = SNDBF3+SBSIZE-&0100 ;sound channel 3 0033 E445 80 = SNDBF4+SBSIZE-&0100 ;sound channel 4 0034 E446 00 = SPCHBF+SPCHSZ-&0100 ;speech 0035 E447 ; buffer origin offsets within page 0036 E447 BFORG 0037 E447 E0 = &0100-RDCHSZ 0038 E448 00 = &0100-RSRISZ 0039 E449 40 = &0100-RSROSZ 0040 E44A C0 = &0100-PRNSZ 0041 E44B F0 = &0100-SBSIZE 0042 E44C F0 = &0100-SBSIZE 0043 E44D F0 = &0100-SBSIZE 0044 E44E F0 = &0100-SBSIZE 0045 E44F C0 = &0100-SPCHSZ 0046 E450 ; general buffer manipulation routines 0047 E450 SETBUF 0048 E450 ; set buffer pointer 0049 E450 BD 3E E4 LDAAX BFADLO 0050 E453 85 FA STA BUFFLO 0051 E455 BD 35 E4 LDAAX BFADHI 0052 E458 85 FB STA BUFFHI 0053 E45A 60 RTS 0054 E45B 0055 E45B 0056 E45B EXAM ;examine character in buffer 0057 E45B 2C B7 D9 BIT FFBYT ;V=1 => examine option 0058 E45E 70 01 BVS EXAM1 ;[ALWAYS jump] 0059 E460 ; NEVER fall thru 0060 E460 REMOV ;remove character from buffer 0061 E460 B8 CLV ;V=0 => indicate remove option 0062 E461 ; X = buffer index 0063 E461 ; V=0 => remove, V=1 => examine 0064 E461 EXAM1 ;entered with V=1 0065 E461 ; 0066 E461 6C 2C 02 JMI REMVEC ;use indirection (defaults to REM) 0067 E464 ; 0068 E464 REM 0069 E464 [ $Tutu 0072 E464 | 0073 E464 ; disable interrupts 0074 E464 08 PHP 0075 E465 78 SEI 0076 E466 ] 0077 E466 ; get buffer start pointer 0078 E466 BD D8 02 LDAAX BFSTRT 0079 E469 DD E1 02 CMPAX BFEND 0080 E46C F0 72 BEQ REMOV1 0081 E46E A8 TAY ;Y := buffer start pointer 0082 E46F ; set buffer pointer 0083 E46F 20 50 E4 JSR SETBUF 0084 E472 ; remove character from buffer 0085 E472 B1 FA LDAIY BUFFLO 0086 E474 70 1B BVS REMOV3 ;[examine option, exit with character] 0087 E476 48 PHA ;push character 0088 E477 ; update buffer start pointer 0089 E477 C8 INY 0090 E478 98 TYA 0091 E479 D0 03 BNE REMOV2 0092 E47B ; wraparound 0093 E47B BD 47 E4 LDAAX BFORG 0094 E47E REMOV2 0095 E47E 9D D8 02 STAAX BFSTRT 0096 E481 ; check for removal of last character in buffer 0097 E481 ; N.B. this code is only executed for the remove option 0098 E481 E0 02 CPXIM OUTPUT 0099 E483 90 0A BCC REMOV4 ;[input buffer, buffer empty event not applicable] 0100 E485 DD E1 02 CMPAX BFEND 0101 E488 D0 05 BNE REMOV4 ;[not last character] 0102 E48A ; signal buffer empty event 0103 E48A A0 00 LDYIM EVMPTY 0104 E48C 20 94 E4 JSR EVENT 0105 E48F REMOV4 0106 E48F 68 PLA ;restore character read 0107 E490 A8 TAY ;Y := character 0108 E491 REMOV3 ;return with C=0 indicating removal successful 0109 E491 28 PLP ;restore interrupt state 0110 E492 18 CLC 0111 E493 60 RTS 0112 E494 0113 E494 0114 E494 EVENT ;signal event given by Y, optional arguments given in A & X 0115 E494 ; this routine must not corrupt A 0116 E494 08 PHP 0117 E495 78 SEI 0118 E496 48 PHA ;save A 0119 E497 85 FA STA EVENTA ;save A 0120 E499 B9 BF 02 LDAAY EVENTS 0121 E49C F0 41 BEQ EVENT0 ;[event disabled] 0122 E49E ; event enabled, call event routine 0123 E49E 98 TYA ;A = event code 0124 E49F A4 FA LDY EVENTA ;Y := argument passed originally in A 0125 E4A1 20 A5 F0 JSR JMIEVT ;A = event code, must not corrupt X 0126 E4A4 68 PLA ;restore A 0127 E4A5 28 PLP Acorn macro assembler Page 82 MOS42 Buffer management 0128 E4A6 18 CLC ;indicate event was enabled 0129 E4A7 60 RTS 0130 E4A8 0131 E4A8 CKESCY ;insert character in Y into buffer 0132 E4A8 ; 0133 E4A8 ; signal input event 0134 E4A8 ; 0135 E4A8 98 TYA ;A := character 0136 E4A9 A0 02 LDYIM EVKYBD 0137 E4AB 20 94 E4 JSR EVENT ;assumes A and X not corrupted 0138 E4AE A8 TAY 0139 E4AF INSERT ;FX call to insert character into buffer 0140 E4AF 98 TYA 0141 E4B0 INSRT ;insert character into buffer 0142 E4B0 ; 0143 E4B0 6C 2A 02 JMI INSVEC ;use indirection (defaults to INS) 0144 E4B3 ; 0145 E4B3 INS 0146 E4B3 ; A = character 0147 E4B3 ; X = buffer index 0148 E4B3 [ $Tutu 0151 E4B3 | 0152 E4B3 ; disable interrupts 0153 E4B3 08 PHP 0154 E4B4 78 SEI 0155 E4B5 ] 0156 E4B5 ; save character 0157 E4B5 48 PHA 0158 E4B6 ; construct buffer end offset in Y 0159 E4B6 BC E1 02 LDYAX BFEND 0160 E4B9 C8 INY 0161 E4BA D0 03 BNE INSRT2 0162 E4BC ; buffer wraparound 0163 E4BC BC 47 E4 LDYAX BFORG 0164 E4BF INSRT2 0165 E4BF 98 TYA 0166 E4C0 DD D8 02 CMPAX BFSTRT 0167 E4C3 F0 0F BEQ INSRT1 ;[buffer full] 0168 E4C5 ; update buffer end pointer 0169 E4C5 BC E1 02 LDYAX BFEND 0170 E4C8 9D E1 02 STAAX BFEND 0171 E4CB ; construct buffer pointer 0172 E4CB 20 50 E4 JSR SETBUF 0173 E4CE ; store character in buffer 0174 E4CE 68 PLA ;A := character 0175 E4CF 91 FA STAIY BUFFLO 0176 E4D1 ; return with C=0 => insert successful 0177 E4D1 28 PLP ;restore interrupt state 0178 E4D2 18 CLC 0179 E4D3 60 RTS 0180 E4D4 0181 E4D4 INSRT1 ;signal buffer full event 0182 E4D4 68 PLA ;restore character 0183 E4D5 E0 02 CPXIM OUTPUT 0184 E4D7 B0 07 BCS INOBUF ;[output buffer, buffer full event not applicable] 0185 E4D9 ; signal input buffer full event 0186 E4D9 A0 01 LDYIM EVFULL 0187 E4DB 20 94 E4 JSR EVENT ;A=character, X=bufferid 0188 E4DE ; (N.B. does not corrupt A, should not corrupt X) 0189 E4DE 48 PHA ;compensate for following PLA 0190 E4DF EVENT0 ;indicate event was disabled 0191 E4DF 68 PLA 0192 E4E0 INOBUF ;output buffer, buffer full event not applicable 0193 E4E0 REMOV1 ;return with C=1 => insert/remove failed due to buffer full/empty 0194 E4E0 28 PLP ;restore interrupt state 0195 E4E1 38 SEC 0196 E4E2 60 RTS 0197 E4E3 0198 E4E3 0199 E4E3 CAPS ;test for an uppercase letter 0200 E4E3 0201 E4E3 48 PHA 0202 E4E4 29 DF ANDIM &DF 0203 E4E6 C9 41 CMPIM "A" 0204 E4E8 90 04 BCC CAPSC1 ;[fail] 0205 E4EA C9 5B CMPIM "Z"+&01 0206 E4EC 90 01 BCC CAPSX ;[succeed] 0207 E4EE CAPSC1 ;set C=1 and exit 0208 E4EE 38 SEC 0209 E4EF CAPSX ;exit 0210 E4EF 68 PLA 0211 E4F0 ; C=0 => Pass, C=1 => Fail 0212 E4F0 60 RTS 0213 E4F1 0214 E4F1 0215 E4F1 RDCHS ;insert character into RDCH (keyboard) buffer 0216 E4F1 A2 00 LDXIM BRDCH 0217 E4F3 RNSRT 0218 E4F3 ; insert character Y into buffer whose index is X, 0219 E4F3 ; checking for the interrupt character (default ASCII escape) 0220 E4F3 ; 0221 E4F3 ; RS423 8 bit does not detect interrupt character 0222 E4F3 8A TXA 0223 E4F4 2D 45 02 AND RS8BIT 0224 E4F7 D0 B6 BNE INSERT ;[RSI & RS423-8-bit, no input event] 0225 E4F9 ; 0226 E4F9 98 TYA 0227 E4FA 4D 6C 02 EOR INTCH ;default INTCH is ESC 0228 E4FD 0D 75 02 ORA ESCHAR ;treat as character? 0229 E500 D0 A6 BNE CKESCY ;[not escape character or let escape thru, take no action] 0230 E502 ; 0231 E502 ; ESC detected - ignore ? 0232 E502 AD 58 02 LDA CRIT 0233 E505 6A RORA 0234 E506 98 TYA ;A := character 0235 E507 B0 0A BCS CLCRTS ;[ignore escape] 0236 E509 ; 0237 E509 A0 06 LDYIM EVESC 0238 E50B 20 94 E4 JSR EVENT ;N.B. does not corrupt A 0239 E50E 90 03 BCC CKESC1 ;[event was enabled, no need to take default action] 0240 E510 ; 0241 E510 ; event was disabled, so take default action 0242 E510 ; default escape routine 0243 E510 ; C=1 0244 E510 20 74 E6 JSR CESCPS ;set escape flag **** MUST USE ROUTINE CESCPS **** 0245 E513 CKESC1 ;character 'inserted' successfully 0246 E513 CLCRTS 0247 E513 18 CLC 0248 E514 ; C=0 => character inserted OK, C=1 => character not inserted 0249 E514 60 RTS ;RETURN - do not insert ESC into buffer 0250 E515 Acorn macro assembler Page 83 MOS42 Buffer management 0251 E515 RDCHGX ;check for cursor option 1 0252 E515 6A RORA 0253 E516 68 PLA 0254 E517 B0 79 BCS RDCHGCLC ;[option 1 active, return &87..&8B] 0255 E519 ; treat as cursor option 2 0256 E519 RDCHGS ;process character as real softkey 0257 E519 98 TYA ;A := character 0258 E51A ; 0259 E51A 48 PHA 0260 E51B 4A LSRA 0261 E51C 4A LSRA 0262 E51D 4A LSRA 0263 E51E 4A LSRA 0264 E51F ; 0265 E51F 49 04 EORIM &04 ;fudge to tie in with frozen documentation 0266 E521 A8 TAY 0267 E522 ; character on stack 0268 E522 ; 0269 E522 B9 65 02 LDAAY SOFTLO-&08 0270 E525 C9 01 CMPIM &01 ;test softkey range option 0271 E527 F0 6B BEQ GKEY ;[expand softkey] 0272 E529 68 PLA ;restore character 0273 E52A 90 0D BCC RDCHG1 ;[ignore key] 0274 E52C ; return byte code 0275 E52C ; C=1 0276 E52C 29 0F ANDIM &0F ;A := offset of soft key 0277 E52E 18 CLC 0278 E52F 79 65 02 ADCAY SOFTLO-&08 0279 E532 0280 E532 18 CLC 0281 E533 60 RTS ;read successful, character in A 0282 E534 0283 E534 0284 E534 RDCHGB 0285 E534 ; invalid character at cursor position 0286 E534 ; complain by transmitting BEL 0287 E534 20 6F E8 JSR BELL ;**** N.B. NOT THRU OSWRCH **** must restore X 0288 E537 68 PLA 0289 E538 AA TAX ;restore X 0290 E539 ; get next character 0291 E539 ; 0292 E539 RDCHG1 ;process character from currently selected input buffer 0293 E539 20 60 E4 JSR REMOV ;get character from buffer 0294 E53C B0 55 BCS RDCHG0 ;[buffer empty, C=1] 0295 E53E ; 0296 E53E ; C=0 0297 E53E ; 0298 E53E ; character is in A 0299 E53E ; 0300 E53E ; check whether to set RTS hi for RS423 input 0301 E53E ; save A 0302 E53E 48 PHA 0303 E53F ; 0304 E53F ; check for RS423 input buffer 0305 E53F E0 01 CPXIM BRSI 0306 E541 D0 06 BNE RDCHL ;[keyboard buffer, C=0] 0307 E543 ; 0308 E543 20 73 E1 JSR RSETX ;set RHITXE if applicable 0309 E546 ; 0310 E546 A2 01 LDXIM BRSI ;restore bufferid 0311 E548 38 SEC 0312 E549 ; 0313 E549 RDCHL ;do not alter RTS 0314 E549 ; C=0 => keyboard, C=1 => RS423 0315 E549 ; 0316 E549 ; restore A 0317 E549 68 PLA 0318 E54A ; 0319 E54A 90 05 BCC RDCHK ;[keyboard] 0320 E54C ; 0321 E54C ; RS423 0322 E54C ; 0323 E54C AC 45 02 LDY RS8BIT 0324 E54F D0 41 BNE RDCHGCLC ;[let RS423 deliver 8 bit codes] 0325 E551 RDCHK 0326 E551 ; 0327 E551 ; test to see if it is a softkey (real or pseudo) 0328 E551 A8 TAY ;Y := character 0329 E552 10 3E BPL RDCHGCLC ;[not a soft key (top bit zero), C=0] 0330 E554 0331 E554 [ FALSE=0 0334 E554 ] 0335 E554 0336 E554 ; character is a softkey 0337 E554 ; check for cursor control key 0338 E554 29 0F ANDIM &0F 0339 E556 C9 0B CMPIM MCOPY-SOFTK0 0340 E558 90 BF BCC RDCHGS ;[not a cursor control, therefore a real softkey] 0341 E55A ; cursor control key 0342 E55A ; C=1 0343 E55A ; convert character to codes &87..&8B 0344 E55A 69 7B ADCIM &87-MCOPY+SOFTK0-&1 0345 E55C 48 PHA ;save converted code, real character still in Y 0346 E55D ; there are 3 cursor options (selected by *FX4) 0347 E55D ; 0 cursor edit VDU 0348 E55D ; 1 return codes &87..&8B 0349 E55D ; 2 treat as softkey 0350 E55D AD 7D 02 LDA CURSED 0351 E560 D0 B3 BNE RDCHGX ;[not option 0] 0352 E562 ; option 0 0353 E562 ; check if output to VDU 0354 E562 AD 7C 02 LDA WRCHSW 0355 E565 6A RORA 0356 E566 6A RORA 0357 E567 68 PLA ;restore converted code 0358 E568 B0 CF BCS RDCHG1 ;[ignore character, output not to VDU] 0359 E56A ; let VDU process code 0360 E56A C9 87 CMPIM &87 0361 E56C F0 38 BEQ RDCHGY ;[COPY key] 0362 E56E ; cursor direction key 0363 E56E A8 TAY ;save X 0364 E56F 8A TXA 0365 E570 48 PHA 0366 E571 98 TYA 0367 E572 20 CE D8 JSR VDUB ;N.B. cursor control entry point 0368 E575 68 PLA 0369 E576 AA TAX ;restore X 0370 E577 ; falling thru will transfer control to RDCHG1 0371 E577 RDCHG 0372 E577 ; FETCH CHAR FROM RDCH BUFFER 0373 E577 ; EXPAND SOFT KEYS AS NECESSARY Acorn macro assembler Page 84 MOS42 Buffer management 0374 E577 ; PASS CURSOR CONTROL KEYS 0375 E577 ; STRAIGHT TO VDU DRIVER 0376 E577 ; RETURN CARRY SET IF CHARACTER 0377 E577 ; AVAILABLE 0378 E577 ; 0379 E577 ; check for ECONET interception 0380 E577 ; 0381 E577 2C 5F 02 BIT NETRDC 0382 E57A 10 05 BPL RDCHNM ;[normal RDCH] 0383 E57C ; 0384 E57C ; let network supply character 0385 E57C ; 0386 E57C A9 06 LDAIM NTRDCH 0387 E57E 6C 24 02 JMINET JMI NETVEC ;network operation call, results returned in A and C 0388 E581 0389 E581 0390 E581 RDCHNM ;not reading from network 0391 E581 AD 68 02 LDA SOFKL 0392 E584 F0 B3 BEQ RDCHG1 ;[no pending soft key expansion] 0393 E586 AC C9 02 LDY SOFKP 0394 E589 B9 01 0B LDAAY SKBUF ;GET EXPANSION CHAR 0395 E58C EE C9 02 INC SOFKP ;increment pointer into soft key buffer 0396 E58F CE 68 02 DEC SOFKL ;decrement remaining count of soft key characters 0397 E592 RDCHGCLC 0398 E592 18 CLC ;C=0 => character read successfully 0399 E593 RDCHG0 0400 E593 60 RTS 0401 E594 0402 E594 GKEY ;soft key detected AND soft keys enabled 0403 E594 68 PLA ;restore softkey code 0404 E595 29 0F ANDIM &0F ;convert to soft key number in range 0-15 (assumes SFTKY0=$x0)) 0405 E597 A8 TAY ;Y := soft key number 0406 E598 20 A8 E3 JSR SKSIZE ;A := length of soft key string given by Y 0407 E59B 8D 68 02 STA SOFKL ;SOFKL := length of soft key string 0408 E59E ; N.B. X = soft key number 0409 E59E B9 00 0B LDAAY SKPTR 0410 E5A1 8D C9 02 STA SOFKP ;SOFKP points to key string (N.B. pointer always <> 0) 0411 E5A4 D0 D1 BNE RDCHG ;[ALWAYS JUMP] 0412 E5A6 0413 E5A6 RDCHGY ;copy character at text cursor position 0414 E5A6 8A TXA 0415 E5A7 48 PHA ;save X 0416 E5A8 20 05 D9 JSR COPYCH ;N.B. VDU sets Z bit, but this is not used 0417 E5AB A8 TAY ;save character 0418 E5AC F0 86 BEQ RDCHGB ;[invalid character at text cursor] 0419 E5AE ; valid character at cursor position 0420 E5AE 68 PLA 0421 E5AF AA TAX ;restore X 0422 E5B0 98 TYA ;restore character 0423 E5B1 ; C=0, character in A 0424 E5B1 18 CLC 0425 E5B2 60 RTS 0426 E5B3 0427 E5B3 0428 E5B3 LNK MOS44 0001 E5B3 ; > MOS44 0002 E5B3 TTL MOS44 OSBYTE routines 0003 E5B3 OPT MOS44 Acorn macro assembler Page 85 MOS44 OSBYTE routines 0004 E5B3 ;(c) 1981 ACORN Computers Limited 0005 E5B3 ;BBC Microcomputer Machine Operating System (MOS) 0006 E5B3 ;Change record: 0007 E5B3 ;01-Mar-82 PB PEEK and POKE introduced 0008 E5B3 ;Author(s): 0009 E5B3 ;PB Paul Bond 0010 E5B3 0011 E5B3 0012 E5B3 BYTET ;table for OSBYTE. N.B. lo-byte followed by hi-byte 0013 E5B3 ; 0014 E5B3 ; 0 indicate version number 0015 E5B3 ; X=0 => BRK message 0016 E5B3 ; X<>0 => return version number in X 0017 E5B3 21 E8 & VER 0018 E5B5 0019 E5B5 ; 0020 E5B5 ; 1 set value 0021 E5B5 88 E9 & V2B156 0022 E5B7 0023 E5B7 ; 0024 E5B7 ; 2 select input stream 0025 E5B7 ; X=0 => select keyboard, disable RS423 0026 E5B7 ; X=1 => select RS423, enable RS423 0027 E5B7 ; X=2 => select keyboard, enable RS423 0028 E5B7 D3 E6 & SELIN 0029 E5B9 0030 E5B9 ; 0031 E5B9 ; 3 select output stream(s) 0032 E5B9 ; X=rrrrspvl 0033 E5B9 ; r (reserved) 0034 E5B9 ; s=0 => spooling enabled 0035 E5B9 ; p=0 => printing enabled 0036 E5B9 ; v=0 => output to VDU enabled 0037 E5B9 ; l=1 => output to RS423 enabled 0038 E5B9 97 E9 & V2B34 0039 E5BB 0040 E5BB ; 0041 E5BB ; 4 enable/disable cursor edit 0042 E5BB ; X=0 => cursor editing enabled 0043 E5BB ; X=1 => COPY/LEFT/RIGHT/DOWN/UP return $87/$88/$89/$8A/$8B 0044 E5BB ; X=2 => COPY/LEFT/RIGHT/DOWN/UP at as soft keys 11 thru 15 0045 E5BB 97 E9 & V2B34 0046 E5BD 0047 E5BD ; 0048 E5BD ; 5 select print destination 0049 E5BD ; X=0 => infinite sink 0050 E5BD ; X=1 => centronics 0051 E5BD ; X=2 => RS423 0052 E5BD 76 E9 & SPRINT 0053 E5BF 0054 E5BF ; 0055 E5BF ; 6 set printer ignore character 0056 E5BF ; X=0 => ignore no characters 0057 E5BF ; X<>0 => ignore character 0058 E5BF 88 E9 & V2B156 0059 E5C1 0060 E5C1 ; 0061 E5C1 ; 7 set RS423 receive baud rate 0062 E5C1 ; X=0 => set default (9600) 0063 E5C1 ; X=1/2/3/4/5/6/7/8 => 75/150/300/1200/2400/4800/9600/19200 0064 E5C1 8B E6 & RXBAUD 0065 E5C3 0066 E5C3 ; 0067 E5C3 ; 8 set RS423 trasmit baud rate 0068 E5C3 ; [values as for OSBYTE(7)] 0069 E5C3 89 E6 & TXBAUD 0070 E5C5 0071 E5C5 ; 0072 E5C5 ; 9 set flash mark period 0073 E5C5 ; X=0 => infinite 0074 E5C5 ; X<>0 => * 20 milliseconds 0075 E5C5 B0 E6 & FMRK 0076 E5C7 0077 E5C7 ; 0078 E5C7 ; 10 set flash space period 0079 E5C7 ; 9 set flash mark period 0080 E5C7 ; X=0 => infinite 0081 E5C7 ; X<>0 => * 20 milliseconds 0082 E5C7 B2 E6 & FSPC 0083 E5C9 0084 E5C9 ; 0085 E5C9 ; 11 set auto-repeat delay period 0086 E5C9 ; X=0 => suppress auto-repeat 0087 E5C9 ; X<>0 => set delay between first and second character to centiseconds 0088 E5C9 95 E9 & ARDLY 0089 E5CB 0090 E5CB ; 0091 E5CB ; 12 set auto-repeat repeat period 0092 E5CB ; X=0 => set delay and period to values on power-up 0093 E5CB ; X<>0 => set period between subsequent characters to centiseconds 0094 E5CB 8C E9 & ARRPT 0095 E5CD 0096 E5CD ; 0097 E5CD ; 13 disable event 0098 E5CD ; X=event_code 0099 E5CD ; 0: output buffer empty 0100 E5CD ; 1: input buffer full 0101 E5CD ; 2: character entering input buffer 0102 E5CD ; 3: ADC conversion complete 0103 E5CD ; 4: vertical SYNC 0104 E5CD ; 5: interval timer crossing zero 0105 E5CD ; 6: ESCAPE detected 0106 E5CD ; 7: RS423 error 0107 E5CD F9 E6 & MDSABL 0108 E5CF 0109 E5CF ; 0110 E5CF ; 14 enable event 0111 E5CF ; [values as for OSBYTE(13)] 0112 E5CF FA E6 & ENABLE 0113 E5D1 0114 E5D1 ; 0115 E5D1 ; 15 flush buffer class 0116 E5D1 ; X=0 => flush all buffers 0117 E5D1 ; X=1 => flush currently selected input buffer 0118 E5D1 A8 F0 & FLUSHC 0119 E5D3 0120 E5D3 ; 0121 E5D3 ; 16 select number of ADC channels 0122 E5D3 ; X=0 => stop scanning ADC channels 0123 E5D3 ; X=1/2/3/4 => only scan channels 1 thru 0124 E5D3 06 E7 & SETADC Acorn macro assembler Page 86 MOS44 OSBYTE routines 0125 E5D5 0126 E5D5 ; 0127 E5D5 ; 17 start ADC conversion on channel X 0128 E5D5 ; X=1/2/3/4 => start conversion on channel 0129 E5D5 8C DE & ADCBEG 0130 E5D7 0131 E5D7 ; 0132 E5D7 ; 18 reset soft keys 0133 E5D7 C8 E9 & RSOFT 0134 E5D9 0135 E5D9 ; 0136 E5D9 ; 19 wait for vertical sync 0137 E5D9 B6 E9 & WFVS 0138 E5DB 0139 E5DB ; 0140 E5DB ; 20 implode/explode soft font 0141 E5DB 07 CD & FONT 0142 E5DD 0143 E5DD ; 0144 E5DD ; 21 flush specific buffer 0145 E5DD B4 F0 & FLUSHS 0146 E5DF 0147 E5DF ; 0148 E5DF 0016 BYTEL * .-BYTET:SHR: 1 ;next entry in BYTETL table (lo component) 0149 E5DF ; 0150 E5DF BYTET2 0151 E5DF 0075 BYTEM * &0075 0152 E5DF ; 0153 E5DF ; 0154 E5DF 6C E8 & VDUST ;read VDU status; $75 0155 E5E1 0156 E5E1 ; 0157 E5E1 D9 E9 & MOSTST ;reflect state of KSTAT; $76 0158 E5E3 0159 E5E3 ; 0160 E5E3 75 E2 & SHUTES ;close EXEC and SPOOL files; $77 0161 E5E5 0162 E5E5 ; 0163 E5E5 45 F0 & OLDKEY ;set keyboard old key; $78 0164 E5E7 0165 E5E7 ; 0166 E5E7 CF F0 & XSCANB ;scan keyboard at specific address; $79 0167 E5E9 0168 E5E9 ; 0169 E5E9 CD F0 & XSCANA ;scan keyboard from matrix entry $10; $7A 0170 E5EB 0171 E5EB ; 0172 E5EB 97 E1 & PFREE ;indicate printer dormant; $7B 0173 E5ED 0174 E5ED ; 0175 E5ED 73 E6 & CESCPC ;clear escape flag; $7C 0176 E5EF 0177 E5EF ; 0178 E5EF 74 E6 & CESCPS ;set escape flag; $7D 0179 E5F1 0180 E5F1 ; 0181 E5F1 5C E6 & CESCP ;clear escape flag and purge selected input buffer; $7E 0182 E5F3 0183 E5F3 ; 0184 E5F3 35 E0 & EOF ;end of file; $7F 0185 E5F5 0186 E5F5 ; 0187 E5F5 ; $80 0188 E5F5 ;; read data on ADC channel 0189 E5F5 ; in: Y>=0 => X=0 => read control information 0190 E5F5 ; X<>0 => read last conversion on channel X 0191 E5F5 ; Y<0 => read info for buffer NOT(X) 0192 E5F5 ; out: Y>=0 => X=0 => X=fire-buttons, Y=last-channel-to-convert 0193 E5F5 ; X<>0 => X=lo-data, Y=hi-data 0194 E5F5 ; Y<0 => X=buffer-count (input: bytes ready, output: bytes left) 0195 E5F5 4F E7 & RADCX 0196 E5F7 0197 E5F7 ; 0198 E5F7 ; $81 0199 E5F7 ; read key with time limit 0200 E5F7 ; in: Y>=0 => X=lo-count, Y=hi-count (centiseconds) 0201 E5F7 ; Y<0 => X=NOT(key-matrix-address) 0202 E5F7 ; out: Y>=0 => Y=$00 => X=character 0203 E5F7 ; Y=$1B => escape condition detected 0204 E5F7 ; Y=$FF => timeout 0205 E5F7 ; Y<0 => X=0 => key not pressed 0206 E5F7 ; X<>0 => key pressed 0207 E5F7 13 E7 & INKY 0208 E5F9 0209 E5F9 ; 0210 E5F9 ; $82 0211 E5F9 ; read machine high order address 0212 E5F9 ; out: X = lo-component, Y = hi-component 0213 E5F9 29 E7 & RMHA 0214 E5FB 0215 E5FB ; 0216 E5FB ; $83 0217 E5FB ; read operating system high water mark 0218 E5FB ; out: X = lo-address, Y = hi-address 0219 E5FB 85 F0 & RMLA 0220 E5FD 0221 E5FD ; 0222 E5FD ; $84 0223 E5FD ; read address of start of current screen mode 0224 E5FD ; out: X = lo-address, Y = hi-address 0225 E5FD 23 D9 & TOPCMD 0226 E5FF 0227 E5FF ; 0228 E5FF ; $85 0229 E5FF ; read address of start of screen for mode X 0230 E5FF ; in: X = mode 0231 E5FF ; out: X = lo-address, Y = hi-address 0232 E5FF 26 D9 & TOPMDX 0233 E601 0234 E601 ; 0235 E601 ; $86 0236 E601 ;; read text cursor position 0237 E601 ; out: X = x-text-coord, Y = y-text-coord 0238 E601 47 D6 & CSRPOS 0239 E603 0240 E603 ; 0241 E603 ; $87 0242 E603 ;; read character at text cursor 0243 E603 ; out: X=0 => no character at cursor position 0244 E603 ; X<>0 => X=character 0245 E603 ; Y = current screen mode Acorn macro assembler Page 87 MOS44 OSBYTE routines 0246 E603 C2 D7 & READCH 0247 E605 0248 E605 ; 0249 E605 ; $88 0250 E605 ; *CODE X, Y 0251 E605 ; in: X = arg, Y = arg 0252 E605 ; out: C = return code 0253 E605 ; X = return code 0254 E605 ; Y = return code 0255 E605 57 E6 & MCODE 0256 E607 0257 E607 ; 0258 E607 ; $89 0259 E607 ; *MOTOR X, Y 0260 E607 ; in: X=0 => turn motor off 0261 E607 ; X=1 => turn motor on 0262 E607 ; Y => motor selection 0263 E607 7F E6 & MOTOR ;MOTOR command; $89 0264 E609 0265 E609 ; 0266 E609 ; $8A 0267 E609 ; insert character into buffer 0268 E609 ; in: X = bufferid, Y = character 0269 E609 AF E4 & INSERT 0270 E60B 0271 E60B ; 0272 E60B ; $8B 0273 E60B ; *OPT X, Y 0274 E60B ; in: X = arg, Y = arg (effect is filing system dependent) 0275 E60B 34 E0 & OPT 0276 E60D 0277 E60D ; 0278 E60D ; $8C 0279 E60D ; *TAPE X, Y 0280 E60D ; in: X=0 => tape filing system at default baud rate (1200 baud) 0281 E60D ; X=3 => tape filing system at 300 baud 0282 E60D ; X=12 => tape filing system at 1200 baud 0283 E60D ; Y=$00 => tape filing system is cassette 0284 E60D ; Y=$FF => tape filing system is ROMs 0285 E60D 35 F1 & TAPE 0286 E60F 0287 E60F ; 0288 E60F ; $8D 0289 E60F ; *ROM X, Y 0290 E60F ; X and Y ignored 0291 E60F 35 F1 & CROM 0292 E611 0293 E611 ; 0294 E611 ; $8E 0295 E611 ; enter language 0296 E611 ; in: X = ROMid of language, Y = arg 0297 E611 E7 DB & SELANG 0298 E613 0299 E613 ; 0300 E613 ; $8F 0301 E613 ; call paged ROM function 0302 E613 ; in: X = reason code, Y = arg 0303 E613 ; out: C = return code 0304 E613 ; Y = return code 0305 E613 68 F1 & SVOP 0306 E615 0307 E615 ; 0308 E615 ; $90 0309 E615 ; alter TV characteristics 0310 E615 ; in: X = vertical sync adjust, Y = interlace adjust 0311 E615 E3 EA & TV 0312 E617 0313 E617 ; 0314 E617 ; $91 0315 E617 ; remove character from buffer 0316 E617 ; in: X = bufferid 0317 E617 ; out: C=0 => Y=character 0318 E617 ; C=1 => buffer empty 0319 E617 60 E4 & REMOV 0320 E619 0321 E619 ; 0322 E619 ; $92 0323 E619 ; read from FRED 0324 E619 ; in: X = offset 0325 E619 ; out: Y = value 0326 E619 AA FF & RFRED 0327 E61B 0328 E61B ; 0329 E61B ; $93 0330 E61B ; write to FRED 0331 E61B ; in: X = offset, Y = value 0332 E61B F4 EA & WFRED 0333 E61D 0334 E61D ; 0335 E61D ; $94 0336 E61D ; read from JIM 0337 E61D ; in: X = offset 0338 E61D ; out: Y = value 0339 E61D AE FF & RJIM 0340 E61F 0341 E61F ; 0342 E61F ; $95 0343 E61F ; write to JIM 0344 E61F ; in: X = offset, Y = value 0345 E61F F9 EA & WJIM 0346 E621 0347 E621 ; 0348 E621 ; $96 0349 E621 ; read from SHEILA 0350 E621 ; in: X = offset 0351 E621 ; out: Y = value 0352 E621 B2 FF & RSHEIL 0353 E623 0354 E623 ; 0355 E623 ; $97 0356 E623 ; write to SHEILA 0357 E623 ; in: X = offset, Y = value 0358 E623 FE EA & WSHEIL 0359 E625 0360 E625 ; 0361 E625 ; $98 0362 E625 ; examine character in buffer 0363 E625 ; in: X = bufferid 0364 E625 ; out: C=0 => Y=character 0365 E625 ; C=1 => buffer empty 0366 E625 5B E4 & EXAM Acorn macro assembler Page 88 MOS44 OSBYTE routines 0367 E627 0368 E627 ; 0369 E627 ; $99 0370 E627 ; insert character into buffer dealing with ESC code 0371 E627 ; in: X = bufferid, Y = character 0372 E627 F3 E4 & RNSRT 0373 E629 0374 E629 ; 0375 E629 ;; $9A 0376 E629 ; update vidproc control register 0377 E629 ; in: X = value 0378 E629 FF E9 & VP0 0379 E62B 0380 E62B ; 0381 E62B ; $9B 0382 E62B ; update vidproc palette register 0383 E62B ; in: X = value EOR $07 0384 E62B 10 EA & VP1 0385 E62D 0386 E62D ; 0387 E62D ; $9C 0388 E62D ; update 6850 ACIA 0389 E62D ; in: X = value, Y = mask 0390 E62D 7C E1 & RS423 0391 E62F 0392 E62F ; 0393 E62F ; $9D 0394 E62F ; fast tube BPUT 0395 E62F ; in: X = byte, Y = handle 0396 E62F A7 FF & FXBPUT 0397 E631 0398 E631 ; 0399 E631 ; $9E 0400 E631 ; read from speech chip 0401 E631 ; in: Y = command 0402 E631 ; out: Y = result 0403 E631 6D EE & RSPECH 0404 E633 0405 E633 ; 0406 E633 ; $9F 0407 E633 ; write to speech chip 0408 E633 ; in: Y = command 0409 E633 7F EE & WSPECH 0410 E635 0411 E635 ; 0412 E635 ; $A0 0413 E635 ; read VDU variables 0414 E635 ; in: X = index 0415 E635 ; out: X = variable0, Y = variable1 0416 E635 C0 E9 & VDUVAR 0417 E637 0418 E637 ; 0419 E637 00A1 BYTEH * .-BYTET2:SHR: 1+BYTEM ;next entry in BYTET table (hi component) 0420 E637 ; 0421 E637 9C E9 & SETV ;set variable 0422 E639 0423 E639 ; 0424 E639 59 E6 & JMIUSR ;OSWORD calls >=$E0 0425 E63B 0426 E63B 0427 E63B 0428 E63B WORDT ;table for OSWORD. N.B. lo-byte followed by hi-byte 0429 E63B ; 0430 E63B 02 E9 & RDLN ;read line; $00 0431 E63D 0432 E63D ; 0433 E63D D5 E8 & RATM ;read absolute time; $01 0434 E63F 0435 E63F ; 0436 E63F E8 E8 & WATM ;write absolute time; $02 0437 E641 0438 E641 ; 0439 E641 D1 E8 & RITM ;read interval time; $03 0440 E643 0441 E643 ; 0442 E643 E4 E8 & WITM ;write interval time; $04 0443 E645 0444 E645 ; 0445 E645 03 E8 & PEEK ;PEEK; $05 0446 E647 0447 E647 ; 0448 E647 0B E8 & POKE ;POKE; $06 0449 E649 0450 E649 ; 0451 E649 0007 OSWSND * .-WORDT:SHR: 1 0452 E649 ; 0453 E649 2D E8 & NOTE ;sound; $07 0454 E64B 0455 E64B ; 0456 E64B AE E8 & NVLP ;define envelope; $08 0457 E64D 0458 E64D ; 0459 E64D 35 C7 & RPXLXY ;read pixel at given coordinate to X; $09 0460 E64F 0461 E64F ; 0462 E64F F3 CB & RCHDEF ;read character definition of XY to XY+1..8; $0A 0463 E651 0464 E651 ; 0465 E651 48 C7 & RPALET ;read palette for XY to XY+1..4; $0B 0466 E653 0467 E653 ; 0468 E653 E0 C8 & PRPAL ;programme palette; $0C 0469 E655 0470 E655 ; 0471 E655 CE D5 & CSREAD ;cursor read; $0D 0472 E657 0473 E657 ; 0474 E657 000E WORDN * .-WORDT:SHR: 1 ;number of entries in WORDT table 0475 E657 0476 E657 0477 E657 MCODE ;call user code 0478 E657 A9 00 LDAIM ZERO 0479 E659 6C 00 02 JMIUSR JMI USRVEC ;user OSBYTE call/OSWORD calls 0480 E65C 0481 E65C 0482 E65C ; OSBYTE specific routines 0483 E65C ; N.B. routines must exit with PLP to restore 0484 E65C ; caller's interrupt state 0485 E65C CESCP ;clear escape flag ad purge selected input buffer 0486 E65C A2 00 LDXIM ZERO ;indicate escape not cleared 0487 E65E 24 FF BIT ESCFLG Acorn macro assembler Page 89 MOS44 OSBYTE routines 0488 E660 10 11 BPL CESCPC ;[no escape to clear] 0489 E662 ; bypass procedure ? 0490 E662 AD 76 02 LDA EAOPT 0491 E665 D0 0A BNE CESCX ;[bypass normal acknowledge procedure] 0492 E667 ; Z=1, A=$00 0493 E667 ; close exec file 0494 E667 58 CLI ;********** (close may be a long operation) 0495 E668 8D 69 02 STA LINES ;reset page mode page origin 0496 E66B 20 8D F6 JSR EXEC ;just close exec file, N.B. needs Z=1, A=$00 0497 E66E ; flush all buffers and clear soft key expansion 0498 E66E 20 AA F0 JSR FLSHAL ;N.B. also kills sound AND cancels VDU queueing 0499 E671 CESCX 0500 E671 A2 FF LDXIM &FF ;indicate escape cleared 0501 E673 CESCPC ;clear system escape flag 0502 E673 18 CLC 0503 E674 CESCPS ;set system escape flag (N.B. C=1) 0504 E674 66 FF ROR ESCFLG 0505 E676 2C 7A 02 BIT TUBEM 0506 E679 30 01 BMI TESC ;[tube active] 0507 E67B 60 RTS 0508 E67C ; 0509 E67C TESC 0510 E67C 4C 03 04 JMP TBESC ;tube escape 0511 E67F 0512 E67F 0513 E67F MOTOR ;control cassette motor 0514 E67F ; on entry: X=0 => motor off 0515 E67F ; X<>0 => motor on 0516 E67F ; N.B. previous instruction was LDX 0517 E67F AD 82 02 LDA SPREGA 0518 E682 A8 TAY ;Y := old value 0519 E683 ; 0520 E683 2A ROLA 0521 E684 E0 01 CPXIM &01 ;C=0 => X=0, C=1 => X<>0 0522 E686 6A RORA 0523 E687 50 1E BVC STASP ;[ALWAYS jump] 0524 E689 0525 E689 0526 E689 TXBAUD ;set RS423 transmit baudrate (N.B. A=$08) 0527 E689 A9 38 LDAIM &38 0528 E68B RXBAUD ;set RS423 receive baudrate (N.B. A=$07) 0529 E68B 49 3F EORIM &3F ;Rx: A=$38, Tx: A=$07 0530 E68D 85 FA STA MASK 0531 E68F AC 82 02 LDY SPREGA 0532 E692 E0 09 CPXIM &09 0533 E694 B0 17 BCS BAUD1 ;[bad baud selection] 0534 E696 3D AD E9 ANDAX BAUDS ;extract serproc baud bits 0535 E699 85 FB STA BAUD 0536 E69B 98 TYA 0537 E69C 05 FA ORA MASK 0538 E69E 45 FA EOR MASK ;clear slot for baudrate 0539 E6A0 05 FB ORA BAUD 0540 E6A2 09 40 ORAIM &40 ;set cassette/RS423 bit 0541 E6A4 4D 5D 02 EOR RSCASS ;select cassette/RS423 0542 E6A7 ; 0543 E6A7 STASP ;used by MOTOR and RESET 0544 E6A7 8D 82 02 STA SPREGA 0545 E6AA 8D 10 FE STA SERPRC 0546 E6AD ; 0547 E6AD BAUD1 0548 E6AD TYATAX ;used by TXBAUD, RXBAUD, FSPC, FMRK 0549 E6AD 98 TYA 0550 E6AE BADEVT 0551 E6AE AA TAX ;X := old value (bad events appear disabled) 0552 E6AF 60 RTS 0553 E6B0 0554 E6B0 0555 E6B0 FMRK ;set flash mark, Y=0, C=1 0556 E6B0 C8 INY 0557 E6B1 18 CLC 0558 E6B2 ; 0559 E6B2 ; Y=1, C=0 0560 E6B2 ; 0561 E6B2 FSPC ;set flash space, Y=0, C=1 0562 E6B2 B9 52 02 LDAAY FLASHB 0563 E6B5 ; 0564 E6B5 48 PHA 0565 E6B6 8A TXA 0566 E6B7 99 52 02 STAAY FLASHB 0567 E6BA 68 PLA 0568 E6BB ; 0569 E6BB A8 TAY 0570 E6BC ; 0571 E6BC ; C=0 => mark, C=1 => space 0572 E6BC ; FMS0 exit used, despite X not being corrupted 0573 E6BC ; (makes code clearer) 0574 E6BC AD 51 02 LDA FLCNT 0575 E6BF D0 10 BNE FMS1 ;[flash enabled] 0576 E6C1 ; 'kick' flash count 0577 E6C1 8E 51 02 STX FLCNT 0578 E6C4 ; force mark/space (lsb VPREGA := C) 0579 E6C4 AD 48 02 LDA VPREGA 0580 E6C7 08 PHP 0581 E6C8 6A RORA 0582 E6C9 28 PLP 0583 E6CA 2A ROLA 0584 E6CB 8D 48 02 STA VPREGA 0585 E6CE 8D 20 FE STA VPROC0 0586 E6D1 FMS1 ; chain from clear escape condition routine 0587 E6D1 50 DA BVC TYATAX ;[ALWAYS jump] 0588 E6D3 0589 E6D3 0590 E6D3 SELIN ;select input 0591 E6D3 8A TXA 0592 E6D4 29 01 ANDIM &01 ;force legal bufferid 0593 E6D6 48 PHA ;save change 0594 E6D7 AD 50 02 LDA RSCTFL ;A := old state of controller status 0595 E6DA 2A ROLA 0596 E6DB E0 01 CPXIM &01 ;C=0 => disable RS423, C=1 => enable RS423 0597 E6DD 6A RORA ;A := new state of controller status 0598 E6DE ; *FX 2,0 disables RS423, *FX 2,(1,2) enables RS423 0599 E6DE ; if RS423 then enable RS423 Rx interrupt 0600 E6DE CD 50 02 CMP RSCTFL 0601 E6E1 08 PHP 0602 E6E2 8D 50 02 STA RSCTFL 0603 E6E5 8D 08 FE STA RSCTL ;update RS423 control register 0604 E6E8 20 73 E1 JSR RSETX ;set RHITXE if possible 0605 E6EB 28 PLP 0606 E6EC F0 03 BEQ SELIN1 ;branch if no change 0607 E6EE 2C 09 FE BIT RSDATA ;purge character in controller 0608 E6F1 ; this purges data register if: disabled state -> enabled state Acorn macro assembler Page 90 MOS44 OSBYTE routines 0609 E6F1 ; this does not matter if: enabled state -> disabled state 0610 E6F1 SELIN1 0611 E6F1 AE 41 02 LDX RDCHSW ;X := old value 0612 E6F4 68 PLA 0613 E6F5 8D 41 02 STA RDCHSW ;update value 0614 E6F8 60 RTS 0615 E6F9 0616 E6F9 0617 E6F9 MDSABL ;disable event X 0618 E6F9 ; N.B. Y=0 0619 E6F9 98 TYA ;A := 0 0620 E6FA ;* LDAIM ZERO 0621 E6FA ENABLE ;enable event X (N.B. A<>$00) 0622 E6FA E0 0A CPXIM NEVENT 0623 E6FC B0 B0 BCS BADEVT 0624 E6FE BC BF 02 LDYAX EVENTS 0625 E701 9D BF 02 STAAX EVENTS 0626 E704 ; 0627 E704 50 A7 BVC TYATAX ;[ALWAYS jump] 0628 E706 0629 E706 0630 E706 SETADC ;set number of ADC channels to scan 0631 E706 ; N.B. preceeding instruction was LDX 0632 E706 ; Y=0 0633 E706 F0 03 BEQ SETAD1 ;[kill ADC (eventually)] 0634 E708 20 8C DE JSR ADCBEG ;initiate conversion on channel X, uses Y=0 0635 E70B ; N.B. X not corrupted 0636 E70B SETAD1 0637 E70B ; a value of X=0 stops the ADC after the next (external) channel 1 0638 E70B ; conversion 0639 E70B AD 4D 02 LDA MAXADC 0640 E70E 8E 4D 02 STX MAXADC 0641 E711 AA TAX ;X := old value 0642 E712 60 RTS 0643 E713 0644 E713 0645 E713 INKY ;read key with time limit 0646 E713 98 TYA 0647 E714 30 0B BMI RDKY 0648 E716 58 CLI ;**** ENABLE INTERRUPTS 0649 E717 20 BB DE JSR INKEY 0650 E71A B0 03 BCS INKY1 ;[escape detected or count exhausted] 0651 E71C ; 0652 E71C ; character read 0653 E71C ; 0654 E71C AA TAX ;X := character (INKEY) or lo-count (BUFN) 0655 E71D A9 00 LDAIM ZERO ;Y = 0 => success 0656 E71F ; 0657 E71F INKY1 ;escape detected or count exhausted, C=1 0658 E71F A8 TAY ;Y < $80 => escape, Y >= $80 => count exhausted 0659 E720 60 RTS 0660 E721 0661 E721 0662 E721 RDKY ;C=1, V=0, read key addressed by X 0663 E721 ; N.B. interrupts disabled 0664 E721 ; 0665 E721 ; test key at matrix address 0666 E721 ; 0667 E721 [ $Tutu 0675 E721 | 0676 E721 8A TXA 0677 E722 49 7F EORIM &7F 0678 E724 AA TAX 0679 E725 20 68 F0 JSR JMIKEY 0680 E728 2A ROLA ;result into C 0681 E729 ] 0682 E729 ; 0683 E729 BADADC ;entered with C=1 0684 E729 RMHA ;entered with C=1 0685 E729 ; C=0 => return 0, C=1 => return -1 0686 E729 A2 FF LDXIM &FF ;N.B. I/O processor is notionally located at address $FFFFxxxx 0687 E72B A0 FF LDYIM &FF 0688 E72D B0 02 BCS RDKY0 0689 E72F ; INKEY entry (key open) 0690 E72F E8 INX ;X=0 0691 E730 ; invalid soft key read, return Y<>0 0692 E730 C8 INY ;Y=0 (except for soft key read entry) 0693 E731 RDKY0 0694 E731 60 RTS 0695 E732 0696 E732 0697 E732 BUFN ;count entries in buffer, called by FX ADVAL with negative argument 0698 E732 ; -N gives count for buffer with external id N 0699 E732 ; C=1 (by FX conventions) 0700 E732 8A TXA 0701 E733 49 FF EORIM &FF 0702 E735 AA TAX ;X := bufferid 0703 E736 ; 0704 E736 ; count entries (in)/(remaining in) buffer given by X 0705 E736 ; returns: 0706 E736 ; number of entries present for input buffers 0707 E736 ; number of entries remaining for output buffers 0708 E736 ; 0709 E736 E0 02 CPXIM OUTPUT 0710 E738 ; C=0 => count used entries 0711 E738 ; C=1 => count free slots 0712 E738 ; 0713 E738 JMICNT 0714 E738 B8 CLV ;V=0 => count buffer entry 0715 E739 50 03 BVC JMICNP ;[ALWAYS jump] 0716 E73B ; 0717 E73B 2C B7 D9 JMIPUR BIT FFBYT ;V=1 0718 E73E 6C 2E 02 JMICNP JMI CNPVEC ;use indirection (defaults to CNP) 0719 E741 ; return count in X (lo) and Y (hi) 0720 E741 0721 E741 0722 E741 CNTRS ;count bytes left in RS423 input buffer 0723 E741 38 SEC ;count empty slots left ... 0724 E742 A2 01 LDXIM BRSI ;... in RS423 input buffer 0725 E744 20 38 E7 JSR JMICNT 0726 E747 ; count in Y (hi) and X (lo) 0727 E747 C0 01 CPYIM &01 0728 E749 B0 03 BCS CNTRS0 ;[more than RSOVER bytes left] 0729 E74B ; 0730 E74B EC 5B 02 CPX RSHLVL 0731 E74E ; 0732 E74E CNTRS0 0733 E74E ; C=0 => overflow 0734 E74E ; C=1 => no overflow 0735 E74E 60 RTS 0736 E74F Acorn macro assembler Page 91 MOS44 OSBYTE routines 0737 E74F 0738 E74F RADCX ;read ADC channel X 0739 E74F 30 E1 BMI BUFN ;[count entries in buffer] 0740 E751 F0 0C BEQ FIRE ;[get status of fire buttons] 0741 E753 E0 05 CPXIM &05 0742 E755 B0 D2 BCS BADADC 0743 E757 ; return latest conversion 0744 E757 BC B9 02 LDYAX ADCHIV -&01 0745 E75A BD B5 02 LDAAX ADCLOV -&01 0746 E75D AA TAX ;X := lo-byte 0747 E75E 60 RTS 0748 E75F 0749 E75F 0750 E75F FIRE ;get status of fire buttons 0751 E75F ; X=0 0752 E75F AD 40 FE LDA PBQ 0753 E762 6A RORA 0754 E763 6A RORA 0755 E764 6A RORA 0756 E765 6A RORA 0757 E766 49 FF EORIM &FF 0758 E768 29 03 ANDIM &03 ;A := fire buttons 0759 E76A AC BE 02 LDY ADCFLG ;return latest conversion number 0760 E76D ; clear latest conversion number 0761 E76D 8E BE 02 STX ADCFLG 0762 E770 AA TAX ;return status of fire buttons in b0 and b1 0763 E771 60 RTS 0764 E772 0765 E772 0766 E772 LNK MOS46 0001 E772 ; > MOS46 0002 E772 TTL MOS46 OSWORD routines 0003 E772 OPT MOS46 Acorn macro assembler Page 92 MOS46 OSWORD routines 0004 E772 ;(c) 1981 ACORN Computers Limited 0005 E772 ;BBC MOS 0006 E772 ;Change record: 0007 E772 ;203 01-May-82 PB Fix EXTSND bug 0008 E772 ;041 15-Aug-81 PB First edition 0009 E772 ;Author(s): 0010 E772 ;PB Paul Bond 0011 E772 0012 E772 0013 E772 BYTE ;OSBYTE call 0014 E772 ; 0015 E772 ; uses: 0016 E772 ; BYTEX, BYTEY (may be shared by sei-routines) 0017 E772 ; JMILO, JMIHI 0018 E772 ; 0019 E772 48 PHA 0020 E773 08 PHP 0021 E774 78 SEI ;**** DISABLE INTERRUPTS **** 0022 E775 ; 0023 E775 ; save A and X 0024 E775 ; 0025 E775 85 EF STA BYTEA 0026 E777 86 F0 STX BYTEX 0027 E779 84 F1 STY BYTEY 0028 E77B ; 0029 E77B A2 07 LDXIM SVBYTE ;illegal codes are referred to paged ROM 0030 E77D ; 0031 E77D ; check for legal code 0032 E77D ; 0033 E77D C9 75 CMPIM BYTEM 0034 E77F 90 41 BCC BYTELO ;[interactive code] 0035 E781 ; 0036 E781 ; code >= BYTEM 0037 E781 ; 0038 E781 C9 A1 CMPIM BYTEH 0039 E783 90 09 BCC BYTEHI ;[code < BYTEH] 0040 E785 ; 0041 E785 ; check for variable setting 0042 E785 ; 0043 E785 C9 A6 CMPIM VORG 0044 E787 90 3F BCC BYTE0 ;[not a variable setting] 0045 E789 ; 0046 E789 ; set variable 0047 E789 ; 0048 E789 18 CLC ;force A=BYTEH 0049 E78A ; 0050 E78A WORDU ;user OSWORD call, C=1, force A=BYTEH+$01 0051 E78A ; 0052 E78A A9 A1 LDAIM BYTEH 0053 E78C 69 00 ADCIM ZERO ;add in carry (C=0 => variable, C=1 => user OSWORD) 0054 E78E ; 0055 E78E BYTEHI 0056 E78E ; 0057 E78E 38 SEC 0058 E78F E9 5F SBCIM BYTEM-BYTEL 0059 E791 ; 0060 E791 BYTE1 ;construct address of specific OSBYTE routine 0061 E791 ; 0062 E791 0A ASLA ;prepare for Y := 2*code 0063 E792 ; 0064 E792 38 SEC ;indicate OSBYTE call 0065 E793 ; 0066 E793 BYTE2 ;C=0 => OSWORD call 0067 E793 ; 0068 E793 84 F1 STY BYTEY ;save Y 0069 E795 ; 0070 E795 A8 TAY ;Y := 2*code 0071 E796 ; 0072 E796 ; allow net to indirect OS call 0073 E796 ; 0074 E796 2C 5E 02 BIT NETIOC 0075 E799 10 07 BPL NET1 ;[net not indirecting OS calls] 0076 E79B ; 0077 E79B ; indirect OS call thru net 0078 E79B ; 0079 E79B 8A TXA ;A := reason code 0080 E79C B8 CLV 0081 E79D 20 7E E5 JSR JMINET ;args in BYTEA, BYTEX, BYTEY (call type in A) 0082 E7A0 70 1A BVS OSRET ;[net substituted result] 0083 E7A2 ; 0084 E7A2 ; construct specific OSBYTE routine address 0085 E7A2 ; 0086 E7A2 NET1 ;call internal routine 0087 E7A2 B9 B4 E5 LDAAY BYTET+&01 ;hi-byte 0088 E7A5 85 FB STA JMIHI 0089 E7A7 B9 B3 E5 LDAAY BYTET+&00 ;lo-byte 0090 E7AA 85 FA STA JMILO 0091 E7AC ; 0092 E7AC ; enter specific OSBYTE routine 0093 E7AC ; 0094 E7AC ; X = SVBYTE or SVWORD 0095 E7AC ; 0096 E7AC ; 0097 E7AC A5 EF LDA BYTEA ;in case OSBYTE call 0098 E7AE A4 F1 LDY BYTEY ;restore Y 0099 E7B0 ; 0100 E7B0 ; determine type of call 0101 E7B0 ; 0102 E7B0 B0 04 BCS OSB ;[OSBYTE call] 0103 E7B2 ; 0104 E7B2 ; OSWORD call 0105 E7B2 ; 0106 E7B2 A0 00 LDYIM ZERO 0107 E7B4 B1 F0 LDAIY WORDX 0108 E7B6 ; 0109 E7B6 OSB 0110 E7B6 ; 0111 E7B6 ; ********** V=0 USED BY OSBYTE ROUTINES ********** 0112 E7B6 38 SEC ;used by several routines 0113 E7B7 A6 F0 LDX BYTEX ;restore X (N.B. N, Z status used by several routines) 0114 E7B9 20 58 F0 JSR JMI ;enter specific routine 0115 E7BC ; 0116 E7BC OSRET 0117 E7BC ; 0118 E7BC 6A RORA ;save C 0119 E7BD 28 PLP 0120 E7BE 2A ROLA ;restore C (needed by readline routine - BASIC expects it) 0121 E7BF 68 PLA ;restore A 0122 E7C0 B8 CLV ;indicate call recognised 0123 E7C1 60 RTS 0124 E7C2 Acorn macro assembler Page 93 MOS46 OSWORD routines 0125 E7C2 0126 E7C2 BYTELO ;code has top bit clear - use table lo component 0127 E7C2 A0 00 LDYIM ZERO ;only one argument, set Y=0 for variable settings and ADC ops 0128 E7C4 C9 16 CMPIM BYTEL 0129 E7C6 90 C9 BCC BYTE1 ;[recognised code] 0130 E7C8 ; 0131 E7C8 ; unrecognised code 0132 E7C8 ; 0133 E7C8 BYTE0 ;unrecognised OSBYTE code 0134 E7C8 WORD0 ;unrecognised OSWORD code (C=1) 0135 E7C8 ; force 4 bytes on stack (making 4 before Preg, simulating a return link) 0136 E7C8 08 PHP ;N.B. non-zero byte (SEI mode) 0137 E7C9 08 PHP 0138 E7CA ; 0139 E7CA EXTSND ;entry point used by SOUND (return link still on stack) 0140 E7CA 68 PLA 0141 E7CB 68 PLA 0142 E7CC ; 0143 E7CC 20 68 F1 JSR SVOP ;offer to paged ROMs (N.B. X=SVBYTE or X=SVWORD) 0144 E7CF D0 05 BNE BADOSC ;[unrecognised OS call] 0145 E7D1 ; 0146 E7D1 ; recognised OS call 0147 E7D1 ; 0148 E7D1 A6 F0 LDX BYTEX ;replace X (corrupted by SVOP) 0149 E7D3 ; 0150 E7D3 4C BC E7 JMP OSRET 0151 E7D6 0152 E7D6 0153 E7D6 BADOSC ;bad OS call 0154 E7D6 28 PLP ;restore interrupt status 0155 E7D7 68 PLA ;restore code to return with 0156 E7D8 2C B7 D9 BIT FFBYT ;indicate call not recognised 0157 E7DB 60 RTS 0158 E7DC 0159 E7DC 0160 E7DC MSGON ;used by CFS 0161 E7DC ;Return EQ if messages off and not doing catalogue 0162 E7DC ;or during EXEC/SPOOL (during which messages cannot occur 0163 E7DC ;since this implies writing chars while within RDCH or WRCH) 0164 E7DC 0165 E7DC A5 EB LDA ESSEMA 0166 E7DE 30 32 BMI MSGONY ;Inside RDCH/WRCH -> msgs OFF 0167 E7E0 0168 E7E0 A9 08 LDAIM CATBIT 0169 E7E2 25 E2 AND CFSTAT 0170 E7E4 D0 04 BNE MSGONX ;Out with msgs set. 0171 E7E6 0172 E7E6 A9 88 LDAIM MONBIT 0173 E7E8 25 BB AND USFLGS 0174 E7EA 60 MSGONX RTS 0175 E7EB 0176 E7EB 0177 E7EB WORD ;OSWORD call 0178 E7EB ; uses: 0179 E7EB ; WORDX, WORDY (may be shared by sei-routines) 0180 E7EB ; JMILO, JMIHI (may be shared by sei-routines) 0181 E7EB ; 0182 E7EB 48 PHA 0183 E7EC 08 PHP ;save interrupt state 0184 E7ED 78 SEI ;**** DISABLE INTERRUPTS **** 0185 E7EE ; 0186 E7EE ; save A, X and Y 0187 E7EE ; 0188 E7EE 85 EF STA WORDA 0189 E7F0 86 F0 STX WORDX 0190 E7F2 84 F1 STY WORDY 0191 E7F4 ; 0192 E7F4 A2 08 LDXIM SVWORD ;code used if indirection taken 0193 E7F6 ; 0194 E7F6 ; check for user OSWORD call 0195 E7F6 ; 0196 E7F6 C9 E0 CMPIM &E0 0197 E7F8 B0 90 BCS WORDU ;[user OSWORD call - route thru USRVEC, C=1] 0198 E7FA ; 0199 E7FA ; not a user OSWORD call 0200 E7FA ; 0201 E7FA ; check for legal code 0202 E7FA ; 0203 E7FA C9 0E CMPIM WORDN 0204 E7FC B0 CA BCS WORD0 ;[unrecognised code] 0205 E7FE ; C=0 0206 E7FE ; 0207 E7FE ; recognised OSWORD call 0208 E7FE ; construct address of specific OSWORD routine 0209 E7FE ; 0210 E7FE ; C=0 0211 E7FE 69 44 ADCIM WORDT-BYTET:SHR: 1 0212 E800 ; C=0 0213 E800 ; 0214 E800 ; enter specific OSWORD routine 0215 E800 ; 0216 E800 0A ASLA ;prepare for Y := 2*code 0217 E801 ; C=0 0218 E801 90 90 BCC BYTE2 ;[ALWAYS jump, C=0 => OSWORD call] 0219 E803 0220 E803 0221 E803 PEEK ;read byte from I/O processor 0222 E803 20 15 E8 JSR PEKBYT ;sets X=0, Y=4 0223 E806 A1 F9 LDAIX PEEKLO-MCVER ;read byte 0224 E808 91 F0 STAIY WORDX ;save result 0225 E80A 60 RTS 0226 E80B 0227 E80B POKE ;write byte to I/O processor 0228 E80B 20 15 E8 JSR PEKBYT ;sets X=0, Y=4 0229 E80E B1 F0 LDAIY WORDX ;useful for POKE 0230 E810 81 F9 STAIX PEEKLO-MCVER ;write byte 0231 E812 MSGONY ;used by MSGON below 0232 E812 A9 00 LDAIM ZERO 0233 E814 60 RTS 0234 E815 0235 E815 PEKBYT ;used by PEEK and POKE 0236 E815 ; assumes Y=0, A=[LDAIY WORDX] 0237 E815 85 FA STA PEEKLO ;lo-IO address 0238 E817 C8 INY ;Y := 1 0239 E818 B1 F0 LDAIY WORDX 0240 E81A 85 FB STA PEEKHI ;hi-IO address 0241 E81C A0 04 LDYIM &04 ;generally useful 0242 E81E RVER ;return OS version number in X 0243 E81E A2 01 LDXIM MCVER ;generally useful 0244 E820 60 RTS 0245 E821 Acorn macro assembler Page 94 MOS46 OSWORD routines 0246 E821 0247 E821 VER ;print version number of OS 0248 E821 D0 FB BNE RVER 0249 E823 ; 0250 E823 00 BRK 0251 E824 F7 = FX0MSG 0252 E825 4F 53 20 = "OS " 0253 E828 31 = VERA 0254 E829 2E = "." 0255 E82A 32 = VERB 0256 E82B 30 = VERC 0257 E82C 00 = ZERO 0258 E82D 0259 E82D 0260 E82D NOTE ;add note to note buffer 0261 E82D ; ********************* 0262 E82D ; MAY ENABLE INTERRUPTS 0263 E82D ; ********************* 0264 E82D ; XY -> 8 bytes of info 0265 E82D ; C=1 0266 E82D ; X=SVWORD 0267 E82D ; Y=0 0268 E82D ; 0269 E82D [ $Tutu 0274 E82D | 0275 E82D C8 INY 0276 E82E B1 F0 LDAIY WORDX ;A := command type indicator (hi-byte of 1st argument) 0277 E830 C9 FF CMPIM &FF 0278 E832 ] 0279 E832 F0 59 BEQ SPEECH ;[speech command] 0280 E834 ; 0281 E834 C9 20 CMPIM &20 0282 E836 A2 08 LDXIM SVWORD ;in case EXTSND called 0283 E838 B0 90 BCS EXTSND ;[route command to paged ROM] 0284 E83A ; 0285 E83A ; sound command 0286 E83A ; 0287 E83A 88 DEY ;Y := 0 0288 E83B 20 C9 E8 JSR NOTEX ;C => flush, A = channel, Y := 1 0289 E83E 09 04 ORAIM &04 ;********** N.B. assumes BSND1=4 0290 E840 AA TAX ;X := (internal) sound bufferid 0291 E841 90 05 BCC NOTENF ;[do not flush channel] 0292 E843 ; C=1 0293 E843 ; flush channel 0294 E843 ; 0295 E843 ; C=1 0296 E843 20 AE E1 JSR PURGEX ;purge buffer 0297 E846 A0 01 LDYIM &01 ;restore Y 0298 E848 ; 0299 E848 NOTENF 0300 E848 20 C9 E8 JSR NOTEX ;C => release continue, A = chordcount-1 0301 E84B 85 FA STA NOTEWK 0302 E84D ; 0303 E84D 08 PHP ;needed in order to share code with BELL 0304 E84E A0 06 LDYIM &06 ;A := duration-lo 0305 E850 B1 F0 LDAIY WORDX 0306 E852 48 PHA 0307 E853 ; 0308 E853 A0 04 LDYIM &04 ;A := note-lo 0309 E855 B1 F0 LDAIY WORDX 0310 E857 48 PHA 0311 E858 ; 0312 E858 ; C => release continue 0313 E858 ; 0314 E858 A0 02 LDYIM &02 0315 E85A B1 F0 LDAIY WORDX ;A = envelope-lo 0316 E85C 2A ROLA ;rotate in release continue bit 0317 E85D 38 SEC 0318 E85E E9 02 SBCIM &02 ;envelope numbers start at 1 0319 E860 0A ASLA 0320 E861 0A ASLA ;rotate in 2 zero bits 0321 E862 05 FA ORA NOTEWK ;A := AEEE ERHH 0322 E864 ; 0323 E864 ; insert byte into buffer, waiting if necessary 0324 E864 ; 0325 E864 20 F8 E1 JSR WRITE 0326 E867 90 1E BCC NOTE2 ;[byte inserted] 0327 E869 ; 0328 E869 SPESC ;ESCAPE detected 0329 E869 68 PLA 0330 E86A 68 PLA 0331 E86B 28 PLP 0332 E86C ; 0333 E86C VDUST ;FX call to return VDU status 0334 E86C A6 D0 LDX STATS 0335 E86E ; 0336 E86E 60 RTS 0337 E86F 0338 E86F 0339 E86F ; 0340 E86F ;; ===== 0341 E86F ; BELL 0342 E86F ; ===== 0343 E86F ; 0344 E86F ; Add BELL to sound queue 0345 E86F ; 0346 E86F ; ENTRY:- No conditions 0347 E86F ; 0348 E86F ; EXIT:- A,X,Y Corrupted 0349 E86F ; Flags preserved 0350 E86F ; 0351 E86F BELL 0352 E86F 08 PHP 0353 E870 78 SEI 0354 E871 ; 0355 E871 ; try to add bell to sound channel queue 0356 E871 ; 0357 E871 AD 63 02 LDA BELLC 0358 E874 29 07 ANDIM &07 0359 E876 09 04 ORAIM &04 0360 E878 AA TAX ;force valid sound channel 0361 E879 ; 0362 E879 ; insert envelope/chord info 0363 E879 ; 0364 E879 AD 64 02 LDA BELLI 0365 E87C 20 B0 E4 JSR INSRT 0366 E87F ; 0367 E87F ; N.B. ignore return code 0368 E87F ; C=0 => inserted, C=1 => not inserted 0369 E87F ; if first INSRT failed then so will the following INSRTs 0370 E87F ; set to insert duration Acorn macro assembler Page 95 MOS46 OSWORD routines 0371 E87F ; 0372 E87F AD 66 02 LDA BELLD 0373 E882 48 PHA 0374 E883 ; 0375 E883 ; set to insert note 0376 E883 ; 0377 E883 AD 65 02 LDA BELLN 0378 E886 48 PHA 0379 E887 ; 0380 E887 NOTE2 ;buffer slot available 0381 E887 ; C=0 => inserted, C=1 => not inserted 0382 E887 ; 0383 E887 38 SEC 0384 E888 7E 00 08 RORAX MACTIV-BSND1 0385 E88B 30 17 BMI NOTE3 ;[ALWAYS JUMP] 0386 E88D ; 0387 E88D SPEECH ;SOUND -1,x,y,z command 0388 E88D ; Y=1 0389 E88D 08 PHP ;needed to share code with BELL 0390 E88E C8 INY ;Y := $02 0391 E88F B1 F0 LDAIY WORDX 0392 E891 48 PHA 0393 E892 ; 0394 E892 C8 INY ;Y := $03 0395 E893 B1 F0 LDAIY WORDX 0396 E895 48 PHA 0397 E896 ; 0398 E896 A0 00 LDYIM ZERO 0399 E898 B1 F0 LDAIY WORDX 0400 E89A A2 08 LDXIM BSPCH 0401 E89C 20 F8 E1 JSR WRITE ;insert first byte into buffer 0402 E89F B0 C8 BCS SPESC ;[escape detected] 0403 E8A1 ; 0404 E8A1 ; C=0 0405 E8A1 ; 0406 E8A1 6E D7 02 ROR SPSTAT ;indicate speech buffer non-empty 0407 E8A4 ; 0408 E8A4 NOTE3 ;add note and duration (ignored if first byte not inserted) 0409 E8A4 68 PLA 0410 E8A5 20 B0 E4 JSR INSRT ;add note data to queue 0411 E8A8 68 PLA 0412 E8A9 20 B0 E4 JSR INSRT ;add duration info to queue 0413 E8AC 28 PLP 0414 E8AD 60 RTS 0415 E8AE 0416 E8AE 0417 E8AE NVLP ;define envelope shape 0418 E8AE ; A := envelope number 0419 E8AE ; C=1 0420 E8AE ; 0421 E8AE E9 01 SBCIM &01 ;subtract 1 from envelope number 0422 E8B0 ; 0423 E8B0 ; envelope number forced into range 0 to 15 (1->0, 2->1 ... 16->15) 0424 E8B0 ; (0 forced to 255, which will have the same effect as 15) 0425 E8B0 ; 0426 E8B0 0A ASLA 0427 E8B1 0A ASLA 0428 E8B2 0A ASLA 0429 E8B3 0A ASLA ;envelope number := (envelope number - 1) * 16 0430 E8B4 09 0F ORAIM ENVSIZ-&01 ;N.B. ENVSIZ must be 16! 0431 E8B6 AA TAX ;X -> end of envelope (relative to ENVEL) 0432 E8B7 ; 0433 E8B7 ; copy envelope definition to envelope slot 0434 E8B7 ; padding to 16 bytes with zeroes 0435 E8B7 ; 0436 E8B7 A9 00 LDAIM ZERO ;padding value 0437 E8B9 A0 10 LDYIM ENVSIZ 0438 E8BB ; 0439 E8BB NVLP1 0440 E8BB C0 0E CPYIM ENVSIZ-&02 0441 E8BD B0 02 BCS NVLP2 ;[still padding] 0442 E8BF ; 0443 E8BF B1 F0 LDAIY WORDX 0444 E8C1 NVLP2 0445 E8C1 9D C0 08 STAAX ENVEL 0446 E8C4 CA DEX 0447 E8C5 88 DEY 0448 E8C6 D0 F3 BNE NVLP1 0449 E8C8 ; 0450 E8C8 60 RTS 0451 E8C9 0452 E8C9 NOTEX ;extract byte info from offset Y of vector 0453 E8C9 B1 F0 LDAIY WORDX 0454 E8CB C9 10 CMPIM &10 ;C => flag (flush or release continue) 0455 E8CD 29 03 ANDIM &03 0456 E8CF C8 INY ;step Y to next slot 0457 E8D0 60 RTS 0458 E8D1 0459 E8D1 RITM ;read interval time 0460 E8D1 A2 0F LDXIM STPW+&5-TIME 0461 E8D3 D0 03 BNE RTM ;[ALWAYS jump] 0462 E8D5 ; NEVER fall thru 0463 E8D5 RATM ;read absolute time 0464 E8D5 AE 83 02 LDX TIMESW 0465 E8D8 RTM 0466 E8D8 A0 04 LDYIM &04 0467 E8DA RTM1 0468 E8DA BD 8D 02 LDAAX TIME -&05 0469 E8DD 91 F0 STAIY WORDX 0470 E8DF E8 INX 0471 E8E0 88 DEY 0472 E8E1 10 F7 BPL RTM1 0473 E8E3 WTM0 0474 E8E3 60 RTS 0475 E8E4 0476 E8E4 WITM ;write interval time, C=1 0477 E8E4 A9 0F LDAIM STPW+&5-TIME 0478 E8E6 D0 06 BNE WTM ;[ALWAYS jump] 0479 E8E8 ; NEVER fall thru 0480 E8E8 WATM ;write absolute time 0481 E8E8 AD 83 02 LDA TIMESW 0482 E8EB 49 0F EORIM &0F ;N.B. Z=0 0483 E8ED 18 CLC ;indicate WATM entry 0484 E8EE WTM 0485 E8EE 48 PHA ;save TIMESW for WATM entry 0486 E8EF AA TAX 0487 E8F0 A0 04 LDYIM &04 0488 E8F2 WTM1 0489 E8F2 B1 F0 LDAIY WORDX 0490 E8F4 9D 8D 02 STAAX TIME -&05 0491 E8F7 E8 INX Acorn macro assembler Page 96 MOS46 OSWORD routines 0492 E8F8 88 DEY 0493 E8F9 10 F7 BPL WTM1 0494 E8FB 68 PLA 0495 E8FC B0 E5 BCS WTM0 ;[not WATM entry, do not reset TIMESW] 0496 E8FE ; WATM entry, reset TIMESW 0497 E8FE 8D 83 02 STA TIMESW 0498 E901 60 RTS 0499 E902 0500 E902 RDLN ;read input buffer 0501 E902 ; ****************** 0502 E902 ; ENABLES INTERRUPTS 0503 E902 ; ****************** 0504 E902 ;**************** 0505 E902 ;variables: 0506 E902 ;zero page: RDLNX, RDLNY (contiguous) 0507 E902 ;other page: RDLNN, RDLNLC, RDLNHC (contiguous) 0508 E902 ;**************** 0509 E902 ;Called with Y and X the high and low addresses of the information 0510 E902 ;describing what is to be done. The bytes in order are: 0511 E902 ;lsb address of buffer 0512 E902 ;msb address of buffer 0513 E902 ;maximum length allowed 0514 E902 ;minimum character value to be stored in buffer 0515 E902 ;maximum character value to be stored in buffer 0516 E902 ;Return when escape is pressed or seen with CARRY SET 0517 E902 ;Return after CR (which is always stored) with CARRY CLEAR 0518 E902 ;Always returns with Y the number of characters in the buffer 0519 E902 ;DEL,ESC and NAK are always processed 0520 E902 ;**** NOTE **** 0521 E902 ; if the 'other page' variables are put into page zero 0522 E902 ; this routine can be made ~10 bytes shorter. 0523 E902 ; however, an extra pointer variable in page zero would 0524 E902 ; then be required. 0525 E902 ; this routine enables interrupts 0526 E902 ; ********** 0527 E902 ; copy 'other page' values 0528 E902 0529 E902 A0 04 LDYIM &04 0530 E904 BUFFPR 0531 E904 B1 F0 LDAIY WORDX 0532 E906 99 B1 02 STAAY RDLNN -&02 ;N.B. offset of -02 0533 E909 88 DEY 0534 E90A C0 02 CPYIM &02 0535 E90C B0 F6 BCS BUFFPR ;[more arguments to copy] 0536 E90E ; 0537 E90E ; C=0, Y=1 0538 E90E ; copy buffer pointer 0539 E90E ; 0540 E90E B1 F0 LDAIY WORDX ;hi-byte 0541 E910 85 E9 STA RDLNBF +&01 0542 E912 88 DEY ;Y := 0 0543 E913 8C 69 02 STY LINES ;reset page mode page origin 0544 E916 B1 F0 LDAIY WORDX ;lo-byte 0545 E918 85 E8 STA RDLNBF +&00 0546 E91A ; 0547 E91A ; C=0, Y=0 0548 E91A ; 0549 E91A 58 CLI ;**** ENABLE INTERRUPTS **** 0550 E91B 90 07 BCC BUFFIN ;[ALWAYS JUMP] 0551 E91D ; 0552 E91D ; NEVER fall thru 0553 E91D 0554 E91D 0555 E91D A9 07 BUFEXH LDAIM BEL ;reflect bell to indicate error 0556 E91F 88 BUFIGN DEY ;adjust buffer pointer to ignore character 0557 E920 C8 BUFECH INY ;increment count of characters in buffer 0558 E921 ; echo character 0559 E921 BFWRCH 0560 E921 20 EE FF JSR OSWRCH 0561 E924 ; 0562 E924 BUFFIN ;main loop 0563 E924 20 E0 FF JSR OSRDCH ;read a character 0564 E927 B0 49 BCS BUFESC ;[escape detected] 0565 E929 AA TAX 0566 E92A AD 7C 02 LDA WRCHSW 0567 E92D 6A RORA 0568 E92E 6A RORA 0569 E92F 8A TXA 0570 E930 B0 05 BCS BUFNQ ;[output does not include VDU] 0571 E932 ; 0572 E932 ; output includes VDU 0573 E932 ; 0574 E932 ; 0575 E932 AE 6A 02 LDX QPOSN 0576 E935 D0 EA BNE BFWRCH ;[VDU queueing, reflect character] 0577 E937 ; 0578 E937 ; output does not include VDU 0579 E937 ; 0580 E937 BUFNQ ;VDU not queueing 0581 E937 C9 7F CMPIM MDEL 0582 E939 D0 07 BNE BUFNXA ;[not DEL] 0583 E93B ; 0584 E93B ; DEL received 0585 E93B ; 0586 E93B C0 00 CPYIM ZERO 0587 E93D F0 E5 BEQ BUFFIN ;[delete at start of line] 0588 E93F ; 0589 E93F ; C=1, A=DEL 0590 E93F 88 DEY 0591 E940 B0 DF BCS BFWRCH ;[ALWAYS jump, reflect DEL and get next char] 0592 E942 ; NEVER fall thru 0593 E942 0594 E942 BUFNXA 0595 E942 C9 15 CMPIM MNAK 0596 E944 D0 0D BNE BUFNXB ;[not DEL or NAK] 0597 E946 98 TYA 0598 E947 F0 DB BEQ BUFFIN ;[cancel at start of line, ignore] 0599 E949 ; 0600 E949 ; cancel with non-zero count of characters 0601 E949 ; 0602 E949 A9 7F LDAIM MDEL 0603 E94B ; 0604 E94B BUFCNL ;output DEL for each character in the buffer 0605 E94B 20 EE FF JSR OSWRCH 0606 E94E 88 DEY 0607 E94F D0 FA BNE BUFCNL ;[more characters to delete] 0608 E951 F0 D1 BEQ BUFFIN ;[ALWAYS jump, reached start of line] 0609 E953 ; NEVER fall thru 0610 E953 ; 0611 E953 BUFNXB ;check for ESC explicitly in case machine in non ESC mode 0612 E953 ;CMPIM ESC Acorn macro assembler Page 97 MOS46 OSWORD routines 0613 E953 ;BEQ BUFESC ;[ESC, N.B. C = 1] 0614 E953 ; not DEL, NAK or ESC 0615 E953 91 E8 STAIY RDLNBF ;store character in buffer 0616 E955 C9 0D CMPIM MCR 0617 E957 F0 13 BEQ BUFEND ;[CR detected, exit indicating CR received] 0618 E959 CC B3 02 CPY RDLNN 0619 E95C B0 BF BCS BUFEXH ;[buffer exhausted, do not echo character] 0620 E95E ; 0621 E95E ; buffer not exhausted 0622 E95E ; 0623 E95E CD B4 02 CMP RDLNLC 0624 E961 90 BC BCC BUFIGN ;[character < lo-character] 0625 E963 CD B5 02 CMP RDLNHC 0626 E966 F0 B8 BEQ BUFECH ;[character = hi-character, so accept] 0627 E968 90 B6 BCC BUFECH ;[character < hi-character, so accept] 0628 E96A B0 B3 BCS BUFIGN ;[ALWAYS jump, character > hi-character, so ignore] 0629 E96C ; NEVER fall thru 0630 E96C 0631 E96C BUFEND ;read line successful 0632 E96C ; echo LF CR 0633 E96C 20 E7 FF JSR OSNEWL 0634 E96F 20 7E E5 JSR JMINET ;N.B. assumes NTCR has value $0D 0635 E972 ; 0636 E972 BUFESC ;escape exit (C=1) 0637 E972 A5 FF LDA ESCFLG 0638 E974 2A ROLA ;C=0 => no escape, C=1 => escape 0639 E975 60 RTS 0640 E976 0641 E976 0642 E976 SPRINT ;change printer selection (*FX 5) 0643 E976 ; allow interrupts during wait, this means that: 0644 E976 ; (a) the printer can purge AND/OR 0645 E976 ; (b) escape can be detected 0646 E976 58 CLI 0647 E977 78 SEI 0648 E978 24 FF BIT ESCFLG 0649 E97A 30 30 BMI SPR0 ;[escape detected] 0650 E97C 2C D2 02 BIT PFLAG 0651 E97F 10 F5 BPL SPRINT ;[printer busy] 0652 E981 ; mention change of printer to print routines 0653 E981 20 A4 E1 JSR UPTX ;N.B. Y corrupted 0654 E984 ; interrupts may have corrupted BYTEX and BYTEY, so restore them 0655 E984 A0 00 LDYIM ZERO ;Y altered by call to UPTX 0656 E986 84 F1 STY BYTEY 0657 E988 ; N.B. X reset at SETVX 0658 E988 ; N.B. A not altered since SPRINT 0659 E988 ; 0660 E988 V2B156 ;convert FX 1,5,6 to FX 241,245,246 0661 E988 09 F0 ORAIM &F0 0662 E98A D0 0E BNE SETVX ;[ALWAYS jump] 0663 E98C ; 0664 E98C ARRPT ;A = $0C, set auto-repeat repeat count 0665 E98C ; N.B. previous instruction was LDX 0666 E98C ; C=1 0667 E98C D0 07 BNE ARRPT1 ;[X<>0 => do not set defaults] 0668 E98E ; set defaults 0669 E98E A2 32 LDXIM DAUTOD 0670 E990 8E 54 02 STX FARSET 0671 E993 A2 08 LDXIM DAUTOP 0672 E995 ARRPT1 ;A = $0C, C=1 0673 E995 ARDLY ;A = $0B, C=1, set auto-repeat delay count (0 => disable) 0674 E995 69 CF ADCIM FARSET-VBASE-&01-&0B- 233 ;$01 for carry, $0B for FX base 0675 E997 ; 0676 E997 V2B34 ;C=1 0677 E997 18 CLC 0678 E998 69 E9 ADCIM 233 ;convert FX 3&4 to FX 236,237 0679 E99A ; 0680 E99A SETVX 0681 E99A 86 F0 STX BYTEX 0682 E99C ; 0683 E99C SETV ;set variable 0684 E99C ; A = FX code 0685 E99C ; X = value 0686 E99C ; Y = mask 0687 E99C A8 TAY ;Y := FX code 0688 E99D B9 90 01 LDAAY VBASE ;A := old value 0689 E9A0 AA TAX ;X := old value 0690 E9A1 25 F1 AND BYTEY ;apply mask 0691 E9A3 45 F0 EOR BYTEX ;apply value 0692 E9A5 99 90 01 STAAY VBASE ;store new value 0693 E9A8 B9 91 01 LDAAY VBASE+&01 0694 E9AB A8 TAY ;return following byte 0695 E9AC SPR0 0696 E9AC 60 RTS 0697 E9AD 0698 E9AD 0699 E9AD BAUDS ;baud rate table (N.B. RS423 bit set cos of B9600 definition) 0700 E9AD BUFTYP ;**** WARNING - SUBTLE WAY TO DETECT SOUND BUFFERS **** 0701 E9AD ; (*) = sound buffer 0702 E9AD 0080 SOUNDB * &80 0703 E9AD 64 = B9600 ;default baud rate / buffer 0 0704 E9AE 7F = &7F ;75 111 111 / buffer 1 0705 E9AF 5B = &5B ;150 011 011 / buffer 2 0706 E9B0 6D = &6D ;300 101 101 / buffer 3 0707 E9B1 C9 = &49+SOUNDB ;1200 001 001 / buffer 4 (*) 0708 E9B2 F6 = &76+SOUNDB ;2400 110 110 / buffer 5 (*) 0709 E9B3 D2 = &52+SOUNDB ;4800 010 010 / buffer 6 (*) 0710 E9B4 E4 = B9600+SOUNDB ;9600 100 100 / buffer 7 (*) 0711 E9B5 40 = &40 ;19200 000 000 / buffer 8 0712 E9B6 0713 E9B6 0714 E9B6 WFVS ;wait for vertical sync 0715 E9B6 AD 40 02 LDA CYCLE 0716 E9B9 WFVS1 ;wait for CYCLE to alter 0717 E9B9 58 CLI ;must enable interrupts to allow CYCLE to operate 0718 E9BA ; this should give the user control immediately after VSYNC 0719 E9BA ; interrupt occurred 0720 E9BA 78 SEI 0721 E9BB CD 40 02 CMP CYCLE 0722 E9BE F0 F9 BEQ WFVS1 ;[CYCLE not altered] 0723 E9C0 ; 0724 E9C0 ; share exit with read VDU variable 0725 E9C0 ; 0726 E9C0 VDUVAR ;read VDU variables 0727 E9C0 BC 01 03 LDYAX VARBLE+&01 0728 E9C3 BD 00 03 LDAAX VARBLE+&00 0729 E9C6 AA TAX 0730 E9C7 60 RTS 0731 E9C8 0732 E9C8 0733 E9C8 RSOFT ;reset soft keys Acorn macro assembler Page 98 MOS46 OSWORD routines 0734 E9C8 ; initialise soft key pointers 0735 E9C8 ; exits with X=0 (used by RESET) 0736 E9C8 ; ********** MUST NOT CORRUPT Y (SEE RESET) ********** 0737 E9C8 A9 10 LDAIM NSOFTK 0738 E9CA 8D 84 02 STA USKFLG ;signal soft keys inconsistent 0739 E9CD A2 00 LDXIM ZERO 0740 E9CF STTA ;set soft key buffer pointers, including the two end pointers 0741 E9CF 9D 00 0B STAAX SKPTR 0742 E9D2 E8 INX 0743 E9D3 D0 FA BNE STTA 0744 E9D5 ; X=0 0745 E9D5 8E 84 02 STX USKFLG ;USKFLG set to zero when soft keys consistent 0746 E9D8 ; X=0 0747 E9D8 60 RTS 0748 E9D9 0749 E9D9 0750 E9D9 LNK MOS48 0001 E9D9 0002 E9D9 ; MOS48 0003 E9D9 TTL MOS48 Miscellaneous routines 0004 E9D9 OPT MOS48 Acorn macro assembler Page 99 MOS48 Miscellaneous routines 0005 E9D9 ;(c) 1981 ACORN Computers Limited 0006 E9D9 ;BBC Microcomputer Machine Operating System (MOS) 0007 E9D9 0008 E9D9 ;Change record: 0009 E9D9 ;01/03/82 PB GSINTC CR indication 0010 E9D9 ;05/01/82 PB Change from printer claim to RS423 0011 E9D9 0012 E9D9 ;Author(s): 0013 E9D9 ;PB Paul Bond 0014 E9D9 0015 E9D9 0016 E9D9 TTL MOS48 External interface routines 0017 E9D9 OPT OPNEWP Acorn macro assembler Page 100 MOS48 External interface routines 0018 E9D9 0019 E9D9 0020 E9D9 ; external interfaces 0021 E9D9 0022 E9D9 0023 E9D9 MOSTST 0024 E9D9 ; C=0 => do not set LEDs, C=1 => set LEDs 0025 E9D9 ; N.B. must not corrupt X (see WRCH print section) 0026 E9D9 08 PHP ;push interrupt state 0027 E9DA 78 SEI 0028 E9DB ; test for ESCAPE 0029 E9DB A9 40 LDAIM &40 0030 E9DD 20 EA E9 JSR LEDSON ;conditionally set LEDs and test escape condition 0031 E9E0 30 05 BMI SHIFTX ;[escape pending, simulate SHIFT without CTRL] 0032 E9E2 ; 0033 E9E2 18 CLC ;indicate test ctrl/shift entry point 0034 E9E3 B8 CLV 0035 E9E4 20 68 F0 JSR JMIKEY 0036 E9E7 ; 0037 E9E7 SHIFTX ;b7(A) => CTRL, b6(A) => SHIFT 0038 E9E7 28 PLP 0039 E9E8 2A ROLA ;C => CTRL, MI => SHIFT 0040 E9E9 60 RTS 0041 E9EA 0042 E9EA 0043 E9EA LEDSON ;turn LEDs on 0044 E9EA ; **************************************** 0045 E9EA ; MUST BE ENTERED WITH INTERRUPTS DISABLED 0046 E9EA ; **************************************** 0047 E9EA ; C=0 => do not turn LEDs on, C=1 => turn LEDs on 0048 E9EA ; returns status of BIT ESCFLG 0049 E9EA 90 09 BCC LEDS0 ;[do not turn LEDs on] 0050 E9EC ; set both LEDs (indicating a wait state) 0051 E9EC A0 07 LDYIM &07 0052 E9EE 8C 40 FE STY PBQ ;PBQ:=$07 0053 E9F1 88 DEY 0054 E9F2 8C 40 FE STY PBQ ;PBQ:=$06 0055 E9F5 LEDS0 ;set escape status 0056 E9F5 24 FF BIT ESCFLG 0057 E9F7 60 RTS 0058 E9F8 0059 E9F8 CREG ;called by VDU module 0060 E9F8 ; interrupts are disabled in order that a spurious 0061 E9F8 ; ADC interrupt does not occur 0062 E9F8 08 PHP ;save interrupt state 0063 E9F9 78 SEI 0064 E9FA 8D 40 FE STA PBQ ;set addressable latch value 0065 E9FD 28 PLP ;restore interrupt state 0066 E9FE 60 RTS 0067 E9FF 0068 E9FF 0069 E9FF VP0 ;program vidproc register 0 (FX entry) 0070 E9FF 8A TXA 0071 EA00 MVPRC0 ;set video processor register 0 0072 EA00 08 PHP 0073 EA01 78 SEI ;**** DISABLE INTERRUPTS **** 0074 EA02 8D 48 02 STA VPREGA ;update RAM image 0075 EA05 8D 20 FE STA VPROC0 ;update ULA 0076 EA08 AD 53 02 LDA FLMRK 0077 EA0B 8D 51 02 STA FLCNT ;reset flash count to mark value 0078 EA0E 28 PLP 0079 EA0F 60 RTS 0080 EA10 0081 EA10 VP1 ;program vidproc register 1 (FX entry) 0082 EA10 8A TXA 0083 EA11 MVPRC1 ;set video processor register 1 0084 EA11 49 07 EORIM &07 ;adjust value accounting for ULA bug 0085 EA13 08 PHP 0086 EA14 78 SEI ;**** DISABLE INTERRUPTS **** 0087 EA15 8D 49 02 STA VPREGB ;update RAM image 0088 EA18 8D 21 FE STA VPROC1 ;update ULA 0089 EA1B 28 PLP 0090 EA1C 60 RTS 0091 EA1D 0092 EA1D 0093 EA1D GSINTC ;intialise for string access (read item) 0094 EA1D 0095 EA1D 18 CLC 0096 EA1E GSINTS ;initialise for string access (read item/rest of line) 0097 EA1E 66 E4 ROR KQUOTE 0098 EA20 20 3A E0 JSR SKIPSP ;A := LDAIY WORK 0099 EA23 C8 INY ;skip possible opening quote 0100 EA24 C9 22 CMPIM DQUOTE 0101 EA26 F0 02 BEQ CLIOQ ;[opening quote, C=1] 0102 EA28 ; no opening quote 0103 EA28 88 DEY ;adjust for erroneous skip 0104 EA29 18 CLC 0105 EA2A CLIOQ 0106 EA2A 66 E4 ROR KQUOTE ;PL => not a quoted string, MI => a quoted string 0107 EA2C C9 0D CMPIM MCR ;return EQ => end-of-string, NEQ => not end-of-string 0108 EA2E 60 RTS 0109 EA2F ; 0110 EA2F GSREAD ;read character from string 0111 EA2F 0112 EA2F ; reset key mask (used in top bit option) 0113 EA2F A9 00 LDAIM ZERO 0114 EA31 GSRA ;used by |! option, entered with A=$80 0115 EA31 85 E5 STA KMASK ;KMASK := 0000 0000 (or KMASK := 1000 0000) 0116 EA33 B1 F2 LDAIY WORK ;A := next character 0117 EA35 C9 0D CMPIM MCR 0118 EA37 D0 06 BNE KEYNCR ;[not CR] 0119 EA39 ; CR found, C=1 0120 EA39 ; check that string did not open with double quote 0121 EA39 24 E4 BIT KQUOTE 0122 EA3B 30 52 BMI BADSTR ;[opening double quote without closing double quote] 0123 EA3D 10 1B BPL GSR1 ;[ALWAYS jump, return C=1 and EQ=>CR] 0124 EA3F KEYNCR ;character not CR 0125 EA3F C9 20 CMPIM SPACE 0126 EA41 90 4C BCC BADSTR ;[control character in string] 0127 EA43 D0 06 BNE KEYNSP ;[not space] 0128 EA45 ; space character 0129 EA45 24 E4 BIT KQUOTE 0130 EA47 30 40 BMI GSR0 ;[in quoted string] 0131 EA49 50 0F BVC GSR1 ;[not in quoted string and not read line, so space is terminator] 0132 EA4B ; fall thru, space will be returned as a valid character 0133 EA4B KEYNSP 0134 EA4B C9 22 CMPIM DQUOTE 0135 EA4D D0 10 BNE KEYNDQ ;[not double quote] 0136 EA4F ; double quote found 0137 EA4F 24 E4 BIT KQUOTE 0138 EA51 10 36 BPL GSR0 ;[not in quoted string] Acorn macro assembler Page 101 MOS48 External interface routines 0139 EA53 ; in quoted string 0140 EA53 C8 INY 0141 EA54 B1 F2 LDAIY WORK ;get next character 0142 EA56 C9 22 CMPIM DQUOTE 0143 EA58 F0 2F BEQ GSR0 ;["" found in quoted string] 0144 EA5A GSR1 ;closing quote of quoted string 0145 EA5A 20 3A E0 JSR SKIPSP ;skip spaces 0146 EA5D 38 SEC 0147 EA5E 60 RTS 0148 EA5F 0149 EA5F KEYNDQ ;character not CR or " 0150 EA5F C9 7C CMPIM "|" ;check for pseudo-escape 0151 EA61 D0 26 BNE GSR0 ;[valid string character] 0152 EA63 ; 0153 EA63 C8 INY 0154 EA64 B1 F2 LDAIY WORK 0155 EA66 C9 7C CMPIM "|" 0156 EA68 F0 1F BEQ GSR0 ;[|| found] 0157 EA6A ; 0158 EA6A C9 22 CMPIM DQUOTE 0159 EA6C F0 1B BEQ GSR0 ;[|" found] 0160 EA6E ; 0161 EA6E C9 21 CMPIM "!" 0162 EA70 D0 05 BNE KEYNPL ;[not |!] 0163 EA72 ; C=1 0164 EA72 ; |! found - top bit option 0165 EA72 C8 INY ;step to next character 0166 EA73 ; C=1 0167 EA73 A9 80 LDAIM &80 ;KMASK := 1000 0000 0168 EA75 D0 BA BNE GSRA ;[ALWAYS jump, get next character reseting key mask] 0169 EA77 ; NEVER fall thru 0170 EA77 0171 EA77 KEYNPL ;check for control character 0172 EA77 C9 20 CMPIM SPACE 0173 EA79 90 14 BCC BADSTR ;[string contains a control character] 0174 EA7B ; convert to CTRL character 0175 EA7B C9 3F CMPIM "?" 0176 EA7D F0 08 BEQ KEYDEL 0177 EA7F 20 BF EA JSR CTRLCH 0178 EA82 ; fall thru with adjusted character 0179 EA82 2C B7 D9 BIT FFBYT ;indicate character was escaped 0180 EA85 70 03 BVS GSRX ;[ALWAYS jump] 0181 EA87 ; 0182 EA87 KEYDEL ;|? 0183 EA87 A9 7F LDAIM MDEL 0184 EA89 ; 0185 EA89 GSR0 ;valid character 0186 EA89 B8 CLV 0187 EA8A ; 0188 EA8A GSRX ;exit with valid character 0189 EA8A ; rotate in selected top bit 0190 EA8A C8 INY ;skip to next character 0191 EA8B 05 E5 ORA KMASK ;test character for filing system applications 0192 EA8D 18 CLC 0193 EA8E ; C=0, V=0 => not escaped, V=1 => escaped 0194 EA8E 60 RTS 0195 EA8F 0196 EA8F 0197 EA8F 0198 EA8F BADSTR 0199 EA8F 00 BRK ;report error 'Bad string' 0200 EA90 FD = BADST 0201 EA91 42 61 64 = "Bad string" 0202 EA9B 00 = ZERO ;end of message 0203 EA9C 0204 EA9C 0205 EA9C SHIFT ;perform shift inversion 0206 EA9C ; 0207 EA9C ; check for '0' character explicitly 0208 EA9C ; 0209 EA9C C9 30 CMPIM "0" 0210 EA9E F0 1E BEQ SHIFT0 ;[character is '0', shift '0' is '0', no action] 0211 EAA0 0212 EAA0 ; convert characters in range ['A',DEL) 0213 EAA0 ; 0214 EAA0 C9 40 CMPIM AT 0215 EAA2 F0 1A BEQ SHIFT0 ;[AT, no action] 0216 EAA4 90 12 BCC SHIFT1 ;[ch= 'A' 0219 EAA6 ; 0220 EAA6 C9 7F CMPIM MDEL 0221 EAA8 F0 14 BEQ SHIFT0 ;[ch=DEL, no action] 0222 EAAA B0 10 BCS SHFLIP ;[ch>DEL, is softkey code] 0223 EAAC ; 0224 EAAC ; 'A' <= character < DEL 0225 EAAC ; 0226 EAAC CTRLSK ;used by CTRLCH for CTRL/softkey 0227 EAAC 49 30 EORIM &30 ;flip bit to effect shift (N.B. EORIM $10 later) 0228 EAAE ; 0229 EAAE ; N.B. this has mapped '_' to $6F and POUND to $50 0230 EAAE ; swop underline and pound characters 0231 EAAE ; 0232 EAAE C9 6F CMPIM &6F ;i.e. mapped '_' 0233 EAB0 F0 04 BEQ SHIFT2 ;[underline character] 0234 EAB2 C9 50 CMPIM &50 ;i.e. mapped POUND (not altered by EORIM $20 anyway) 0235 EAB4 D0 02 BNE SHIFT1 ;[neither underline nor pound character] 0236 EAB6 ; 0237 EAB6 SHIFT2 ;swop underline and pound characters 0238 EAB6 49 1F EORIM &1F 0239 EAB8 ; 0240 EAB8 SHIFT1 0241 EAB8 0242 EAB8 ; convert characters above '!' 0243 EAB8 ; 0244 EAB8 C9 21 CMPIM "!" 0245 EABA 90 02 BCC SHIFT0 ;[ch<'!', no action] 0246 EABC ; 0247 EABC ; '!' <= ch < AT 0248 EABC ; 0249 EABC SHFLIP 0250 EABC 49 10 EORIM &10 ;$80..$8F -> $90..$9F and vice-versa 0251 EABE 0252 EABE SHIFT0 0253 EABE 60 RTS 0254 EABF 0255 EABF 0256 EABF CTRLCH ;compute CTRL version of character 0257 EABF C9 7F CMPIM MDEL 0258 EAC1 F0 0E BEQ CTRL0 ;[CTRL/DEL = DEL] 0259 EAC3 B0 E7 BCS CTRLSK ;[top bit set, therefore softkey needing EORIM $20] Acorn macro assembler Page 102 MOS48 External interface routines 0260 EAC5 0261 EAC5 ; pound & underline 0262 EAC5 ; 0263 EAC5 C9 60 CMPIM POUND ;make CTRL/pound = CTRL/underline 0264 EAC7 D0 02 BNE CTRL1 ;[not pound character] 0265 EAC9 A9 5F LDAIM "_" ;substitute underline for pound 0266 EACB CTRL1 0267 EACB 0268 EACB [ FALSE=0 0274 EACB ] 0275 EACB 0276 EACB [ FALSE=0 0282 EACB ] 0283 EACB 0284 EACB C9 40 CMPIM AT 0285 EACD 90 02 BCC CTRL4 ;[character < AT so do not convert] 0286 EACF ; AT <= character < DEL, so convert 0287 EACF 29 1F ANDIM &1F ;convert to ctrl value 0288 EAD1 CTRL4 0289 EAD1 0290 EAD1 CTRL0 0291 EAD1 60 RTS 0292 EAD2 0293 EAD2 [ FALSE=0 0296 EAD2 ] 0297 EAD2 0298 EAD2 0299 EAD2 SLBOOT ;'/!BOOT' auto-boot string 0300 EAD2 2F 21 42 = "/!BOOT" 0301 EAD8 0D = MCR 0302 EAD9 0303 EAD9 0304 EAD9 BREAK ;conditionally intercept BREAK 0305 EAD9 ; type of interception is in C 0306 EAD9 AD 87 02 LDA BREAKI 0307 EADC 49 4C EORIM &4C 0308 EADE D0 13 BNE BREAK0 ;[not a JMP instruction] 0309 EAE0 4C 87 02 JMP BREAKI 0310 EAE3 0311 EAE3 0312 EAE3 TV ;alter TV characteristics 0313 EAE3 AD 90 02 LDA VERTIC 0314 EAE6 8E 90 02 STX VERTIC ;vertical height adjust 0315 EAE9 AA TAX ;X := old state 0316 EAEA 98 TYA 0317 EAEB 29 01 ANDIM &01 0318 EAED AC 91 02 LDY INTERL ;Y := old state 0319 EAF0 8D 91 02 STA INTERL ;interlace invert 0320 EAF3 BREAK0 0321 EAF3 60 RTS 0322 EAF4 0323 EAF4 0324 EAF4 WFRED 0325 EAF4 98 TYA 0326 EAF5 9D 00 FC STAAX FRED 0327 EAF8 60 RTS 0328 EAF9 0329 EAF9 WJIM 0330 EAF9 98 TYA 0331 EAFA 9D 00 FD STAAX JIM 0332 EAFD 60 RTS 0333 EAFE 0334 EAFE WSHEIL 0335 EAFE 98 TYA 0336 EAFF 9D 00 FE STAAX SHEIL 0337 EB02 60 RTS 0338 EB03 0339 EB03 0340 EB03 LNK MOS52 0001 EB03 0002 EB03 ; MOS52 0003 EB03 TTL MOS52 Sound generator 0004 EB03 OPT MOS52 Acorn macro assembler Page 103 MOS52 Sound generator 0005 EB03 ;(c) 1981 ACORN Computers Limited 0006 EB03 ;BBC Microcomputer Machine Operating System (MOS) 0007 EB03 ;Change record: 0008 EB03 ;Prototype version 14/1/82 0009 EB03 ;Author(s): 0010 EB03 ;PBM Peter Miller 0011 EB03 ;Internal variable allocation $0800 to $08C0 0012 EB03 08C0 ENV * ENVEL ;envelope table 16 bytes per envelope 0013 EB03 0804 ATTN * SNDWRK+&04 ;current attenuation 0014 EB03 0808 EPERD * ATTN +&04 ;current envelope period 0015 EB03 080C SNOTE * EPERD +&04 ;base note 0016 EB03 0810 NPERD * SNOTE +&04 ;the current frequency envelope period 0-3 0017 EB03 0814 NCONT * NPERD +&04 ;number of ticks left in current frequency period 0018 EB03 0818 DUR * NCONT +&04 ;remaining number of ticks in the current note 0019 EB03 081C DRDIV * DUR +&04 ;division of 1/100 sewc to 1/20 sec 0020 EB03 0820 ENVLP * DRDIV +&04 ;current envelope ( TIMES 16) 0021 EB03 0824 SCONT * ENVLP +&04 ;number of 1/100th secs before next envelope tick 0022 EB03 0828 WAIT * SCONT +&04 ;channel waiting for sWATGO flag 0023 EB03 082C OLDNTE * WAIT +&04 ;current note in chip 0024 EB03 0830 NTADD * OLDNTE +&04 ;current offset from base note 0025 EB03 0026 EB03 0027 EB03 0838 NOWAT * NTADD +&08 ;number of other channels required for chord 0028 EB03 0839 ATINC * NOWAT +&01 ;current rate of attn change 0029 EB03 083A PEAK * ATINC +&01 ;peak of amplitude envelope 0030 EB03 083B WATGO * PEAK +&01 ;flag <>0 => play chord 0031 EB03 083C FRACT * WATGO +&01 ;fractional part of current note 0032 EB03 083D PRDL * FRACT +&01 ;low period during convert 0033 EB03 083E PRDH * PRDL +&01 ;hign period during convert 0034 EB03 083F NOTDIF * PRDH +&01 ;Note difference used in interpolation 0035 EB03 0036 EB03 02CF FLUSH * SFLUSH -&04 0037 EB03 0800 ACTIV * MACTIV -&04 0038 EB03 0039 EB03 0040 EB03 ;Externally referenced data 0041 EB03 ;ACTIV 0042 EB03 ;FLUSH 0043 EB03 ;ENVEL 0044 EB03 ;SNDWRK 0045 EB03 ;Externally referenced routines 0046 EB03 ;EXAM 0047 EB03 ;REMOV 0048 EB03 ;Entry points 0049 EB03 ;SNDRST Initialise sound system, shut sound chip up 0050 EB03 ; Acc,X,Y ,P destroyed 0051 EB03 ;SNDIRQ Service entry point 1/100th second 0052 EB03 ; only use after initialisation 0053 EB03 ; Acc,X ,Y and P destroyed 0054 EB03 ;; A,X,P preserved, Y set to zero on exit 0055 EB03 0056 EB03 0057 EB03 MINATN ;set minimum attenuation 0058 EB03 A9 04 LDAIM &04 0059 EB05 9D 08 08 STAAX EPERD 0060 EB08 A9 C0 LDAIM &C0 0061 EB0A 0062 EB0A 0063 EB0A UPATN ;update attenuation 0064 EB0A 9D 04 08 STAAX ATTN 0065 EB0D ; 0066 EB0D ; shut up mode ? 0067 EB0D ; 0068 EB0D AC 62 02 LDY SHUTUP 0069 EB10 F0 02 BEQ NOISY ;[sound allowed] 0070 EB12 ; sound suppressed 0071 EB12 A9 C0 LDAIM &C0 ;force minimum attenuation 0072 EB14 NOISY 0073 EB14 ; 0074 EB14 38 SEC 0075 EB15 E9 40 SBCIM &40 ;convert signed to unsigned number 0076 EB17 4A LSRA 0077 EB18 4A LSRA 0078 EB19 4A LSRA ;shift top four bits into low nibble 0079 EB1A 49 0F EORIM &0F ;invert for correct output 0080 EB1C 1D 3C EB ORAAX CHAN ;add channel specification 0081 EB1F 09 10 ORAIM &10 ;select odd register (attenuation) 0082 EB21 ;fall into the send routine 0083 EB21 SNDOUT 0084 EB21 SEND 0085 EB21 08 PHP 0086 EB22 SENDX ;entered by code which has already done a PHP 0087 EB22 78 SEI 0088 EB23 A0 FF LDYIM &FF 0089 EB25 8C 43 FE STY &FE43 0090 EB28 8D 4F FE STA &FE4F 0091 EB2B C8 INY 0092 EB2C 8C 40 FE STY &FE40 0093 EB2F A0 02 LDYIM &02 0094 EB31 SWAIT 0095 EB31 88 DEY 0096 EB32 D0 FD BNE SWAIT 0097 EB34 A0 08 LDYIM &08 0098 EB36 8C 40 FE STY &FE40 0099 EB39 A0 04 LDYIM &04 0100 EB3B SWAT2 0101 EB3B 88 DEY 0102 EB3C D0 FD BNE SWAT2 0103 EB3E 28 PLP 0104 EB3F 60 RTS 0105 EB40 RCHAN 0106 EB40 EB3C CHAN * RCHAN -&04 0107 EB40 E0 = &E0 0108 EB41 C0 = &C0 0109 EB42 A0 = &A0 0110 EB43 80 = &80 0111 EB44 0112 EB44 0113 EB44 HENDS 0114 EB44 4C 59 EC JMP ENDSW ;finished all envelope processing 0115 EB47 0116 EB47 SNDIRQ 0117 EB47 A9 00 LDAIM ZERO 0118 EB49 8D 3B 08 STA WATGO 0119 EB4C AD 38 08 LDA NOWAT 0120 EB4F D0 06 BNE MAN2 0121 EB51 EE 3B 08 INC WATGO 0122 EB54 CE 38 08 DEC NOWAT 0123 EB57 MAN2 0124 EB57 A2 08 LDXIM &08 ;X always contains current channel 0125 EB59 MNLOP Acorn macro assembler Page 104 MOS52 Sound generator 0126 EB59 CA DEX ;first real channel is 3 0127 EB5A BD 00 08 LDAAX ACTIV ;check if channel X is doing anything 0128 EB5D F0 E5 BEQ HENDS ;[channel not active so take quick route] 0129 EB5F BD CF 02 LDAAX FLUSH 0130 EB62 30 05 BMI MAN8 ;[must abort current note] 0131 EB64 BD 18 08 LDAAX DUR 0132 EB67 D0 03 BNE MAN10 ;[note finished] 0133 EB69 MAN8 0134 EB69 20 6B EC JSR NXTNT ;[get new note from queue if it exists] 0135 EB6C MAN10 0136 EB6C BD 18 08 LDAAX DUR 0137 EB6F F0 13 BEQ MAN13 ;next note now 0138 EB71 C9 FF CMPIM &FF 0139 EB73 F0 12 BEQ MAN12 0140 EB75 DE 1C 08 DECAX DRDIV 0141 EB78 D0 0D BNE MAN12 ;[not 1/20th sec tick] 0142 EB7A A9 05 LDAIM &05 0143 EB7C 9D 1C 08 STAAX DRDIV ; set counter to wait for further 1/20th sec 0144 EB7F DE 18 08 DECAX DUR 0145 EB82 D0 03 BNE MAN12 0146 EB84 MAN13 0147 EB84 20 6B EC JSR NXTNT ;try to get a new note 0148 EB87 MAN12 0149 EB87 BD 24 08 LDAAX SCONT 0150 EB8A F0 05 BEQ MAN11 0151 EB8C DE 24 08 DECAX SCONT ;dec envelope scaling counter 0152 EB8F D0 B3 BNE HENDS ;[not time for new envelope tick] 0153 EB91 MAN11 0154 EB91 BC 20 08 LDYAX ENVLP ;get envelope offset into Y 0155 EB94 C0 FF CPYIM &FF 0156 EB96 F0 AC BEQ HENDS 0157 EB98 B9 C0 08 LDAAY ENV ;get first envelope parameter 0158 EB9B 29 7F ANDIM &7F ;mask off sweep repeat bit 0159 EB9D 9D 24 08 STAAX SCONT ;set up scaling counter again 0160 EBA0 BD 08 08 LDAAX EPERD ;envelope period 0161 EBA3 C9 04 CMPIM &04 ;check for 'finished' period 0162 EBA5 F0 60 BEQ ENDEV ;[no longer in middle of envelope] 0163 EBA7 ; 0164 EBA7 BD 08 08 LDAAX EPERD 0165 EBAA 18 CLC 0166 EBAB 7D 20 08 ADCAX ENVLP ;get offset to current amplitude envelope parameters 0167 EBAE A8 TAY ;ENV+7,Y now point to attninc rate and sENV+11 to attnlevel 0168 EBAF B9 CB 08 LDAAY ENV+&0B ;atenuation level 0169 EBB2 38 SEC 0170 EBB3 E9 3F SBCIM &3F 0171 EBB5 8D 3A 08 STA PEAK ;temp data for following calculations 0172 EBB8 B9 C7 08 LDAAY ENV+&7 ;amount by which attenuation is changed each tick 0173 EBBB 8D 39 08 STA ATINC ;temp data for calculations 0174 EBBE BD 04 08 LDAAX ATTN 0175 EBC1 48 PHA 0176 EBC2 18 CLC 0177 EBC3 6D 39 08 ADC ATINC ;add incremnet to attenuation 0178 EBC6 50 07 BVC OK8 ;first check for 8 bit overflow 0179 EBC8 2A ROLA ;get sign bit into carry 0180 EBC9 A9 3F LDAIM &3F ;highest value 0181 EBCB B0 02 BCS OK8 0182 EBCD 49 FF EORIM &FF ; convert to bottom limit 0183 EBCF OK8 0184 EBCF 9D 04 08 STAAX ATTN ;store as new attenuation 0185 EBD2 2A ROLA ;the following code checks for overflow of attenuation (only a 7 bit number) 0186 EBD3 5D 04 08 EORAX ATTN 0187 EBD6 10 09 BPL ATOK 0188 EBD8 A9 3F LDAIM &3F 0189 EBDA 90 02 BCC LMATN ;[hit #3F limit] 0190 EBDC 49 FF EORIM &FF ;convert for bottom limit 0191 EBDE LMATN 0192 EBDE 9D 04 08 STAAX ATTN 0193 EBE1 ATOK 0194 EBE1 CE 39 08 DEC ATINC 0195 EBE4 BD 04 08 LDAAX ATTN ;the following code checks that (ATTN-PEAK)*SIGN(increment)>=0 0196 EBE7 38 SEC 0197 EBE8 ED 3A 08 SBC PEAK 0198 EBEB 4D 39 08 EOR ATINC 0199 EBEE 30 09 BMI SMPER ;[attenuation has not reached limit yet] 0200 EBF0 AD 3A 08 LDA PEAK ;attn was too large therefore set to peak 0201 EBF3 9D 04 08 STAAX ATTN 0202 EBF6 FE 08 08 INCAX EPERD ;next envelope period 0203 EBF9 SMPER ;same envelope period 0204 EBF9 68 PLA 0205 EBFA 5D 04 08 EORAX ATTN 0206 EBFD 29 F8 ANDIM &F8 0207 EBFF F0 06 BEQ NNEWA ;no new chip attenuation output (hasn't changed)] 0208 EC01 BD 04 08 LDAAX ATTN 0209 EC04 20 0A EB JSR UPATN ;update chip attenuation 0210 EC07 NNEWA 0211 EC07 ENDEV 0212 EC07 ;frequency sweeping part of envelope 0213 EC07 BD 10 08 LDAAX NPERD 0214 EC0A C9 03 CMPIM &03 0215 EC0C F0 4B BEQ ENDSW 0216 EC0E BD 14 08 LDAAX NCONT ;number of ticks left in this frequency period 0217 EC11 D0 2A BNE GTPRD 0218 EC13 FE 10 08 INCAX NPERD ;next period 0219 EC16 BD 10 08 LDAAX NPERD 0220 EC19 C9 03 CMPIM &03 ;check for period=3 =>end of all periods 0221 EC1B D0 10 BNE NTLF ;[not last period] 0222 EC1D BC 20 08 LDYAX ENVLP ;the following checks for bit 8 set in the first envelope byte=> no sweep repeat 0223 EC20 B9 C0 08 LDAAY ENV 0224 EC23 30 34 BMI ENDSW ;[not a repeating sweep therefore jump to end] 0225 EC25 A9 00 LDAIM ZERO 0226 EC27 9D 30 08 STAAX NTADD ;reset amount added to note to zero for next sweep 0227 EC2A 9D 10 08 STAAX NPERD ;first sweep period 0228 EC2D NTLF 0229 EC2D BD 10 08 LDAAX NPERD ;the following points Y to the sweep parameters of the current envelope/period 0230 EC30 18 CLC 0231 EC31 7D 20 08 ADCAX ENVLP 0232 EC34 A8 TAY 0233 EC35 B9 C4 08 LDAAY ENV+&04 0234 EC38 9D 14 08 STAAX NCONT ;number of cycles for this frequency period 0235 EC3B F0 1C BEQ ENDSW ;zero frequency period 0236 EC3D GTPRD 0237 EC3D DE 14 08 DECAX NCONT 0238 EC40 BD 20 08 LDAAX ENVLP 0239 EC43 18 CLC 0240 EC44 7D 10 08 ADCAX NPERD 0241 EC47 A8 TAY 0242 EC48 B9 C1 08 LDAAY ENV+&01 ;note increment for this frequency period 0243 EC4B 18 CLC 0244 EC4C 7D 30 08 ADCAX NTADD 0245 EC4F 9D 30 08 STAAX NTADD ;add increment to the note offset 0246 EC52 18 CLC Acorn macro assembler Page 105 MOS52 Sound generator 0247 EC53 7D 0C 08 ADCAX SNOTE 0248 EC56 20 01 ED JSR CNVRT ;convert note to period and output 0249 EC59 ENDSW 0250 EC59 E0 04 CPXIM &04 ;'test channel number for zero' 0251 EC5B F0 0D BEQ EDUP ;[channel was zero therefore leave loop] 0252 EC5D 4C 59 EB JMP MNLOP 0253 EC60 0254 EC60 0255 EC60 SNDRST 0256 EC60 A2 08 LDXIM &08 0257 EC62 ; 0258 EC62 RLOP 0259 EC62 CA DEX 0260 EC63 20 A2 EC JSR SCRST ;reset sound channel X 0261 EC66 E0 04 CPXIM &04 0262 EC68 D0 F8 BNE RLOP 0263 EC6A ; 0264 EC6A EDUP ;end of 1/100th sec processing 0265 EC6A 60 RTS 0266 EC6B 0267 EC6B 0268 EC6B NXTNT 0269 EC6B BD 08 08 LDAAX EPERD ;get current amplitude period 0270 EC6E C9 04 CMPIM &04 ;period 4 => note has fully released 0271 EC70 F0 05 BEQ ELDDN 0272 EC72 A9 03 LDAIM &03 0273 EC74 9D 08 08 STAAX EPERD ;put note in the release phase of the envelope 0274 EC77 ELDDN 0275 EC77 BD CF 02 LDAAX FLUSH 0276 EC7A F0 14 BEQ NOFL ;[no flush has been flagged] 0277 EC7C A9 00 LDAIM ZERO 0278 EC7E 9D CF 02 STAAX FLUSH ;clear the flush flag 0279 EC81 A0 04 LDYIM &04 ;the following clears all wait variables 0280 EC83 SWTLOP 0281 EC83 99 2B 08 STAAY WAIT +&03 0282 EC86 88 DEY 0283 EC87 D0 FA BNE SWTLOP 0284 EC89 9D 18 08 STAAX DUR ;set duration to zero => note finished 0285 EC8C 88 DEY 0286 EC8D 8C 38 08 STY NOWAT ;reset chord building status 0287 EC90 NOFL 0288 EC90 BD 28 08 LDAAX WAIT ;check it channel waiting for chord 0289 EC93 F0 46 BEQ NOTWT 0290 EC95 AD 3B 08 LDA WATGO ;check if chord now ready to play 0291 EC98 F0 36 BEQ NOTGO ;[chord not ready yet] 0292 EC9A A9 00 LDAIM ZERO 0293 EC9C 9D 28 08 STAAX WAIT ;clear waiting for chord status 0294 EC9F NNWAT 0295 EC9F 4C 98 ED JMP STRNT ;start playing note 0296 ECA2 SCRST ;reset sound channel X 0297 ECA2 20 03 EB JSR MINATN 0298 ECA5 98 TYA 0299 ECA6 9D 18 08 STAAX DUR 0300 ECA9 9D CF 02 STAAX FLUSH 0301 ECAC 9D 00 08 STAAX ACTIV 0302 ECAF ; 0303 ECAF ;clear wait periods to zero 0304 ECAF ; 0305 ECAF A0 03 LDYIM &03 0306 ECB1 CWP 0307 ECB1 99 2C 08 STAAY WAIT+&04 0308 ECB4 88 DEY 0309 ECB5 10 FA BPL CWP ;[more wait periods to clear] 0310 ECB7 ; Y=$FF 0311 ECB7 ; MI true 0312 ECB7 ; 0313 ECB7 ; indicate no channels waiting 0314 ECB7 ; 0315 ECB7 8C 38 08 STY NOWAT 0316 ECBA ; 0317 ECBA 30 4A BMI FCNVRT ;[ALWAYS JUMP, set period of chip to zero] 0318 ECBC 0319 ECBC 0320 ECBC NGONG 0321 ECBC 08 PHP 0322 ECBD 78 SEI 0323 ECBE BD 08 08 LDAAX EPERD ;while irq disabled check if active can be cleared 0324 ECC1 C9 04 CMPIM &04 ;if envelope period=4 then note finished 0325 ECC3 D0 0A BNE NOGO2 ;[note not yet released] 0326 ECC5 20 5B E4 JSR EXAM ;check for recent arrival of note 0327 ECC8 90 05 BCC NOGO2 ;queue no longer empty 0328 ECCA A9 00 LDAIM ZERO 0329 ECCC 9D 00 08 STAAX ACTIV ;set channel as inactive 0330 ECCF NOGO2 0331 ECCF 28 PLP 0332 ECD0 NOTGO 0333 ECD0 BC 20 08 LDYAX ENVLP 0334 ECD3 C0 FF CPYIM &FF 0335 ECD5 D0 03 BNE PROG 0336 ECD7 20 03 EB JSR MINATN ;update attenuation of box envelopes 0337 ECDA PROG 0338 ECDA PRTS ;rts pointer 0339 ECDA 60 RTS 0340 ECDB 0341 ECDB 0342 ECDB NOTWT 0343 ECDB 20 5B E4 JSR EXAM ;examine byte at head of queue 0344 ECDE B0 DC BCS NGONG ;[queue empty] 0345 ECE0 29 03 ANDIM &03 0346 ECE2 F0 BB BEQ NNWAT ;[no chord commands for next note] 0347 ECE4 AD 38 08 LDA NOWAT 0348 ECE7 F0 15 BEQ SRTS ;[full chord already accepted,ignore this channel for now] 0349 ECE9 FE 28 08 INCAX WAIT ;set waiting flag 0350 ECEC 2C 38 08 BIT NOWAT ;check for chord being built 0351 ECEF 10 0A BPL SMCRD ;chord already being built 0352 ECF1 20 5B E4 JSR EXAM ;getheader byte again 0353 ECF4 29 03 ANDIM &03 ;select chord bits 0354 ECF6 8D 38 08 STA NOWAT ;new chord so set number of other channels required 0355 ECF9 10 03 BPL LNOTGO 0356 ECFB SMCRD 0357 ECFB CE 38 08 DEC NOWAT ;decrement the number of channels still required for chord 0358 ECFE SRTS ;must point to RTS command 0359 ECFE LNOTGO 0360 ECFE 4C D0 EC JMP NOTGO 0361 ED01 0362 ED01 0363 ED01 ;routine to convert note to period 0364 ED01 ;and output to the chip 0365 ED01 CNVRT 0366 ED01 DD 2C 08 CMPAX OLDNTE 0367 ED04 F0 D4 BEQ PRTS ;no need to update chip Acorn macro assembler Page 106 MOS52 Sound generator 0368 ED06 FCNVRT ;force note output 0369 ED06 9D 2C 08 STAAX OLDNTE 0370 ED09 E0 04 CPXIM &04 ;check if noise channel 0371 ED0B D0 09 BNE TONE 0372 ED0D 29 0F ANDIM &0F ;noise input is only 4 bits 0373 ED0F 1D 3C EB ORAAX CHAN ;add channel information 0374 ED12 08 PHP ;push P (will immediately be pulled) 0375 ED13 4C 95 ED JMP CDONE ;output and return 0376 ED16 TONE ;tone channel 0377 ED16 48 PHA 0378 ED17 29 03 ANDIM &03 0379 ED19 8D 3C 08 STA FRACT ;low 2 bits give fraction of semitone 0380 ED1C A9 00 LDAIM &00 0381 ED1E 8D 3D 08 STA PRDL 0382 ED21 68 PLA 0383 ED22 4A LSRA 0384 ED23 4A LSRA 0385 ED24 OCTL 0386 ED24 C9 0C CMPIM &0C ;check if note > one octave 0387 ED26 90 07 BCC ENDOL 0388 ED28 EE 3D 08 INC PRDL ;use PRDL as octave counter for division 0389 ED2B E9 0C SBCIM &0C 0390 ED2D D0 F5 BNE OCTL ;bne ok since if the answer is zero loop should terminate anyway 0391 ED2F ENDOL 0392 ED2F A8 TAY 0393 ED30 AD 3D 08 LDA PRDL ;number octaves up 0394 ED33 48 PHA 0395 ED34 B9 FB ED LDAAY NTABL ;low period from table 0396 ED37 8D 3D 08 STA PRDL 0397 ED3A B9 07 EE LDAAY NTABH ;high period for lowest octave 0398 ED3D 48 PHA 0399 ED3E 29 03 ANDIM &03 0400 ED40 8D 3E 08 STA PRDH 0401 ED43 68 PLA ;get semitone difference from top bits of NTABH 0402 ED44 4A LSRA 0403 ED45 4A LSRA 0404 ED46 4A LSRA 0405 ED47 4A LSRA 0406 ED48 8D 3F 08 STA NOTDIF 0407 ED4B AD 3D 08 LDA PRDL 0408 ED4E AC 3C 08 LDY FRACT ;number of times NOTDIF has to be added 0409 ED51 F0 0C BEQ INTRPE ;[true semitone] 0410 ED53 INTRPL 0411 ED53 ;following subtracts NOTDIF from period 0412 ED53 38 SEC 0413 ED54 ED 3F 08 SBC NOTDIF 0414 ED57 B0 03 BCS INTRPO 0415 ED59 CE 3E 08 DEC PRDH 0416 ED5C INTRPO 0417 ED5C 88 DEY 0418 ED5D D0 F4 BNE INTRPL ;[add another fraction] 0419 ED5F INTRPE 0420 ED5F 8D 3D 08 STA PRDL 0421 ED62 68 PLA 0422 ED63 A8 TAY ;tranfer octave count to Y 0423 ED64 F0 09 BEQ ODONE ;if lowest octave then no shifts 0424 ED66 SSHIFT 0425 ED66 4E 3E 08 LSR PRDH ;divide period by 2 0426 ED69 6E 3D 08 ROR PRDL 0427 ED6C 88 DEY 0428 ED6D D0 F7 BNE SSHIFT ;[up another octave] 0429 ED6F ODONE 0430 ED6F AD 3D 08 LDA PRDL ;extract low four bits of period 0431 ED72 18 CLC 0432 ED73 7D 3D C4 ADCAX SCHOFF 0433 ED76 8D 3D 08 STA PRDL 0434 ED79 90 03 BCC NOFOV 0435 ED7B EE 3E 08 INC PRDH 0436 ED7E NOFOV 0437 ED7E 29 0F ANDIM &0F 0438 ED80 1D 3C EB ORAAX CHAN ;add channel address 0439 ED83 08 PHP 0440 ED84 78 SEI ;make sure another request does not mess up sequence 0441 ED85 20 21 EB JSR SEND ;output to chip 0442 ED88 AD 3D 08 LDA PRDL ;get next 6 bits of period 0443 ED8B 4E 3E 08 LSR PRDH 0444 ED8E 6A RORA 0445 ED8F 4E 3E 08 LSR PRDH 0446 ED92 6A RORA 0447 ED93 4A LSRA ;transfer to low 6 bits of Acc 0448 ED94 4A LSRA 0449 ED95 CDONE 0450 ED95 4C 22 EB JMP SENDX ;output period to chip 0451 ED98 ;routine to start note at head of queue 0452 ED98 STRNT 0453 ED98 08 PHP ;start indivisible section to stop new 0454 ED99 78 SEI ;note being added to queue half way through extraction 0455 ED9A 20 60 E4 JSR REMOV ;get byte at head queue 0456 ED9D 48 PHA ;save byte at head queue 0457 ED9E 29 04 ANDIM &04 ;extract 'continue' bit 0458 EDA0 F0 15 BEQ NOCONT ;[not continue] 0459 EDA2 68 PLA 0460 EDA3 BC 20 08 LDYAX ENVLP ;must check for continue to auto envelope 0461 EDA6 C0 FF CPYIM &FF 0462 EDA8 D0 03 BNE SCON1 0463 EDAA 20 03 EB JSR MINATN ;update attenuation 0464 EDAD SCON1 0465 EDAD 20 60 E4 JSR REMOV ;throw away note 0466 EDB0 20 60 E4 JSR REMOV ;get duration 0467 EDB3 28 PLP ;end of indivisible section 0468 EDB4 4C F7 ED JMP DODUR ;jump to continue update duration 0469 EDB7 NOCONT 0470 EDB7 68 PLA ;restore header byte 0471 EDB8 29 F8 ANDIM &F8 ;extract 5 envelope bits 0472 EDBA 0A ASLA ;programmable envelope select bit >carry 0473 EDBB 90 0B BCC PENV ;[programmed envelope] 0474 EDBD 49 FF EORIM &FF ;convert box envelope to amplitude 0475 EDBF 4A LSRA 0476 EDC0 38 SEC 0477 EDC1 E9 40 SBCIM &40 ;convert to a signed number 0478 EDC3 20 0A EB JSR UPATN 0479 EDC6 A9 FF LDAIM &FF ;flag box envelope by setting top bit of ENVLP 0480 EDC8 PENV 0481 EDC8 9D 20 08 STAAX ENVLP ;envelope pointer,envelope*16 0482 EDCB A9 05 LDAIM &05 ;start timing first 1/20th second from now 0483 EDCD 9D 1C 08 STAAX DRDIV 0484 EDD0 A9 01 LDAIM &01 0485 EDD2 9D 24 08 STAAX SCONT ;first envelope update next tick 0486 EDD5 A9 00 LDAIM ZERO 0487 EDD7 9D 14 08 STAAX NCONT 0488 EDDA 9D 08 08 STAAX EPERD ;first amplittude envelope Acorn macro assembler Page 107 MOS52 Sound generator 0489 EDDD 9D 30 08 STAAX NTADD ;note add envelope starts at 0 0490 EDE0 A9 FF LDAIM &FF 0491 EDE2 9D 10 08 STAAX NPERD ;set frequency envelope to -1,incremented on first tick 0492 EDE5 20 60 E4 JSR REMOV ;extract note byte from queue 0493 EDE8 9D 0C 08 STAAX SNOTE ;store note 0494 EDEB 20 60 E4 JSR REMOV ;Remove duration 0495 EDEE 28 PLP ;end of indivisible section 0496 EDEF 48 PHA ;remember duration 0497 EDF0 BD 0C 08 LDAAX SNOTE 0498 EDF3 20 01 ED JSR CNVRT ;convert to period and output 0499 EDF6 68 PLA ;get duration back 0500 EDF7 DODUR 0501 EDF7 9D 18 08 STAAX DUR ;set up duration 0502 EDFA 60 RTS 0503 EDFB 0504 EDFB 0505 EDFB NTABL ;lookup table for low 8 bit of period 0506 EDFB F0 = &F0 0507 EDFC B7 = &B7 0508 EDFD 82 = &82 0509 EDFE 4F = &4F 0510 EDFF 20 = &20 0511 EE00 F3 = &F3 0512 EE01 C8 = &C8 0513 EE02 A0 = &A0 0514 EE03 7B = &7B 0515 EE04 57 = &57 0516 EE05 35 = &35 0517 EE06 16 = &16 0518 EE07 NTABH ;lookup table for high 2 bits of period 0519 EE07 E7 = &E7 ;and 6 bits of note difference being the difference 0520 EE08 D7 = &D7 ;between this and the next note 0521 EE09 CB = &CB 0522 EE0A C3 = &C3 0523 EE0B B7 = &B7 0524 EE0C AA = &AA 0525 EE0D A2 = &A2 0526 EE0E 9A = &9A 0527 EE0F 92 = &92 0528 EE10 8A = &8A 0529 EE11 82 = &82 0530 EE12 7A = &7A 0531 EE13 0532 EE13 0533 EE13 LNK MOS54 0001 EE13 ; MOS54 0002 EE13 TTL MOS54 SPEECH DRIVING 0003 EE13 OPT MOS54 Acorn macro assembler Page 108 MOS54 SPEECH DRIVING 0004 EE13 ;(c) 1981 ACORN Computers Limited 0005 EE13 ;BBC Microcomputer Machine Operating System (MOS) 0006 EE13 ;Change record: 0007 EE13 ;004 07-Nov-81 PBM Prototype version 0008 EE13 ;Author(s): 0009 EE13 ;Paul Bond 0010 EE13 0011 EE13 0012 EE13 SRINIT ;initialise SEROM environment for CFS 0013 EE13 A9 EF LDAIM &F0-&01 ;$01 adjusts for future INC SEROM 0014 EE15 ; SEROM will cycle $F0 ... $FF ... $00 ... $10 (max) 0015 EE15 85 F5 STA SEROM 0016 EE17 60 RTS 0017 EE18 0018 EE18 0019 EE18 SRNEXT ;move on to next SEROM 0020 EE18 ; 0021 EE18 ; scans phrase ROM first, then paged ROM 0022 EE18 ; 0023 EE18 SPCPYF ;entry point from failed copyright message test 0024 EE18 A2 0D LDXIM SVISFS 0025 EE1A E6 F5 INC SEROM 0026 EE1C A4 F5 LDY SEROM 0027 EE1E 10 39 BPL SPSV ;[process paged ROM, V not altered] 0028 EE20 ; 0029 EE20 ; process PHROM, V not altered 0030 EE20 ; 0031 EE20 ; no need to check for speech chip present 0032 EE20 ; reads from chip will not indicate copyright message 0033 EE20 ; 0034 EE20 ; check for existence of speech SEROM 0035 EE20 ; 0036 EE20 ; set pointer to 1 0037 EE20 ; 0038 EE20 A2 00 LDXIM ZERO 0039 EE22 86 F7 STX ROMPTR+&01 0040 EE24 E8 INX ;X := 1 0041 EE25 86 F6 STX ROMPTR+&00 0042 EE27 20 BB EE JSR SPLOAD ;set address 0043 EE2A ; 0044 EE2A ; check for copyright (C) 0045 EE2A ; 0046 EE2A A2 03 LDXIM &03 0047 EE2C SPCPY ;V not altered 0048 EE2C 20 62 EE JSR RDBYTE ;does not alter X 0049 EE2F DD 0C DF CMPAX COPYR 0050 EE32 D0 E4 BNE SPCPYF ;[failed test for copyright message] 0051 EE34 ; C=1 0052 EE34 CA DEX 0053 EE35 10 F5 BPL SPCPY 0054 EE37 ; 0055 EE37 ; C=1 0056 EE37 ; 0057 EE37 ; copyright message is present 0058 EE37 ; 0059 EE37 ; we have read 5 bytes so far 0060 EE37 ; skip more bytes allowing for copyright/title strings 0061 EE37 ; 0062 EE37 ; position serial ROM to cassette image data 0063 EE37 ; (indirect pointer held at offset $3E) 0064 EE37 ; 0065 EE37 A9 3E LDAIM &3E 0066 EE39 85 F6 STA ROMPTR+&00 0067 EE3B ; 0068 EE3B ; C=1 0069 EE3B ; 0070 EE3B SPLIND ;load address indirect, V not altered, returns C=0 0071 EE3B 20 BB EE JSR SPLOAD 0072 EE3E [ TRUE=0 0073 EE3E ; perform soft version of read-and-branch 0074 EE3E ; 0075 EE3E A2 FF LDXIM &FF 0076 EE40 RABLP 0077 EE40 ; read lo byte when X=0, hi byte when X=1 0078 EE40 20 62 EE JSR RDBYTE ;does not corrupt X 0079 EE43 ; 0080 EE43 A0 08 LDYIM &08 0081 EE45 RABLO ;reverse bits in A into ROMPTR+(0/1) 0082 EE45 0A ASLA 0083 EE46 76 F7 RORAX ROMPTR+&01 0084 EE48 88 DEY 0085 EE49 D0 FA BNE RABLO ;[process 8 bits] 0086 EE4B ; 0087 EE4B E8 INX 0088 EE4C F0 F2 BEQ RABLP ;repeat loop once more with X=0 0089 EE4E ; 0090 EE4E 18 CLC ;indicate next successful 0091 EE4F 90 6A BCC SPLOAD ;[ALWAYS jump, set indirected address AND return] 0092 EE51 | 0105 EE51 ] 0106 EE51 0107 EE51 0108 EE51 RDSPCH ;read byte from SEROM 0109 EE51 A2 0E LDXIM SVRSFS 0110 EE53 A4 F5 LDY SEROM 0111 EE55 30 0B BMI RDBYTE ;[reading from PHROM, V not altered] 0112 EE57 ; 0113 EE57 ; reading from paged ROM 0114 EE57 ; 0115 EE57 A0 FF LDYIM 0-MCVER ;enter paged ROM with M/C indicator in Y 0116 EE59 ; 0117 EE59 SPSV ;used by read byte routine, V not altered 0118 EE59 08 PHP 0119 EE5A 20 68 F1 JSR SVOP ;search for paged SEROM (N.B. SVOPSP) 0120 EE5D ; 0121 EE5D 28 PLP ;restore V-flag 0122 EE5E C9 01 CMPIM &01 ;claimed => C=0, not claimed => C=1 0123 EE60 98 TYA ;A := read character (useful for read byte routine only) 0124 EE61 60 RTS 0125 EE62 0126 EE62 0127 EE62 RDBYTE ;read byte from speech ROM, V not altered 0128 EE62 08 PHP 0129 EE63 78 SEI 0130 EE64 A0 10 LDYIM SPOPRB ;set to read byte 0131 EE66 20 7F EE JSR WSPECH 0132 EE69 ; read byte (following code shorter than JSR RSPECH; PLP; RTS) 0133 EE69 A0 00 LDYIM ZERO 0134 EE6B F0 17 BEQ SENDSX ;[ALWAYS JUMP, N.B. does PLP & RTS, SEI already active] 0135 EE6D 0136 EE6D Acorn macro assembler Page 109 MOS54 SPEECH DRIVING 0137 EE6D RSPECH ;read from speech processor, must not corrupt X 0138 EE6D A0 00 LDYIM ZERO 0139 EE6F F0 11 BEQ SENDSP ;[ALWAYS jump] 0140 EE71 ; 0141 EE71 ; 0142 EE71 SPL ;send load address nibbles 0143 EE71 ; A = hl 0144 EE71 ; h is hi-nibble 0145 EE71 ; l is lo-nibble 0146 EE71 48 PHA 0147 EE72 20 7A EE JSR SPL1 ;send lo-nibble 0148 EE75 68 PLA 0149 EE76 6A RORA 0150 EE77 6A RORA 0151 EE78 6A RORA 0152 EE79 6A RORA 0153 EE7A ; 0154 EE7A ; send hi-nibble 0155 EE7A ; 0156 EE7A SPL1 0157 EE7A 29 0F ANDIM &0F ;isolate lo-nibble 0158 EE7C 09 40 ORAIM SPOPLA 0159 EE7E ; 0160 EE7E A8 TAY ;Y := command 0161 EE7F ; 0162 EE7F WSPECH ;write to speech processor, must not corrupt X 0163 EE7F 98 TYA ;A := command 0164 EE80 A0 01 LDYIM &01 0165 EE82 ; 0166 EE82 SENDSP ;read/write from/to speech processor 0167 EE82 ; Y=0 => read 0168 EE82 ; Y=1 => write 0169 EE82 08 PHP 0170 EE83 78 SEI 0171 EE84 SENDSX ;entry used by routines which have done a PHP & SEI 0172 EE84 2C 7B 02 BIT SPFLAG 0173 EE87 10 21 BPL SNDSX0 ;[speech chip not present] 0174 EE89 ; 0175 EE89 48 PHA ;save command 0176 EE8A ; 0177 EE8A ; select PA7-0 as inputs/outputs 0178 EE8A ; 0179 EE8A B9 75 F0 LDAAY SENDD 0180 EE8D 8D 43 FE STA DDRAQ 0181 EE90 ; 0182 EE90 ; place command onto data bus 0183 EE90 ; 0184 EE90 68 PLA ;restore command 0185 EE91 8D 4F FE STA PAPQ 0186 EE94 ; 0187 EE94 ; speech enable 0188 EE94 ; 0189 EE94 B9 77 F0 LDAAY SENDS 0190 EE97 8D 40 FE STA PBQ 0191 EE9A ; 0192 EE9A ; wait for speech ready 0193 EE9A ; 0194 EE9A SPWAIT 0195 EE9A 2C 40 FE BIT PBQ 0196 EE9D 30 FB BMI SPWAIT ;[not ready] 0197 EE9F ; 0198 EE9F ; read possible speech data 0199 EE9F ; 0200 EE9F AD 4F FE LDA PAPQ 0201 EEA2 48 PHA 0202 EEA3 ; 0203 EEA3 ; speech disable 0204 EEA3 ; 0205 EEA3 B9 79 F0 LDAAY SENDF 0206 EEA6 8D 40 FE STA PBQ 0207 EEA9 ; 0208 EEA9 ; return 0209 EEA9 ; 0210 EEA9 68 PLA ;restore speech data (not relevant if write) 0211 EEAA ; 0212 EEAA SNDSX0 0213 EEAA 28 PLP 0214 EEAB A8 TAY ;set processor status flags (useful for RSPECH) and Y (for FX calls) 0215 EEAC 60 RTS 0216 EEAD 0217 EEAD 0218 EEAD SRSKIP ;skip to SEROM pointer indicated by SRPTR 0219 EEAD AD CB 03 LDA SRPTR+&00 0220 EEB0 85 F6 STA ROMPTR+&00 0221 EEB2 AD CC 03 LDA SRPTR+&01 0222 EEB5 85 F7 STA ROMPTR+&01 0223 EEB7 A5 F5 LDA SEROM 0224 EEB9 10 1E BPL SRSK0 ;[skipping within paged ROM] 0225 EEBB ; 0226 EEBB ; skipping within speech SEROM 0227 EEBB ; load address from SEROM/ROMPTR 0228 EEBB ; 0229 EEBB SPLOAD ;load address, must not corrupt V 0230 EEBB ; address given in SEROM/ROMPTR 0231 EEBB 08 PHP 0232 EEBC 78 SEI ;N.B. uses SPWK1 0233 EEBD A5 F6 LDA ROMPTR+&00 0234 EEBF 20 71 EE JSR SPL ;send address lo-byte 0235 EEC2 A5 F5 LDA SEROM 0236 EEC4 85 FA STA SPWK1 0237 EEC6 A5 F7 LDA ROMPTR+&01 0238 EEC8 2A ROLA 0239 EEC9 2A ROLA 0240 EECA 46 FA LSR SPWK1 0241 EECC 6A RORA 0242 EECD 46 FA LSR SPWK1 0243 EECF 6A RORA 0244 EED0 20 71 EE JSR SPL ;send address hi-byte 0245 EED3 A5 FA LDA SPWK1 0246 EED5 20 7A EE JSR SPL1 ;send address hi-nibble 0247 EED8 28 PLP 0248 EED9 SRSK0 0249 EED9 60 RTS 0250 EEDA 0251 EEDA 0252 EEDA [ FALSE=0 0265 EEDA ] 0266 EEDA 0267 EEDA 0268 EEDA < &0001 0269 EEDA Acorn macro assembler Page 110 MOS54 SPEECH DRIVING 0270 EEDA 0271 EEDA LNK MOS56 0001 EEDA 0002 EEDA ; > MOS56 0003 EEDA TTL MOS56 Keyboard management 0004 EEDA OPT MOS56 Acorn macro assembler Page 111 MOS56 Keyboard management 0005 EEDA ;(c) 1981 ACORN Computers Limited 0006 EEDA ;BBC Microcomputer Machine Operating System (MOS) 0007 EEDA ;Change record: 0008 EEDA ;202 01-May-82 PB Programmable TAB key 0009 EEDA ;.05 16-Nov-81 PB Fix CTRL/SHIFT matrix h/w problem 0010 EEDA ;100 04-Sep-81 PB Remove SHIFT and CTRL debounce 0011 EEDA ;Author(s): 0012 EEDA ;PB Paul Bond 0013 EEDA ;MP Mike Prees 0014 EEDA ; STATUS BYTE USES (KSTAT) 0015 EEDA ; N.B. status byte is NEVER zero 0016 EEDA ; (CAPITALS and SHIFT lock never concurrent) 0017 EEDA ; BIT 0 not used 0018 EEDA ; BIT 1 not used 0019 EEDA ; BIT 2 not used 0020 EEDA ; BIT 3 SHIFT 0021 EEDA ; BIT 4 not CAPITALS lock 0022 EEDA ; BIT 5 not SHIFT lock 0023 EEDA ; BIT 6 CTRL 0024 EEDA ; BIT 7 shift enable (only meaningful if a lock is active) 0025 EEDA ; SEQUENCE OF EVENTS :- 0026 EEDA ; 1. CHECK SHIFT KEY 0027 EEDA ; 2. CHECK CONTROL KEY 0028 EEDA ; 3. PROCESS CURRENT KEY 0029 EEDA ; 4. PROCESS OLD KEY 0030 EEDA ; 5. SCAN KEYS IF REQ'D 0031 EEDA ; 6. ENABLE CA2 IF REQ'D 0032 EEDA 0033 EEDA 0034 EEDA KBDAW 0035 EEDA A2 FF LDXIM &FF ;prepare to enable keyboard timer interrupts 0036 EEDC ; 0037 EEDC ; IF ALL KEYS UP & FORGOTTEN, RESTORE INTERRUPTS 0038 EEDC ; 0039 EEDC A5 EC LDA CKEY 0040 EEDE 05 ED ORA OKEY 0041 EEE0 D0 06 BNE KBDISX ;[at least one active key, so keep keyboard interrupt disabled] 0042 EEE2 ; 0043 EEE2 ; enable keyboard interrupt 0044 EEE2 ; 0045 EEE2 A9 81 LDAIM &81 0046 EEE4 8D 4E FE STA IERQ 0047 EEE7 E8 INX ;X:=0, disable keyboard timer interrupts 0048 EEE8 ; 0049 EEE8 KBDISX 0050 EEE8 8E 42 02 STX KSEMA ;set keyboard timer interrupt control flag 0051 EEEB ; $00 => disabled, $FF => enabled 0052 EEEB ; 0053 EEEB KBDIS 0054 EEEB 08 PHP 0055 EEEC ; disable keyboard, coping with CAPITALS & SHIFT lock LEDs 0056 EEEC AD 5A 02 LDA KSTAT 0057 EEEF ; isolate CAPITALS lock and SHIFT lock states 0058 EEEF 4A LSRA 0059 EEF0 29 18 ANDIM &18 0060 EEF2 ; update LED1 (CAPITALS lock) 0061 EEF2 09 06 ORAIM &06 ;use addressable latch output 6 0062 EEF4 8D 40 FE STA PBQ ;store LED1 0063 EEF7 ; update LED2 (SHIFT lock) 0064 EEF7 4A LSRA ;move state into bit3 0065 EEF8 09 07 ORAIM &07 ;use addressable latch output 7 0066 EEFA 8D 40 FE STA PBQ ;store LED2 0067 EEFD ; 0068 EEFD [ TRUE=0 0069 EEFD 20 2E F1 JSR KALLOX 0070 EF00 | 0073 EF00 ] 0074 EF00 ; 0075 EF00 68 PLA 0076 EF01 60 RTS 0077 EF02 0078 EF02 DEFKEY ;keyboard control effect 0079 EF02 ; 0080 EF02 ; entered with: 0081 EF02 ; C=0, V=0 => SHIFT/CTRL test 0082 EF02 ; C=1, V=0 => keyboard scan 0083 EF02 ; C=0, V=1 => keyboard interrupt 0084 EF02 ; C=1, V=1 => timer interrupt 0085 EF02 ; 0086 EF02 ; route keyboard entry reason 0087 EF02 ; 0088 EF02 50 0A BVC KEYV0 ;[V=0] 0089 EF04 ; 0090 EF04 A9 01 LDAIM &01 0091 EF06 8D 4E FE STA IERQ 0092 EF09 ; 0093 EF09 B0 08 BCS KYBD ;[timer interrupt entry] 0094 EF0B 4C 0F F0 JMP KBDAT ;[keyboard interrupt] 0095 EF0E ; 0096 EF0E KEYV0 0097 EF0E 90 06 BCC TSHIFT ;[SHIFT/CTRL test] 0098 EF10 4C D1 F0 JMP SKFMA ;C=1, scan keyboard 0099 EF13 0100 EF13 KYBD ;C=1 0101 EF13 ; entered when key(s) active AND timer interrupt 0102 EF13 ; 0103 EF13 ; ensure no more keyboard timer interrupts 0104 EF13 EE 42 02 INC KSEMA ;KSEMA := 0 0105 EF16 ; 0106 EF16 TSHIFT ;C=0 0107 EF16 ; entry point used by test shift routine (uses C=1) 0108 EF16 ; clear SHIFT and CTRL status 0109 EF16 AD 5A 02 LDA KSTAT 0110 EF19 29 B7 ANDIM CTLSHI ;N.B. A will accumulate new state 0111 EF1B ; set SHIFT key status 0112 EF1B A2 00 LDXIM ZERO ;N.B. SHIFT key is at matrix entry 0 0113 EF1D 20 2A F0 JSR KC ;get state of SHIFT key 0114 EF20 ; N.B. C not corrupted 0115 EF20 86 FA STX KTEMP ;save state of SHIFT key for SHIFT/CAPS invert feature 0116 EF22 ; KTEMP = 1xxx xxxx => SHIFT 0117 EF22 ; KTEMP = 0xxx xxxx => no SHIFT 0118 EF22 B8 CLV 0119 EF23 10 05 BPL KYBD1 ;[SHIFT key not active] 0120 EF25 ; shift key active and within timer interrupt routine 0121 EF25 2C B7 D9 BIT FFBYT 0122 EF28 09 08 ORAIM SHFT 0123 EF2A KYBD1 0124 EF2A ; set CTRL key status 0125 EF2A E8 INX ;X := 1, N.B. CTRL key is at matrix entry 1 0126 EF2B 20 2A F0 JSR KC ;get state of CTRL key 0127 EF2E 90 BB BCC KBDIS ;[testing CTRL and SHIFT, MI=>CTRL, V=>SHIFT] Acorn macro assembler Page 112 MOS56 Keyboard management 0128 EF30 10 02 BPL KYBD2 ;[CTRL key not active] 0129 EF32 ; CTRL key active 0130 EF32 09 40 ORAIM CTRL 0131 EF34 KYBD2 ;A has accumulated new keyboard status 0132 EF34 8D 5A 02 STA KSTAT ;update keyboard status 0133 EF37 ; evaluate status of the current key 0134 EF37 ; IF IT IS & WAS OPEN, THEN FORGET IT 0135 EF37 ; IF OPEN & WAS CLOSED, MARK AS OPEN 0136 EF37 ; IF CLOSED & WAS OPEN, MARK AS CLOSED 0137 EF37 ; IF CLOSED & WAS CLOSED, THEN DECREMENT 0138 EF37 ; AUTO-REPEAT COUNTER. IF THIS GOES TO 0139 EF37 ; ZERO (IT STARTS AT 1 INITIALLY) THEN 0140 EF37 ; TRANSMIT CHARACTER TO RDCH BUFFER 0141 EF37 ; (UNLESS IT IS SHF LOCK OR CAPS LOCK) 0142 EF37 ; IF AUTO REPEAT PERMANENTLY DISABLED 0143 EF37 ; THEN DON'T RESET THIS COUNTER. 0144 EF37 A6 EC LDX CKEY 0145 EF39 F0 12 BEQ KBDWU ;[no current key] 0146 EF3B ; current key exists 0147 EF3B 20 2A F0 JSR KC ;get status of current key 0148 EF3E 30 10 BMI KBDX ;[current key closed] 0149 EF40 ; current key open 0150 EF40 E4 EC CPX CKEY 0151 EF42 KBDW 0152 EF42 86 EC STX CKEY ;update open/closed state of current key 0153 EF44 D0 07 BNE KBDWU ;[current key: is open was closed, or is closed was open] 0154 EF46 ; CURRENT KEY HAS BEEN OPEN FOR TWO CLOCK 0155 EF46 ; CYCLES, SO 'FORGET' IT BY ZEROING CKEY 0156 EF46 ; (KEY VALUES START AT 16 IN THIS RTNE) 0157 EF46 ; ALSO SET COUNTER TO 1 0158 EF46 ; indicate no current key 0159 EF46 A2 00 LDXIM ZERO 0160 EF48 86 EC STX CKEY 0161 EF4A FCSP ;fix to CTRL/SHIFT h/w problem 0162 EF4A 20 1F F0 JSR AR ;update auto-repeat intervals 0163 EF4D KBDWU 0164 EF4D 4C E9 EF JMP KBDY 0165 EF50 KBDX ;current KEY IS CLOSED:IF WAS OPEN,SIMPLY 0166 EF50 ; UPDATE STATUS,ELSE CHECK COUNTER 0167 EF50 ; AND PROCESS CHAR IF REQ'D. 0168 EF50 E4 EC CPX CKEY 0169 EF52 D0 EE BNE KBDW ;[current key: is closed, was open] 0170 EF54 ; current key is closed and was closed 0171 EF54 A5 E7 LDA ARCTR 0172 EF56 F0 23 BEQ KBDXS ;[auto-repeat suppressed] 0173 EF58 ; decrement auto-repeat countdown 0174 EF58 C6 E7 DEC ARCTR 0175 EF5A D0 1F BNE KBDXS ;[auto-repeat interval not exhausted] 0176 EF5C ; auto-repeat interval exhausted 0177 EF5C ; auto-repeat countdown := delay/repeat period 0178 EF5C AD CA 02 LDA FARCTR 0179 EF5F 85 E7 STA ARCTR 0180 EF61 ; next auto-repeat interval := repeat period 0181 EF61 AD 55 02 LDA ARSET 0182 EF64 8D CA 02 STA FARCTR 0183 EF67 ; 0184 EF67 AD 5A 02 LDA KSTAT 0185 EF6A ; test for shift lock key 0186 EF6A A6 EC LDX CKEY 0187 EF6C E0 D0 CPXIM SHLKKY ;IS THIS THE SHIFT LOCK? 0188 EF6E D0 0E BNE KCPLK ;[key is not SHIFT lock] 0189 EF70 ; 0190 EF70 ; SHIFT LOCK key processing 0191 EF70 09 90 ORAIM CAPSL+INVERT ;clear CAPITALS lock state 0192 EF72 49 A0 EORIM SHFTL+INVERT ;flip SHIFT lock state and clear invert 0193 EF74 KEYBD3 ;update keyboard status 0194 EF74 8D 5A 02 STA KSTAT ;store SHIFT lock state 0195 EF77 ; suppress auto-repeat 0196 EF77 A9 00 LDAIM ZERO 0197 EF79 85 E7 STA ARCTR 0198 EF7B KBDXS 0199 EF7B 4C E9 EF JMP KBDY 0200 EF7E 0201 EF7E KCPLK ;CAPS key processing 0202 EF7E E0 C0 CPXIM CPLKKY 0203 EF80 D0 0F BNE KCPLK1 ;[not CAPITALS lock] 0204 EF82 ; clear SHIFT lock state 0205 EF82 09 A0 ORAIM SHFTL+INVERT 0206 EF84 ; add in SHIFT invert status 0207 EF84 24 FA BIT KTEMP 0208 EF86 10 04 BPL KCPLK2 ;[not SHIFT/CAPS] 0209 EF88 ; SHIFT/CAPS - force CAPS invert 0210 EF88 09 10 ORAIM CAPSL 0211 EF8A 49 80 EORIM INVERT 0212 EF8C KCPLK2 0213 EF8C ; flip CAPITALS lock state 0214 EF8C 49 90 EORIM CAPSL+INVERT 0215 EF8E ; set CAPITALS lock state and disable auto-repeat 0216 EF8E 4C 74 EF JMP KEYBD3 0217 EF91 0218 EF91 KCPLK1 0219 EF91 ; AT THIS POINT, WE HAVE A CHARACTER FOR RDCH 0220 EF91 ; NOW LOOK UP CODE AND MODIFY BY SHIFT 0221 EF91 ; CONTROL OR CAPS LOCK AS APPROPRIATE 0222 EF91 ; convert current key code to ASCII 0223 EF91 BD AB EF LDAAX KTBL -&80 0224 EF94 D0 03 BNE NTAB ;[not TAB key] 0225 EF96 ; TAB key 0226 EF96 AD 6B 02 LDA TABCOD 0227 EF99 NTAB 0228 EF99 0229 EF99 [ FALSE=0 0248 EF99 ] 0249 EF99 0250 EF99 ; setup for KSTAT tests 0251 EF99 AE 5A 02 LDX KSTAT 0252 EF9C 86 FA STX KTEMP 0253 EF9E ; check for CTRL 0254 EF9E 26 FA ROL KTEMP 0255 EFA0 10 07 BPL KCONV6 ;[no CTRL] 0256 EFA2 ; cannot support two-key rollover with CTRL (h/w constraint) 0257 EFA2 A6 ED LDX OKEY 0258 EFA4 FCSP1 ;chained branch 0259 EFA4 D0 A4 BNE FCSP ;[at least two keys pressed] 0260 EFA6 ; convert character to associated control character 0261 EFA6 20 BF EA JSR CTRLCH 0262 EFA9 KCONV6 0263 EFA9 ; check for SHIFT lock 0264 EFA9 26 FA ROL KTEMP 0265 EFAB 30 08 BMI KCONV3 ;[no SHIFT lock] 0266 EFAD ; shift character Acorn macro assembler Page 113 MOS56 Keyboard management 0267 EFAD 20 9C EA JSR SHIFT 0268 EFB0 26 FA ROL KTEMP ;skip over CAPITALS lock state 0269 EFB2 4C C1 EF JMP KCONV4 ;skip processing of CAPITALS lock 0270 EFB5 KCONV3 0271 EFB5 ; check for CAPS lock 0272 EFB5 26 FA ROL KTEMP 0273 EFB7 30 0D BMI KCONV2 ;[no CAPS lock or SHIFT lock] 0274 EFB9 ; convert character to upper case 0275 EFB9 ; check for character in the range 'A' to 'Z' or 'a' to 'z' 0276 EFB9 20 E3 E4 JSR CAPS 0277 EFBC B0 08 BCS KCONV2 ;[not alpha] 0278 EFBE ; character is an alpha 0279 EFBE 20 9C EA JSR SHIFT ;invert case of alpha 0280 EFC1 KCONV4 0281 EFC1 ; check for shift disabled 0282 EFC1 AE 5A 02 LDX KSTAT 0283 EFC4 10 0B BPL KCONV1 ;[shift disabled] 0284 EFC6 KCONV2 ;check for SHIFT 0285 EFC6 26 FA ROL KTEMP 0286 EFC8 10 07 BPL KCONV1 ;[no SHIFT] 0287 EFCA ; cannot support two-key rollover with SHIFT (h/w constraint) 0288 EFCA A6 ED LDX OKEY 0289 EFCC D0 D6 BNE FCSP1 ;[at least two keys pressed] 0290 EFCE ; shift character 0291 EFCE 20 9C EA JSR SHIFT 0292 EFD1 KCONV1 0293 EFD1 ; 0294 EFD1 ; check for interrupt character 0295 EFD1 ; 0296 EFD1 CD 6C 02 CMP INTCH 0297 EFD4 D0 07 BNE KESC1 ;[not interrupt character] 0298 EFD6 AE 75 02 LDX ESCHAR 0299 EFD9 D0 02 BNE KESC1 ;[treat as normal character] 0300 EFDB ; 0301 EFDB ; X=0, Z=1 0302 EFDB ; 0303 EFDB 86 E7 STX ARCTR ;suppress auto-repeat for escape if escape condition enabled 0304 EFDD KESC1 0305 EFDD ; 0306 EFDD ; allow interrupts 0307 EFDD ; 0308 EFDD A8 TAY ;Y := character (will be passed to RDCHS) 0309 EFDE 20 29 F1 JSR KALLOW 0310 EFE1 ; 0311 EFE1 ; insert character into RDCH buffer 0312 EFE1 ; 0313 EFE1 AD 59 02 LDA NETKDS 0314 EFE4 D0 03 BNE KBDY ;[keyboard disabled] 0315 EFE6 20 F1 E4 JSR RDCHS 0316 EFE9 ; 0317 EFE9 KBDY ; NOW WE EVALUATE THE OLD KEY STATUS. 0318 EFE9 ; IF OPEN FOR 2 CLOCK CYCLES, FORGET IT 0319 EFE9 ; OTHERWISE, SIMPLY MEMORISE IT! 0320 EFE9 A6 ED LDX OKEY 0321 EFEB F0 0B BEQ KBDA ;[old key does not exist] 0322 EFED ; 0323 EFED ; old key exists 0324 EFED 20 2A F0 JSR KC 0325 EFF0 86 ED STX OKEY ;remember old key state 0326 EFF2 30 04 BMI KBDA ;[old key closed] 0327 EFF4 ; 0328 EFF4 ; old key open 0329 EFF4 [ FALSE=0 0333 EFF4 ] 0334 EFF4 ; 0335 EFF4 ; old key: is open, was open 0336 EFF4 A2 00 LDXIM ZERO 0337 EFF6 86 ED STX OKEY ;indicate no old key 0338 EFF8 KBDA ; NOW CHECK TO SEE IF A SCAN IS NEEDED. 0339 EFF8 ; IF OLD KEY ZERO, DO SCAN. IF KEY DOWN & 0340 EFF8 ; NOT EQUAL CKEY THEN SET OLD=CURRENT, & THIS 0341 EFF8 ; ONE = CURRENT, RESET STATUS CHANGE BITS 0342 EFF8 A6 ED LDX OKEY 0343 EFFA D0 16 BNE KBDAU ;[old key exists] 0344 EFFC ; no old key so scan keyboard 0345 EFFC A0 EC LDYIM CKEY 0346 EFFE 20 CC F0 JSR ISCAN 0347 F001 30 09 BMI KBDAS ;[all keys searched] 0348 F003 ; closed key found other than current key 0349 F003 ; new current key found 0350 F003 ; set old key = current key 0351 F003 A5 EC LDA CKEY 0352 F005 85 ED STA OKEY 0353 F007 KBDAR ;set new current key 0354 F007 86 EC STX CKEY ;current key := new key number 0355 F009 20 1F F0 JSR AR ;update auto-repeat intervals 0356 F00C 4C DA EE KBDAS JMP KBDAW 0357 F00F KBDAT 0358 F00F ; ENTRY POINT FROM ANY KEY 0359 F00F ; DOWN INTERRUPT 0360 F00F ; enable keyboard by scanning random key (X) 0361 F00F 20 2A F0 JSR KC 0362 F012 KBDAU ;find new current key 0363 F012 A5 EC LDA CKEY 0364 F014 D0 F6 BNE KBDAS ;[current key exists, should only exist during power up] 0365 F016 ; scan keyboard matrix entries 0366 F016 A0 ED LDYIM OKEY 0367 F018 20 CC F0 JSR ISCAN 0368 F01B 30 EF BMI KBDAS ;[processed all keys] 0369 F01D ; pressed key found other than old key 0370 F01D ; new current key identified 0371 F01D 10 E8 BPL KBDAR ;[ALWAYS JUMP] 0372 F01F ; NEVER fall thru 0373 F01F 0374 F01F 0375 F01F AR ;set auto-repeat interval to reflect next character 0376 F01F A2 01 LDXIM &01 0377 F021 86 E7 STX ARCTR 0378 F023 ; set next auto-repeat interval to delay period 0379 F023 AE 54 02 LDX FARSET 0380 F026 8E CA 02 STX FARCTR 0381 F029 60 RTS 0382 F02A 0383 F02A 0384 F02A [ FALSE=0 0391 F02A ] 0392 F02A 0393 F02A KC 0394 F02A ; KEYBOARD ACCESS SUBROUTINE 0395 F02A ; read state of key 0396 F02A ; X = 0rrrcccc Acorn macro assembler Page 114 MOS56 Keyboard management 0397 F02A ; r = row, c = column 0398 F02A ; N.B. A and C not corrupted 0399 F02A [ 1=0 ;$Tutu 0411 F02A | 0412 F02A ; enable keyboard 0413 F02A A0 03 LDYIM &03 0414 F02C 8C 40 FE STY PBQ 0415 F02F ; select VIAA PA6-PA0 as outputs 0416 F02F A0 7F LDYIM &7F 0417 F031 8C 43 FE STY DDRAQ 0418 F034 8E 4F FE STX PAPQ ;select matrix element 0419 F037 AE 4F FE LDX PAPQ ;read element status: N=0 => open, N=1 => closed 0420 F03A 60 RTS 0421 F03B ] 0422 F03B 0423 F03B 0424 F03B 0425 F03B 0426 F03B ; KEY CONVERSION TABLE 0427 F03B ; ROW 0 0428 F03B ; not relevant 0429 F03B ; (consists of SHIFT, CTRL and start-up options) 0430 F03B KTBL0 0431 F03B F02B KTBL * KTBL0 -&10 0432 F03B ; ROW 1 0433 F03B 71 = "q" 0434 F03C 33 = "3" ;shift '#' 0435 F03D 34 = "4" ;shift '$' 0436 F03E 35 = "5" ;shift '%' 0437 F03F 84 = SOFTK4 ;f4 0438 F040 38 = "8" ;shift '(' 0439 F041 87 = SOFTK7 ;f7 0440 F042 2D = "-" ;shift '=' 0441 F043 5E = "^" ;shift '~' 0442 F044 8C = CURLFT ;cursor left (fC) 0443 F045 0444 F045 ; 'hide' 6 bytes 0445 F045 OLDKEY ;force old key state 0446 F045 84 EC STY CKEY ;CKEY := 0 0447 F047 86 ED STX OKEY ;force old key state 0448 F049 60 RTS 0449 F04A 00 = NULL ;pad to 6 bytes 0450 F04B 0451 F04B ; ROW 2 0452 F04B 80 = SOFTK0 ;f0 0453 F04C 77 = "w" 0454 F04D 65 = "e" 0455 F04E 74 = "t" 0456 F04F 37 = "7" ;shift single quote 0457 F050 69 = "i" 0458 F051 39 = "9" ;shift ')' 0459 F052 30 = "0" ;same shifted 0460 F053 POUNDM 0461 F053 5F = "_" ;shift POUND 0462 F054 8E = CURDWN ;cursor down (fE) 0463 F055 0464 F055 ; 'hide' 6 bytes 0465 F055 6C FE FD JMITST JMI TSTSFT 0466 F058 6C FA 00 JMI JMI JMILO ;jump to specific OSBYTE routine, C=1 0467 F05B 0468 F05B ; ROW 3 0469 F05B 31 = "1" ;shift '!' 0470 F05C 32 = "2" ;shift double quote 0471 F05D 64 = "d" 0472 F05E 72 = "r" 0473 F05F 36 = "6" ;shift '&' 0474 F060 75 = "u" 0475 F061 6F = "o" 0476 F062 70 = "p" 0477 F063 5B = "[" ;shift curly left bracket 0478 F064 8F = CURUP ;cursor up (fF) 0479 F065 0480 F065 ; 'hide' 6 bytes 0481 F065 2C B7 D9 JMIKYV BIT FFBYT 0482 F068 6C 28 02 JMIKEY JMI KEYVEC 0483 F06B 0484 F06B ; ROW 4 0485 F06B 01 = &01 ;CAPS lock 0486 F06C 61 = "a" 0487 F06D 78 = "x" 0488 F06E 66 = "f" 0489 F06F 79 = "y" 0490 F070 6A = "j" 0491 F071 6B = "k" 0492 F072 40 = AT ;same shifted 0493 F073 3A = ":" ;shift '*' 0494 F074 0D = MCR ;same shifted 0495 F075 0496 F075 ; 'hide' 6 bytes 0497 F075 SENDD 0498 F075 00 = &00 ;inputs 0499 F076 FF = &FF ;outputs 0500 F077 SENDS 0501 F077 01 = &01 ;read enable 0502 F078 02 = &02 ;write enable 0503 F079 SENDF 0504 F079 09 = &09 ;read disable 0505 F07A 0A = &0A ;write disable 0506 F07B 0507 F07B ; ROW 5 0508 F07B 02 = &02 ;SHIFT lock 0509 F07C 73 = "s" 0510 F07D 63 = "c" 0511 F07E 67 = "g" 0512 F07F 68 = "h" 0513 F080 6E = "n" 0514 F081 6C = "l" 0515 F082 3B = ";" ;shift '+' 0516 F083 5D = "]" ;shift curly right bracket 0517 F084 7F = MDEL ;same shifted 0518 F085 0519 F085 ; 'hide' 6 bytes 0520 F085 RMLA ;read machine low memory address 0521 F085 AC 44 02 LDY HWM 0522 F088 A2 00 LDXIM ZERO 0523 F08A 60 RTS 0524 F08B 0525 F08B ; ROW 6 0526 F08B 00 = ZERO ;TAB - programmable TAB key 0527 F08C 7A = "z" 0528 F08D 20 = SPACE ;same shifted Acorn macro assembler Page 115 MOS56 Keyboard management 0529 F08E 76 = "v" 0530 F08F 62 = "b" 0531 F090 6D = "m" 0532 F091 2C = "," ;shift '<' 0533 F092 2E = "." ;shift '>' 0534 F093 2F = "/" ; shift '?' 0535 F094 8B = MCOPY ;copy character at cursor (fB) 0536 F095 0537 F095 ; 'hide' 6 bytes 0538 F095 JFLUSH ;flush input buffer and clear soft key expansion 0539 F095 AE 41 02 LDX RDCHSW ;X := input bufferid 0540 F098 FLUSH2 0541 F098 4C AD E1 JMP PURGE ;purge buffer AND return 0542 F09B 0543 F09B ; ROW 7 0544 F09B 1B = ESC ;same shifted 0545 F09C 81 = SOFTK1 ;f1 0546 F09D 82 = SOFTK2 ;f2 0547 F09E 83 = SOFTK3 ;f3 0548 F09F 85 = SOFTK5 ;f5 0549 F0A0 86 = SOFTK6 ;f6 0550 F0A1 88 = SOFTK8 ;f8 0551 F0A2 89 = SOFTK9 ;f9 0552 F0A3 5C = "\" ;shift '|' 0553 F0A4 8D = CURRHT ;cursor right (fD) 0554 F0A5 ENDKT 0555 F0A5 0556 F0A5 0557 F0A5 6C 20 02 JMIEVT JMI EVTVEC ;user event 0558 F0A8 0559 F0A8 0560 F0A8 FLUSHC ;flush buffer 0561 F0A8 D0 EB BNE JFLUSH ;[flush currently selected input buffer] 0562 F0AA ; X=0 => flush all buffers 0563 F0AA FLSHAL ;flush all buffers 0564 F0AA A2 08 LDXIM BUPB 0565 F0AC FLUSH3 0566 F0AC ; allow interrupts 0567 F0AC 58 CLI 0568 F0AD 78 SEI 0569 F0AE 20 B4 F0 JSR FLUSHS ;flush buffer given by X 0570 F0B1 CA DEX 0571 F0B2 10 F8 BPL FLUSH3 0572 F0B4 ; 0573 F0B4 ; N.B. X<0, so is an invalid bufferid (and will be ignored by FLUSHS) 0574 F0B4 ; 0575 F0B4 FLUSHS ;flush specific buffer 0576 F0B4 E0 09 CPXIM BUPB +&01 0577 F0B6 90 E0 BCC FLUSH2 ;[valid bufferid] 0578 F0B8 ; invalid bufferid 0579 F0B8 60 RTS 0580 F0B9 0581 F0B9 0582 F0B9 HELP ;*HELP command 0583 F0B9 A2 09 LDXIM SVHELP 0584 F0BB 20 68 F1 JSR SVOP ;Y = offset within line of arguments 0585 F0BE ; 0586 F0BE ; Y preserved, therefore Y>=2 on return 0587 F0BE ; 0588 F0BE 20 4A FA JSR STROUT ;needs Y<>0 to print 0589 F0C1 0D = MCR 0590 F0C2 4F 53 20 = "OS " 0591 F0C5 31 = VERA 0592 F0C6 2E = "." 0593 F0C7 32 = VERB 0594 F0C8 30 = VERC 0595 F0C9 0D = MCR 0596 F0CA 00 = ZERO 0597 F0CB ; 0598 F0CB 60 RTS 0599 F0CC 0600 F0CC 0601 F0CC ISCAN ;scan keys from matrix address $10 0602 F0CC 18 CLC ;ignore key addressed by Y 0603 F0CD ; 0604 F0CD XSCANA ;FX entry, scan keys from matrix address $10, C=1 (ignore no keys) 0605 F0CD A2 10 LDXIM &10 0606 F0CF ; 0607 F0CF XSCANB ;FX entry, scan keys from matrix address X, C=1 (ignore no keys) 0608 F0CF B0 97 BCS JMIKEY ;[route FX entries thru indirection] 0609 F0D1 ; 0610 F0D1 SKFMA ;scan keys from matrix address (should have C=1) 0611 F0D1 ; start scan address in X 0612 F0D1 ; X>=0 => scan keys starting at X 0613 F0D1 ; X<0 => investigate key NOT(X) 0614 F0D1 ; 0615 F0D1 8A TXA 0616 F0D2 10 05 BPL SKFMA2 ;[scan keys] 0617 F0D4 ; C=1 0618 F0D4 ; look at key 0619 F0D4 ; 0620 F0D4 20 2A F0 JSR KC ;result in top bit of X (N.B. does not alter C) 0621 F0D7 ; C=1 0622 F0D7 B0 55 BCS KALLOX ;return result in A 0623 F0D9 ; 0624 F0D9 SKFMA2 0625 F0D9 ; 0626 F0D9 08 PHP ;save request source indicator (in C) 0627 F0DA 90 02 BCC SKFMA1 ;[CKEY or OKEY entry] 0628 F0DC A0 EE LDYIM CKEY+&02 0629 F0DE SKFMA1 0630 F0DE ; 0631 F0DE 99 DF 01 STAAY KSCSTA-CKEY ;save scan start address 0632 F0E1 ; return MI => no keys, otherwise X = key 0633 F0E1 A2 09 LDXIM &09 0634 F0E3 ; 0635 F0E3 ISCAN1 0636 F0E3 ; allow interrupts 0637 F0E3 ; 0638 F0E3 20 29 F1 JSR KALLOW 0639 F0E6 ; 0640 F0E6 ; select VIAA PA6-PA0 as outputs 0641 F0E6 ; 0642 F0E6 A9 7F LDAIM &7F 0643 F0E8 8D 43 FE STA DDRAQ 0644 F0EB ; 0645 F0EB ; claim keyboard 0646 F0EB ; 0647 F0EB A9 03 LDAIM &03 0648 F0ED 8D 40 FE STA PBQ 0649 F0F0 ; Acorn macro assembler Page 116 MOS56 Keyboard management 0650 F0F0 ; reset keyboard interrupt line 0651 F0F0 ; 0652 F0F0 A9 0F LDAIM &0F ;N.B. use non-existent group which does not interrupt 0653 F0F2 8D 4F FE STA PAPQ 0654 F0F5 ; 0655 F0F5 ; clear latched event 0656 F0F5 ; 0657 F0F5 A9 01 LDAIM &01 0658 F0F7 8D 4D FE STA IFRQ 0659 F0FA ; 0660 F0FA 8E 4F FE STX PAPQ ;select key (force no key first time thru loop) 0661 F0FD 0662 F0FD 2C 4D FE BIT IFRQ ;test for latched event 0663 F100 F0 21 BEQ ISCAND ;[no group key pressed] 0664 F102 ; 0665 F102 ; key pressed in this group 0666 F102 ; 0667 F102 8A TXA ;A := key at start of group 0668 F103 ; 0669 F103 ISCANC ;scan group to find pressed key within group 0670 F103 ; check key against start scan address 0671 F103 ; 0672 F103 D9 DF 01 CMPAY KSCSTA-CKEY 0673 F106 90 16 BCC ISCANE ;[ignore key] 0674 F108 ; 0675 F108 8D 4F FE STA PAPQ 0676 F10B 2C 4F FE BIT PAPQ 0677 F10E 10 0E BPL ISCANE ;[individual key not pressed] 0678 F110 ; 0679 F110 ; individual key pressed 0680 F110 ; 0681 F110 ISCANB ;key press detected at key A 0682 F110 ; 0683 F110 ; key found 0684 F110 ; 0685 F110 28 PLP 0686 F111 08 PHP 0687 F112 B0 13 BCS ISCAN9 ;[ignore no character] 0688 F114 ; 0689 F114 48 PHA ;save key code 0690 F115 ; 0691 F115 ; check whether to ignore character 0692 F115 ; 0693 F115 59 00 00 EORAY ZERO 0694 F118 0A ASLA ;ignore top bit 0695 F119 C9 01 CMPIM &01 0696 F11B 68 PLA ;restore key code 0697 F11C B0 09 BCS ISCAN9 ;[accept key] 0698 F11E ; 0699 F11E ; ignore key 0700 F11E ; 0701 F11E ISCANE ;ignore key 0702 F11E 18 CLC 0703 F11F 69 10 ADCIM &10 0704 F121 10 E0 BPL ISCANC ;[step to next key within group] 0705 F123 ; 0706 F123 ; key group exhausted 0707 F123 ; 0708 F123 ISCAND ;scan within group failed 0709 F123 CA DEX 0710 F124 10 BD BPL ISCAN1 ;[try next group] 0711 F126 ; no key found, X<0 0712 F126 8A TXA ;set up to negate effect of TAX 0713 F127 ; 0714 F127 ISCAN9 ;accept key 0715 F127 AA TAX ;X := key address 0716 F128 ; 0717 F128 28 PLP 0718 F129 ; 0719 F129 KALLOW ;release keyboard and allow interrupts 0720 F129 ; **** MUST NOT CORRUPT Y **** 0721 F129 ; release keyboard 0722 F129 ; 0723 F129 20 2E F1 JSR KALLOX ;release keyboard 0724 F12C ; 0725 F12C ; allow interrupts 0726 F12C ; 0727 F12C 58 CLI 0728 F12D 78 SEI 0729 F12E ; 0730 F12E KALLOX ;release keyboard 0731 F12E A9 0B LDAIM &0B 0732 F130 8D 40 FE STA PBQ 0733 F133 ; 0734 F133 ; return result in N 0735 F133 ; 0736 F133 8A TXA ;N=1 => no new key, N=0 => new key in X 0737 F134 60 RTS 0738 F135 0739 F135 0740 F135 0741 F135 < 3 0742 F135 0743 F135 LNK MOS70 0001 F135 TTL C.F.S. Manifest File - MOS70 0002 F135 OPT &01 0003 F135 0004 F135 0005 MOS70 * DEFOPT 0005 F135 0005 MOS72 * DEFOPT 0006 F135 0005 MOS74 * DEFOPT 0007 F135 0005 MOS76 * DEFOPT 0008 F135 0009 F135 OPT MOS70 Acorn macro assembler Page 117 C.F.S. Manifest File - MOS70 0010 F135 0011 F135 < &0003 0012 F135 > &0002 0013 F135 0014 F135 0015 F135 ;****** C.F.S HEADER FILE ****** 0016 F135 0017 F135 0018 F135 0019 F135 ;cIOBYTS * $00 ;No longer used 0020 F135 0000 LENSW * &00 ;Zero => LOAD modify's OSFILE block 0021 F135 0001 DEBUG * &01 ;zero => messages. +ve => no messages 0022 F135 0000 TUBESW * &00 ;Zero => tube, +ve => no tube 0023 F135 00FF PREMRG * &FF ;Zero => entry indirections, +ve => none 0024 F135 00FF GLYN * &FF ;Zero => special IBG code for 0025 F135 ;Glynn. +ve => as per spec. 0026 F135 0027 F135 ;MANIFESTS 0028 F135 0029 F135 00FE ENDBYT * &FE ;Byte after end of file (GETBYT) 0030 F135 0031 F135 0091 FXCDRV * &0091 ;FX call number 0032 F135 00FF READFX * &FF 0033 F135 0000 WRITFX * &00 0034 F135 0035 F135 0001 INHAND * &0001 ;Input handle 0036 F135 0002 OUTHND * &0002 ;Output handle 0037 F135 0003 HNDS * &03 ;Both handles 0038 F135 00FD NOUTHD * &FD 0039 F135 000B FTSIZE * &000B ;File title size (incl. CR) 0040 F135 0041 F135 ;Note that the 6850 status bytes (following) 0042 F135 ;have their bottom nybble modified according to 0043 F135 ;the setting of SPEED in the routines RXINIT and TXINIT 0044 F135 0045 F135 0030 TXSTAT * &30 ;6850 TX status 0046 F135 ;TXSTAT = ~RTS lo;TXI enabled;8 bits + 1 stop 0047 F135 00D0 RXSTAT * &D0 0048 F135 ;RXSTAT = ~RTS hi;TXI disabled;8 bits + 1 stop 0049 F135 0050 F135 0002 TXBIT * &02 0051 F135 0001 RXBIT * &01 0052 F135 0004 DCDBIT * &04 0053 F135 0054 F135 0085 SERON * &85 ;Motor on/cass. on/RXCLK=0/TXCLK= 1,0,1 0055 F135 0005 SEROFF * &05 ;As SERON but motor off 0056 F135 ;ERRORS 0057 F135 0058 F135 00DF ERRBAS * &DF 0059 F135 0060 F135 00DF CFSERD * ERRBAS -&00 ;EOF 0061 F135 00DE CFSERB * ERRBAS -&01 ;Channel 0062 F135 00DD CFSERK * ERRBAS -&02 ;Address 0063 F135 00DC SYNXER * ERRBAS -&03 ;Syntax 0064 F135 00DB CFSERF * ERRBAS -&04 ;File 0065 F135 00DA CFSERH * ERRBAS -&05 ;Block 0066 F135 00D9 CFSERI * ERRBAS -&06 ;Header 0067 F135 00D8 CFSERJ * ERRBAS -&07 ;Data 0068 F135 00D8 CFSERR * CFSERJ ;Bad tape 0069 F135 0070 F135 00D7 SFSERR * ERRBAS -&08 ;Bad ROM 0071 F135 00D6 SFSER1 * ERRBAS -&09 ;File not found 0072 F135 0073 F135 00D5 CFSERL * ERRBAS -&0A ;Locked 0074 F135 0075 F135 0076 F135 ;STATUS BYTE MASKS 0077 F135 0078 F135 0001 INOPEN * &01 0079 F135 0002 OUTOPN * &02 0080 F135 0040 LSTBYT * &40 ;Last byte read (GETBYTE) 0081 F135 0080 EOFBIT * &80 ;Last byte +1 read (GETBYTE) 0082 F135 00C0 LSTEOF * &C0 ;Last byte & EOF 0083 F135 0084 F135 00F7 NCTBIT * &F7 ;Complement of CATBIT 0085 F135 003F NEFBIT * &3F ;Complement of EOFBIT/lastbyte 0086 F135 00FE NINHND * &FE ;Complement of INHAND 0087 F135 003E NECBIT * &3E ;Complement of EOFBIT/lastbyte/openin bit 0088 F135 0089 F135 0090 F135 0091 F135 ;MESSAGE/ERROR SELECTION MASKS 0092 F135 0093 F135 0094 F135 00CC ERRMSK * &CC ;Error bits to zero 0095 F135 0033 MSGMSK * &33 ;Message bits to zero 0096 F135 0088 MSGS1 * &88 ;Short messages 0097 F135 00CC MSGS2 * &CC ;Long messages 0098 F135 0099 F135 0011 ABTBIT * &11 ;Abort set 0100 F135 0022 RETBIT * &22 ;Retry set 0101 F135 0000 IGBIT * &00 ;Both error bits off => ignore 0102 F135 0030 NIGBIT * &30 ;Complement of ignore bits 0103 F135 0104 F135 00A1 DEFLT * &A1 0105 F135 0106 F135 ;Default is retry/messages for loaded and saved 0107 F135 ;files, abort/no messages for sequential files. 0108 F135 0109 F135 0110 F135 ;INFO FIELDS 0111 F135 0112 F135 000C BKINFO * FTSIZE +&01 0113 F135 000C BKLOAD * BKINFO 0114 F135 000C BKLDLO * BKLOAD 0115 F135 000D BKLDHI * BKLDLO +&01 0116 F135 0010 BKEXEC * BKLOAD +&04 0117 F135 0014 BKNOLO * BKEXEC +&04 0118 F135 0015 BKNOHI * BKNOLO +&01 ;Block no. (lo & hi) 0119 F135 0016 BKSZEL * BKNOHI +&01 0120 F135 0017 BKSZEH * BKSZEL +&01 0121 F135 0018 BKFLAG * BKSZEH +&01 ;b7 => last block 0122 F135 0019 BKSPAR * BKFLAG +&01 0123 F135 001D BKLAST * BKSPAR +&04 ;Length of info. 0124 F135 0125 F135 001D BKWORKK * BKLAST 0126 F135 001E BKWRK1 * BKWORKK +&01 0127 F135 001F BKWRK2 * BKWRK1 +&01 0128 F135 0129 F135 0130 F135 Acorn macro assembler Page 118 C.F.S. Manifest File - MOS70 0131 F135 0132 F135 ;BLOCK FLAG MASKS 0133 F135 0134 F135 0080 LASTBK * &80 ;NOTE - don't change, BMI and BVS etc. used 0135 F135 0136 F135 0137 F135 0138 F135 ;TIMES 0139 F135 0140 F135 0019 DEFGAP * &19 ;25/10 Secs inter block gap 0141 F135 0006 GAP * &06 ;SAVE/LOAD gap 0142 F135 0143 F135 0144 F135 ;BITS AND PIECES 0145 F135 0146 F135 0147 F135 0148 F135 0149 F135 0008 CATBIT * &08 ;Doing a CAT 0150 F135 0088 MONBIT * &88 ;Messages on/off 0151 F135 0152 F135 0153 F135 02EA INBSZE * CFSA ;GBYT block size (retained over FS change) 0154 F135 02EC BUFFLG * INBSZE +&02 ;Note BUFFLG & INBZSE must be contig. 0155 F135 0156 F135 02ED FINBYT * CFSD ;Last byte in GETBYT buffer 0157 F135 0158 F135 ;BUFFERS 0159 F135 0160 F135 0A00 INBUFR * &0A00 0161 F135 0900 OUTBFR * &0900 ;Sequential access I/O buffers 0162 F135 0163 F135 ;VARS 0164 F135 0165 F135 0380 VARSS * &0380 0166 F135 0300 VARPGE * &0300 0167 F135 0168 F135 0380 OUTHDR * VARSS ;Header buffer for PUTBYTE 0169 F135 039D OUTPTR * OUTHDR +BKLAST 0170 F135 039E INPTR * OUTPTR +&01 0171 F135 039F INLDEX * INPTR +&01 ;8 bytes load/exec for input file 0172 F135 03A7 INFILE * INLDEX +&08 ;GETBYTE file name 0173 F135 03B2 INFO * INFILE +FTSIZE ;Header buffer 0174 F135 03CF WORKK * INFO +BKWORKK ;Space to read CRC during RDHEAD 0175 F135 03D1 SEQGAP * WORKK +&02 0176 F135 03D2 FILNAM * SEQGAP +&01 0177 F135 03DD NEXTIN * FILNAM +FTSIZE ;Next expected block (GETBYTE) 0178 F135 03DF OLDFLG * NEXTIN +&02 0179 F135 0180 F135 03CB SRPTR * INFO +BKSPAR 0181 F135 0182 F135 0183 F135 ;CHIP LOCATIONS 0184 F135 0185 F135 FE08 STATUS * &FE08 0186 F135 FE09 PORT * &FE09 0187 F135 0188 F135 0189 F135 0190 F135 ;DOS/MOS ROUTINES & ADDRESSES 0191 F135 0192 F135 0193 F135 00FF ESCADD * &00FF ;b7 = 1 if ESCAPE occured 0194 F135 0195 F135 0196 F135 ;TUBE THINGS 0197 F135 0198 F135 0000 TUBER * &00 ;Value in A for tube READ initialisation 0199 F135 0001 TUBEW * &01 ;Value in A for tube WRITE initialisation 0200 F135 0004 TUBEX * &04 ;Value in A for tube execute 0201 F135 0202 F135 0080 TUBERL * &80 ;A reg. for tube RELEASE 0203 F135 00C0 TUBECL * &C0 ;A reg. for tube CLAIM 0204 F135 0205 F135 002B SFSEND * "+" ;Marker for end of SERROM 0206 F135 0207 F135 ; interface to code in MOS 0208 F135 ; 0209 F135 0210 F135 0211 F135 LNK MOS72 0001 F135 ; FILE -> MOS72 0002 F135 0003 F135 START 0004 F135 0005 F135 TTL C.F.S. Main Routines - INIT 0006 F135 OPT MOS72 Acorn macro assembler Page 119 C.F.S. Main Routines - INIT 0007 F135 0008 F135 0009 F135 CROM ;A=$8D, V=0 0010 F135 TAPE ;A=$8C, V=0 0011 F135 49 8C EORIM &8C 0012 F137 TAPE12 ;used by RESET, A=X=$00 0013 F137 0A ASLA 0014 F138 8D 47 02 STA SROMSW ;A=0 => *TAPE, A=2 => *ROM 0015 F13B E0 03 CPXIM &03 ;test for *TAPE3 0016 F13D 4C 4B F1 JMP SOFTPT ;[ALWAYS jump] 0017 F140 0018 F140 0019 F140 INIT 0020 F140 0021 F140 ;Initialises CLI and file operation 0022 F140 ;vectors. Motor turned OFF 0023 F140 0024 F140 ;Z set => 300 baud => speed nybble = 6 0025 F140 ;Z unset => 1200 baud => speed nybble = 5 0026 F140 0027 F140 ;Speed nybble is OR'd in with 0028 F140 ;6850 status byte during TX/RXinit 0029 F140 0030 F140 08 PHP 0031 F141 A9 A1 LDAIM DEFLT 0032 F143 85 E3 STA OPTS ;User status = retry & msgs on 0033 F145 A9 19 LDAIM DEFGAP 0034 F147 8D D1 03 STA SEQGAP 0035 F14A 28 PLP 0036 F14B 0037 F14B ;Note CFSTAT (CFS0) set to zero by MOS free of charge 0038 F14B ;on hard reset 0039 F14B 0040 F14B SOFTPT ;Soft entry point (*TAPE) 0041 F14B 08 PHP 0042 F14C A9 06 LDAIM FSDIE 0043 F14E 20 31 E0 JSR JMIFSC ;present command to file system 0044 F151 A2 06 LDXIM &06 0045 F153 28 PLP 0046 F154 F0 01 BEQ INITON 0047 F156 CA DEX 0048 F157 86 C6 INITON STX SPEED 0049 F159 ; 0050 F159 ; initialise filing system indirection table 0051 F159 ; 0052 F159 A2 0E LDXIM &0E 0053 F15B BD 51 D9 INITLP LDAAX CFSTAB -&01 0054 F15E 9D 11 02 STAAX FILVEC -&01 0055 F161 CA DEX 0056 F162 D0 F7 BNE INITLP 0057 F164 86 C2 STX ITYPE ;No i'rupts pending 0058 F166 ; 0059 F166 ; inform paged ROMs of change 0060 F166 ; 0061 F166 A2 0F LDXIM SVFSIC 0062 F168 ; 0063 F168 SVOP ;issue service ROM operati 0064 F168 ; optype in X 0065 F168 A5 F4 LDA ROMID ;save current ROM id 0066 F16A 48 PHA 0067 F16B 8A TXA ;A = optype 0068 F16C ; 0069 F16C A2 0F LDXIM NROM-&1 0070 F16E SVOP1 0071 F16E [ $Tutu ; Less farting about with page 02 0077 F16E | 0078 F16E FE A1 02 INCAX ROMS ;test 0079 F171 DE A1 02 DECAX ROMS ;ROMS 0080 F174 10 0D BPL SVOP2 ;[not a service ROM] 0081 F176 ] 0082 F176 ; found a service ROM 0083 F176 86 F4 STX ROMID 0084 F178 8E 30 FE STX ROM 0085 F17B ; call service routine 0086 F17B 20 03 80 JSR ROMSFT ;initialise service ROM 0087 F17E AA TAX 0088 F17F F0 05 BEQ SVOP3 ;[service claimed, do not offer to other ROMs] 0089 F181 ; 0090 F181 A6 F4 LDX ROMID ;restore ROM id 0091 F183 SVOP2 0092 F183 CA DEX 0093 F184 10 E8 BPL SVOP1 0094 F186 ; X<>0 0095 F186 SVOP3 ;C = return code 0096 F186 ; restore caller's ROMid 0097 F186 68 PLA 0098 F187 85 F4 STA ROMID 0099 F189 8D 30 FE STA ROM 0100 F18C ; restore return code 0101 F18C 8A TXA ;A=0 => claimed, A<>0 => not claimed 0102 F18D 60 RTS 0103 F18E 0104 F18E 0105 F18E TTL C.F.S. Main Routines - ARGGO 0106 F18E OPT &01 0107 F18E 0108 F18E 0109 F18E ;Returns 1 if in 1200 baud cassette 0110 F18E ;2 300 0111 F18E ;3 if in SERROM filing system 0112 F18E 0113 F18E ;Note SPEED is 5 if in 1200 and 6 in 300 0114 F18E 0115 F18E 0116 F18E ARGGO 0117 F18E 09 00 ORAIM 0 0118 F190 D0 10 BNE INTRTS ;No action on non-zero entry condition 0119 F192 C0 00 CPYIM &00 0120 F194 D0 0C BNE INTRTS ;If handle not zero -> don't do 0121 F196 A5 C6 LDA SPEED 0122 F198 29 FB ANDIM &FB ;Subtract 4 0123 F19A 0D 47 02 ORA SROMSW 0124 F19D 0A ASLA 0125 F19E 0D 47 02 ORA SROMSW 0126 F1A1 4A LSRA ;Uses the fact that SROMSW is either 0 or 2 0127 F1A2 60 INTRTS RTS 0128 F1A3 0129 F1A3 0130 F1A3 TTL C.F.S Main Routines - FSFUNC 0131 F1A3 OPT &01 0132 F1A3 Acorn macro assembler Page 120 C.F.S Main Routines - FSFUNC 0133 F1A3 JMPTAB 0134 F1A3 4C F5 & CFSOPT-&01 0135 F1A5 1D F6 & CFSEOF-&01 0136 F1A7 04 F3 & RUN-&01 ;"*." 0137 F1A9 0F E3 & MBDCMD-&01 ;"*" = Bad command 0138 F1AB 04 F3 & RUN-&01 ;"*RUN " 0139 F1AD 2A F3 & CAT-&01 0140 F1AF 74 E2 & SHUTES-&01 ;die 0141 F1B1 0007 NOTAB * .-JMPTAB:SHR: 1 0142 F1B1 0143 F1B1 FSFUNC 0144 F1B1 0145 F1B1 ;File system operation entry pt. 0146 F1B1 0147 F1B1 C9 07 CMPIM NOTAB 0148 F1B3 B0 ED BCS INTRTS ;Check call legal otherwise, exit 0149 F1B5 0150 F1B5 86 BC STX TEMP 0151 F1B7 0A ASLA 0152 F1B8 AA TAX ;Get address from table 0153 F1B9 BD A4 F1 LDAAX JMPTAB +&01 0154 F1BC 48 PHA ;push hi byte 0155 F1BD BD A3 F1 LDAAX JMPTAB 0156 F1C0 48 PHA ;push lo byte 0157 F1C1 A6 BC LDX TEMP ;Restore argument 0158 F1C3 60 RTS ;enter routine 0159 F1C4 0160 F1C4 TTL C.F.S. Main Routines - LOAD 0161 F1C4 OPT &01 0162 F1C4 0163 F1C4 0164 F1C4 ;*********** 0165 F1C4 ;* L O A D * 0166 F1C4 ;*********** 0167 F1C4 0168 F1C4 0169 F1C4 ;On entry A NZ => load from OSFILE 0170 F1C4 ; A =0 => load and run 0171 F1C4 ;Differentiating between these is necessary 0172 F1C4 ;so that the protection bit in the flags 0173 F1C4 ;byte can be checked. 0174 F1C4 0175 F1C4 0176 F1C4 LOADGO 0177 F1C4 0178 F1C4 08 PHP ;Store interrupt status 0179 F1C5 48 PHA ;Store indication of load or load/run 0180 F1C6 20 27 FB JSR SETDEF ;Set defaults if nesc. 0181 F1C9 0182 F1C9 AD C2 03 LDA INFO +BKEXEC 0183 F1CC 48 PHA ;EQ=> use addr. from C.line or OSFILE 0184 F1CD 0185 F1CD 20 31 F6 JSR SRCH0 ;Find file on tape. 0186 F1D0 LOADL6 0187 F1D0 0188 F1D0 68 PLA 0189 F1D1 F0 1A BEQ LOADLB ;Use load address from command line or OSFILE 0190 F1D3 0191 F1D3 ;Move load address from OSFILE command block 0192 F1D3 ;and check if is $FFFFFFFF, in which case 0193 F1D3 ;give BAD ADDRESS error 0194 F1D3 0195 F1D3 A2 03 LDXIM &03 0196 F1D5 A9 FF LDAIM &FF 0197 F1D7 48 LOADL1 PHA ;Push cumulative AND of address 0198 F1D8 BD BE 03 LDAAX INFO +BKLOAD ;Address from command block 0199 F1DB 95 B0 STAAX BKADDR 0200 F1DD 68 PLA 0201 F1DE 35 B0 ANDAX BKADDR 0202 F1E0 CA DEX 0203 F1E1 10 F4 BPL LOADL1 0204 F1E3 0205 F1E3 C9 FF CMPIM &FF ;If $FF, all bytes are $FF => error 0206 F1E5 D0 06 BNE LOADLB ;Continue load 0207 F1E7 0208 F1E7 20 E8 FA JSR BEEPOF ;Motor off/beep 0209 F1EA 4C 67 E2 JMP MBADHX 0210 F1ED 0211 F1ED AD CA 03 LOADLB LDA INFO +BKFLAG ;Check protection bit 0212 F1F0 4A LSRA ;CS -> prot. CC -> unprot 0213 F1F1 68 PLA ;Check if loading and running 0214 F1F2 F0 0E BEQ LOADLC ;Yes => carry on 0215 F1F4 90 13 BCC LOADLA ;Not protected -> carry on 0216 F1F6 0217 F1F6 20 F2 FA PROTER JSR CASMOF ;Turn motor off 0218 F1F9 ;Also called from RDBFER 0219 F1F9 0220 F1F9 00 BRK 0221 F1FA D5 = CFSERL 0222 F1FB 4C 6F 63 = "Locked" 0223 F201 00 = &00 0224 F202 0225 F202 LOADLC 0226 F202 90 05 BCC LOADLA ;Loading/running & unprotected 0227 F204 A9 03 LDAIM &03 0228 F206 8D 58 02 STA CRIT ;Loading/running & prot., so disable ESCAPE and trap BREAK 0229 F209 LOADLA 0230 F209 A9 30 LDAIM NIGBIT 0231 F20B 25 BB AND USFLGS 0232 F20D F0 04 BEQ LOADL8 ;If ignore set, just read block 0233 F20F A5 C1 LDA HDRCRC ;Check hdr. checksum 0234 F211 0235 F211 ;Don't start bg job if header CRC is no good, 0236 F211 ;otherwise data may be loaded somewhere strange 0237 F211 0238 F211 D0 0A BNE LOADL7 0239 F213 98 LOADL8 TYA 0240 F214 48 PHA ;Store "Loading" flag 0241 F215 20 BB FB JSR TWINIT ;Initialise tube for writing if nesc. 0242 F218 68 PLA 0243 F219 A8 TAY ;Restore "Loading" flag 0244 F21A 20 D5 F7 JSR RDBLOK 0245 F21D 20 B4 F9 LOADL7 JSR LODHDR ;Print header and error msgs. 0246 F220 D0 33 BNE LODRTR ;=> retry 0247 F222 0248 F222 20 69 FB JSR NXTBLK ;Next block := blk. found + 1 0249 F225 2C CA 03 BIT INFO +BKFLAG 0250 F228 30 08 BMI LOADEX ;Just loaded last block => finish 0251 F22A 0252 F22A 20 6A F9 JSR ADDBKA ;Add block size to BKADDR 0253 F22D Acorn macro assembler Page 121 C.F.S. Main Routines - LOAD 0254 F22D 20 7B F7 JSR RDHEAD 0255 F230 D0 D7 BNE LOADLA ;Always jump 0256 F232 0257 F232 LOADEX 0258 F232 [ LENSW =0 ;Alter OSFILE control block 0259 F232 A0 0A LDYIM &0A ;Length offset in OSFILE block 0260 F234 A5 CC LDA FSIZE ;File size set in PRTHDR 0261 F236 91 C8 STAIY GENPTR ;Note GENPTR kept from OSFILE 0262 F238 C8 INY 0263 F239 A5 CD LDA FSIZE + 1 0264 F23B 91 C8 STAIY GENPTR 0265 F23D A9 00 LDAIM &00 ;Set high bytes of length = 0 0266 F23F C8 INY 0267 F240 91 C8 STAIY GENPTR 0268 F242 C8 INY 0269 F243 91 C8 STAIY GENPTR 0270 F245 ] 0271 F245 0272 F245 28 PLP ;Restore interrupt status 0273 F246 0274 F246 FINOP 0275 F246 0276 F246 20 E8 FA JSR BEEPOF ;Motor OFF/BEEP 0277 F249 0278 F249 24 BA NOOLN1 BIT ERRSW ;If error taken place, already new line 0279 F24B 30 07 BMI FINOPX 0280 F24D 08 NOOLIN PHP 0281 F24E 20 46 FA JSR MSGOUT 0282 F251 0D = MCR 0283 F252 00 = &00 ;Print new line if msgs on 0284 F253 28 PLP 0285 F254 60 FINOPX RTS 0286 F255 0287 F255 0288 F255 20 37 F6 LODRTR JSR SEARCH ;Search for current block (BLOKNO) 0289 F258 D0 AF BNE LOADLA ;Try and reload data 0290 F25A 0291 F25A 0292 F25A 0293 F25A TTL C.F.S. Main Routines - FILEGO 0294 F25A OPT &01 0295 F25A 0296 F25A 0297 F25A GETFLN 0298 F25A 0299 F25A ;X/Y -> start of file name 0300 F25A 0301 F25A 0302 F25A MOVFT 0303 F25A 0304 F25A ;Moves file title from ptr. pointed to by X,Y (lo,hi) 0305 F25A ;to FILNAM. 0306 F25A 0307 F25A ; SEI 0308 F25A 86 F2 STX WORK 0309 F25C 84 F3 STY WORK +&01 0310 F25E A0 00 LDYIM &00 0311 F260 20 1D EA JSR GSINTC ;Initialise 0312 F263 A2 00 LDXIM &00 0313 F265 20 2F EA MOVFTL JSR GSREAD 0314 F268 B0 0D BCS MOVFTX 0315 F26A F0 08 BEQ STRERR 0316 F26C 9D D2 03 STAAX FILNAM 0317 F26F E8 INX 0318 F270 E0 0B CPXIM FTSIZE 0319 F272 D0 F1 BNE MOVFTL 0320 F274 0321 F274 STRNG0 0322 F274 4C 8F EA STRERR JMP BADSTR 0323 F277 0324 F277 A9 00 MOVFTX LDAIM &00 0325 F279 9D D2 03 STAAX FILNAM 0326 F27C ; CLI 0327 F27C 60 RTS 0328 F27D 0329 F27D 0330 F27D FILEGO 0331 F27D 0332 F27D ;Entry here from OSFILE. 0333 F27D 0334 F27D 48 PHA ;Store load/save indication 0335 F27E 86 C8 STX GENPTR 0336 F280 84 C9 STY GENPTR +&01 0337 F282 0338 F282 A0 00 LDYIM &00 0339 F284 B1 C8 LDAIY GENPTR 0340 F286 AA TAX ;Set ptr. to file name for MOVFT 0341 F287 C8 INY 0342 F288 B1 C8 LDAIY GENPTR 0343 F28A A8 TAY 0344 F28B 0345 F28B 20 5A F2 JSR MOVFT ;File title -> FILNAM 0346 F28E A0 02 LDYIM &02 0347 F290 B1 C8 FILELP LDAIY GENPTR 0348 F292 99 BC 03 STAAY INFO +BKLOAD -&02 ;Set LOAD/EXEC address in header buffer 0349 F295 99 AE 00 STAAY BKADDR -&02 ;Optional load address stored for LOAD 0350 F298 C8 INY 0351 F299 C0 0A CPYIM &0A ;Ten coz 2*4 + 2 initially 0352 F29B D0 F3 BNE FILELP 0353 F29D 0354 F29D 68 PLA 0355 F29E F0 07 BEQ FILEL2 0356 F2A0 C9 FF CMPIM &FF 0357 F2A2 D0 B0 BNE FINOPX ;If not Load -> return 0358 F2A4 4C C4 F1 JMP LOADGO ;Else so load 0359 F2A7 0360 F2A7 ;Now doing save 0361 F2A7 0362 F2A7 8D C6 03 FILEL2 STA INFO +BKNOLO ;Set block number in header 0363 F2AA 8D C7 03 STA INFO +BKNOHI ;while A is zero 0364 F2AD B1 C8 FILEL3 LDAIY GENPTR 0365 F2AF 99 A6 00 STAAY BKADDR -&0A ;BKADDR := data start 0366 F2B2 C8 INY ;Also sets HIADDR which 0367 F2B3 ;must be contiguous with BKADDR 0368 F2B3 C0 12 CPYIM &12 0369 F2B5 D0 F6 BNE FILEL3 0370 F2B7 0371 F2B7 8A TXA ;X preserved from MOVFT 0372 F2B8 F0 BA BEQ STRNG0 ;Drops through to SAVE if string OK 0373 F2BA 0374 F2BA Acorn macro assembler Page 122 C.F.S. Main Routines - FILEGO 0375 F2BA TTL C.F.S Main Routines - SAVE 0376 F2BA OPT &01 0377 F2BA 0378 F2BA ;*********** 0379 F2BA ;* S A V E * 0380 F2BA ;*********** 0381 F2BA 0382 F2BA 0383 F2BA 0384 F2BA ;Entry here from OSFILE call 0385 F2BA 0386 F2BA 20 27 FB JSR SETDEF 0387 F2BD 0388 F2BD 20 34 F9 JSR RECORD ;Prompt and motor ON 0389 F2C0 0390 F2C0 [ TUBESW=0 0391 F2C0 A9 00 LDAIM TUBER ;initialise tube for reading 0392 F2C2 20 BD FB JSR TBINIT 0393 F2C5 ] 0394 F2C5 0395 F2C5 20 E2 FB JSR BUGFIX ;Put out extra char 0396 F2C8 0397 F2C8 38 SAVELP SEC 0398 F2C9 A2 FD LDXIM &FD 0399 F2CB BD B7 FF SAVEL1 LDAAX HIADDR -&FD 0400 F2CE FD B3 FF SBCAX BKADDR -&FD 0401 F2D1 9D CB 02 STAAX INFO +BKSZEL-&FD ;Note corrupts Flags byte 0402 F2D4 E8 INX 0403 F2D5 D0 F4 BNE SAVEL1 ;Do HIADDR - BKADDR 0404 F2D7 A8 TAY 0405 F2D8 D0 0E BNE SAVEL2 ;Msb non-zero => not last block 0406 F2DA 0407 F2DA ;Now: IF $0100 < block size THEN block size := $0100, 0408 F2DA ; not last block 0409 F2DA ; ELSE last block 0410 F2DA 0411 F2DA EC C8 03 CPX INFO +BKSZEL ;Note X = 0 0412 F2DD A9 01 LDAIM &01 0413 F2DF ED C9 03 SBC INFO +BKSZEH 0414 F2E2 90 04 BCC SAVEL2 ;$0100 < block size, continue 0415 F2E4 0416 F2E4 A2 80 LDXIM LASTBK ;Else, indicate last block 0417 F2E6 D0 08 BNE SAVEL3 ;And block size correct in INFO area 0418 F2E8 0419 F2E8 A9 01 SAVEL2 LDAIM &01 0420 F2EA 8D C9 03 STA INFO +BKSZEH ;Default block size = $0100 0421 F2ED 8E C8 03 STX INFO +BKSZEL ;X always zero 0422 F2F0 8E CA 03 SAVEL3 STX INFO +BKFLAG 0423 F2F3 0424 F2F3 20 EC F7 JSR WRBLOK ;Write out data + header 0425 F2F6 30 49 BMI SAVFIN ;Last block => finished 0426 F2F8 0427 F2F8 20 6A F9 JSR ADDBKA ;Add block size to address 0428 F2FB 0429 F2FB EE C6 03 INC INFO +BKNOLO 0430 F2FE D0 C8 BNE SAVELP 0431 F300 EE C7 03 INC INFO +BKNOHI ;Inc. block no. for next time 0432 F303 D0 C3 BNE SAVELP ;Assumed always +ve 0433 F305 0434 F305 0435 F305 0436 F305 TTL C.F.S. Main Routines - RUN 0437 F305 OPT &01 0438 F305 0439 F305 RUN 0440 F305 20 5A F2 JSR GETFLN 0441 F308 A2 FF LDXIM &FF 0442 F30A 8E C2 03 STX INFO +BKEXEC ;=> load at file's load address 0443 F30D 0444 F30D ;Note, is assumed here that A = 0 from GETFLN 0445 F30D ;since LOADGO tests A 0446 F30D 0447 F30D 20 C4 F1 JSR LOADGO ;Load file from tape 0448 F310 [ TUBESW=0 0449 F310 2C 7A 02 BIT TUBE 0450 F313 10 0A BPL NOTUB1 ;No tube - jump to IO proc. address 0451 F315 0452 F315 AD C4 03 LDA INFO +BKEXEC +&02 ;Check if execution address 0453 F318 2D C5 03 AND INFO +BKEXEC +&03 ;of file is accross tube 0454 F31B C9 FF CMPIM &FF 0455 F31D D0 03 BNE RUNL1 ;Yes, set up tube call 0456 F31F 6C C2 03 NOTUB1 JMI INFO +BKEXEC ;No, just jump 0457 F322 0458 F322 A2 C2 RUNL1 LDXIM INFO +BKEXEC ;Point to exec. address 0459 F324 A0 03 LDYIM /(INFO +BKEXEC ) 0460 F326 A9 04 LDAIM TUBEX ;=> execute to tube 0461 F328 4C C7 FB JMP TBINT1 ;Claim tube and jump to address 0462 F32B | 0464 F32B ] 0465 F32B 0466 F32B 0467 F32B TTL C.F.S Main Routines - CAT 0468 F32B OPT &01 0469 F32B 0470 F32B 0471 F32B ;********* 0472 F32B ;* C A T * 0473 F32B ;********* 0474 F32B 0475 F32B 0476 F32B 0477 F32B CAT 0478 F32B 0479 F32B ;Entered from MOS with two args 0480 F32B ;in X and Y as per OPT. These are not used. 0481 F32B 0482 F32B A9 08 LDAIM CATBIT 0483 F32D 20 44 F3 JSR ORSTAT 0484 F330 20 27 FB JSR SETDEF ;Set message type etc. 0485 F333 A9 00 LDAIM &00 ;Indicate verify only 0486 F335 20 48 F3 JSR LOOK ;In CFS, will never return 0487 F338 ;In SFS, will return 0488 F338 20 FC FA JSR RELEAS ;So in SFS release RS423 0489 F33B ;NOTE - only release call outside CASMOF 0490 F33B 0491 F33B 0492 F33B A9 F7 CATOFF LDAIM NCTBIT 0493 F33D 0494 F33D 25 E2 ANDSTA AND CFSTAT 0495 F33F 85 E2 ANDSTB STA CFSTAT 0496 F341 Acorn macro assembler Page 123 C.F.S Main Routines - CAT 0497 F341 SAVFIN ;Exit from SAVE 0498 F341 60 RTS 0499 F342 0500 F342 ORLST 0501 F342 A9 40 LDAIM LSTBYT 0502 F344 ; 0503 F344 05 E2 ORSTAT ORA CFSTAT 0504 F346 D0 F7 BNE ANDSTB ;Assumed always non-zero 0505 F348 0506 F348 0507 F348 0508 F348 0509 F348 0510 F348 48 LOOK PHA 0511 F349 AD 47 02 LDA SROMSW 0512 F34C F0 0B BEQ LOOKLR ;No SFS -> don't call SFS routines 0513 F34E 0514 F34E 20 13 EE JSR SRINIT ;Initialise SERROM ptr. 0515 F351 20 18 EE JSR SRNEXT 0516 F354 90 03 BCC LOOKLR 0517 F356 0518 F356 B8 CLV ;Indicate end of rom to outside world 0519 F357 50 41 BVC LOOKEX 0520 F359 0521 F359 20 7B F7 LOOKLR JSR RDHEAD 0522 F35C AD C6 03 LDA INFO +BKNOLO 0523 F35F 85 B4 STA BLOKNO 0524 F361 AD C7 03 LDA INFO +BKNOHI 0525 F364 85 B5 STA BLOKNO +&01 0526 F366 A2 FF LDXIM &FF 0527 F368 8E DF 03 STX OLDFLG 0528 F36B E8 INX 0529 F36C 86 BA STX ERRSW 0530 F36E F0 06 BEQ LOOKL5 ;Always new line 0531 F370 0532 F370 20 69 FB LOOKL1 JSR NXTBLK ;Blokno := INFO +BKNO + 1 0533 F373 0534 F373 20 7B F7 JSR RDHEAD ;Read header 0535 F376 AD 47 02 LOOKL5 LDA SROMSW 0536 F379 F0 02 BEQ LOOKL7 0537 F37B 0538 F37B ;Check V from RDHEAD 0539 F37B 0540 F37B 50 1D BVC LOOKEX ;In SFS and VC => end of all ROMs 0541 F37D 0542 F37D 68 LOOKL7 PLA 0543 F37E 48 PHA ;Check if just verifying 0544 F37F F0 2D BEQ LOOKL4 ;If just verifying, continue 0545 F381 20 72 FA JSR CMPFT ;Otherwise, check file titles 0546 F384 D0 16 BNE LOOKL2 ;Not the same, continue 0547 F386 A9 30 LDAIM NIGBIT 0548 F388 25 BB AND USFLGS 0549 F38A F0 0E BEQ LOOKEX ;If ignore set, just exit 0550 F38C 0551 F38C AD C6 03 LDA INFO +BKNOLO ;Otherwise, check block no. 0552 F38F C5 B6 CMP SRCHBK 0553 F391 D0 09 BNE LOOKL2 ;Not found ... 0554 F393 AD C7 03 LDA INFO +BKNOHI 0555 F396 C5 B7 CMP SRCHBK +&01 0556 F398 D0 02 BNE LOOKL2 0557 F39A 68 LOOKEX PLA 0558 F39B 0559 F39B ;On exit, V indicates in CFS if header 0560 F39B ;interrupted by DCD. In SFS, indicates 0561 F39B ;if end of ROM filing system reached. 0562 F39B 0563 F39B 60 RTS 0564 F39C 0565 F39C LOOKL2 0566 F39C 0567 F39C ;Here, file not recognised. In CFS, just 0568 F39C ;carry on reading next block. In SFS, 0569 F39C ;skip to block zero of next file. 0570 F39C 0571 F39C AD 47 02 LDA SROMSW 0572 F39F F0 0D BEQ LOOKL4 ;In CFS, carry on 0573 F3A1 20 AD EE LOOKL8 JSR SRSKIP ;Not recognised => skip 0574 F3A4 A9 FF LOOKLA LDAIM &FF 0575 F3A6 8D C6 03 STA INFO +BKNOLO ;Look for block zero of next file 0576 F3A9 8D C7 03 STA INFO +BKNOHI 0577 F3AC D0 C2 BNE LOOKL1 0578 F3AE 0579 F3AE 50 05 LOOKL4 BVC LOOKL3 ;Header interrupted 0580 F3B0 A9 FF LDAIM &FF 0581 F3B2 20 D7 F7 JSR CHKBIN ;Check data 0582 F3B5 0583 F3B5 A2 00 LOOKL3 LDXIM &00 0584 F3B7 20 D9 F9 JSR CATERR ;Print errors and header 0585 F3BA 0586 F3BA AD 47 02 LDA SROMSW 0587 F3BD F0 04 BEQ LOOKL9 ;In CFS -> continue 0588 F3BF 24 BB BIT USFLGS 0589 F3C1 50 DE BVC LOOKL8 ;=> short msgs and skip beween files 0590 F3C3 0591 F3C3 2C CA 03 LOOKL9 BIT INFO +BKFLAG 0592 F3C6 30 DC BMI LOOKLA ;Look for block zero 0593 F3C8 10 A6 BPL LOOKL1 ;Look for next block 0594 F3CA 0595 F3CA 0596 F3CA TTL C.F.S Main Routines - FIND 0597 F3CA OPT &01 0598 F3CA 0599 F3CA ;****** SEQUENTIAL ACCESS ****** 0600 F3CA 0601 F3CA 0602 F3CA 0603 F3CA ;*********** 0604 F3CA ;* F I N D * 0605 F3CA ;*********** 0606 F3CA 0607 F3CA 0608 F3CA FIND ;FIND 0609 F3CA 0610 F3CA 0611 F3CA ;Entered from OSFIND: 0612 F3CA 0613 F3CA ;A NZ => open 0614 F3CA ;b6 => file already exists and opened for read/ud 0615 F3CA ;A EQ => shut 0616 F3CA 0617 F3CA ;For open: X,Y -> file name lo,hi Acorn macro assembler Page 124 C.F.S Main Routines - FIND 0618 F3CA 0619 F3CA ;For shut: Y = handle. If zero, all files shut. 0620 F3CA 0621 F3CA 0622 F3CA 0623 F3CA 85 BC STA TEMP 0624 F3CC 8A TXA 0625 F3CD 48 PHA 0626 F3CE 98 TYA 0627 F3CF 48 PHA 0628 F3D0 A5 BC LDA TEMP 0629 F3D2 D0 1E BNE FINDON 0630 F3D4 0631 F3D4 98 TYA 0632 F3D5 D0 0C BNE SHUTL1 ;Y non-zero => shut one file 0633 F3D7 ; 0634 F3D7 20 75 E2 JSR SHUTES ;shut EXEC and SPOOL files opened by CFS 0635 F3DA 20 78 F4 JSR SHUTW ;Else shut write file 0636 F3DD ; Shut read file and exit 0637 F3DD 46 E2 SHUTR LSR CFSTAT 0638 F3DF 06 E2 ASL CFSTAT ;Note assumes input bit = b0 0639 F3E1 ; C=0 0640 F3E1 90 0C BCC JFINDEX ;[ALWAYS jump] 0641 F3E3 ; 0642 F3E3 ; 0643 F3E3 4A SHUTL1 LSRA 0644 F3E4 B0 F7 BCS SHUTR ;Shut input file 0645 F3E6 4A LSRA 0646 F3E7 B0 03 BCS SHUTL2 ;Shut output file 0647 F3E9 0648 F3E9 4C B1 FB JMP HNDERR ;Invalid handle 0649 F3EC 0650 F3EC 20 78 F4 SHUTL2 JSR SHUTW 0651 F3EF JFINDEX 0652 F3EF 4C 71 F4 JMP FINDEX 0653 F3F2 0654 F3F2 0655 F3F2 0656 F3F2 20 5A F2 FINDON JSR MOVFT 0657 F3F5 0658 F3F5 24 BC BIT TEMP 0659 F3F7 50 3D BVC FINDO ;Find for output if b.6 = 0 0660 F3F9 0661 F3F9 ;Opening files already open 0662 F3F9 ;is the same as if not already open 0663 F3F9 0664 F3F9 0665 F3F9 ;Open for reading 0666 F3F9 ;Set handle and read in first buffer 0667 F3F9 0668 F3F9 A9 00 LDAIM &00 0669 F3FB 8D 9E 03 STA INPTR ;Set buffer ptr. := 0 0670 F3FE 8D DD 03 STA NEXTIN 0671 F401 8D DE 03 STA NEXTIN +&01 ;Set expected block := 0 0672 F404 0673 F404 A9 3E LDAIM NECBIT ;End of file/last byte unset/input file closed 0674 F406 20 3D F3 JSR ANDSTA 0675 F409 0676 F409 20 1A FB JSR SETSDF ;Set seq. access default 0677 F40C 0678 F40C 08 PHP ;Store interrupt status 0679 F40D 20 31 F6 JSR SRCH0 ;Find file, first block. 0680 F410 20 B4 F6 JSR RDBFRS ;Check hdr. read ok, and get first bfr. 0681 F413 28 PLP ;Restore interrupt status 0682 F414 0683 F414 A2 FF LDXIM &FF 0684 F416 E8 FINDL5 INX ;Make file name found = file name 0685 F417 BD B2 03 LDAAX INFO ;for subsequent block reads 0686 F41A 9D A7 03 STAAX INFILE ;so that OPENIN "" locks onto one filet block. 0687 F41D D0 F7 BNE FINDL5 0688 F41F 0689 F41F A9 01 LDAIM INOPEN 0690 F421 20 44 F3 JSR ORSTAT 0691 F424 AD EA 02 LDA INBSZE 0692 F427 0D EB 02 ORA INBSZE +&01 0693 F42A D0 03 BNE FINDL6 ;If non-empty, don't worry 0694 F42C 20 42 F3 JSR ORLST ;Otherwise, at end of file 0695 F42F 0696 F42F A9 01 FINDL6 LDAIM INHAND 0697 F431 0D 47 02 ORA SROMSW ;If in SFS, return 3 0698 F434 D0 39 BNE OPENEX ;Return input handle 0699 F436 0700 F436 0701 F436 0702 F436 8A FINDO TXA ;Can't openout "" 0703 F437 D0 03 BNE FINABC 0704 F439 4C 8F EA JMP BADSTR 0705 F43C 0706 F43C A2 FF FINABC LDXIM &FF 0707 F43E E8 FINDL2 INX 0708 F43F BD D2 03 LDAAX FILNAM ;Store output file name 0709 F442 9D 80 03 STAAX OUTHDR 0710 F445 D0 F7 BNE FINDL2 0711 F447 0712 F447 A9 FF LDAIM &FF 0713 F449 A2 08 LDXIM &08 0714 F44B 9D 8B 03 FINDL4 STAAX OUTHDR +BKLOAD -&01 0715 F44E CA DEX 0716 F44F D0 FA BNE FINDL4 ;Set load/EXEC address to default value 0717 F451 0718 F451 8A TXA 0719 F452 A2 14 LDXIM BKNOLO 0720 F454 0721 F454 ;Set block no./block len./last bk. =0 0722 F454 ;Note also sets OUTPTR which must 0723 F454 ;be contiguous with OUTHDR 0724 F454 0725 F454 9D 80 03 FINDL3 STAAX OUTHDR 0726 F457 E8 INX 0727 F458 E0 1E CPXIM BKLAST +&01 0728 F45A D0 F8 BNE FINDL3 ;Note carry set 0729 F45C 2E 97 03 ROL OUTHDR +BKSZEH ;Set hi byte of size 0730 F45F 0731 F45F 20 27 FB JSR SETDEF ;If default, print prompt 0732 F462 20 34 F9 JSR RECORD 0733 F465 20 F2 FA JSR CASMOF ;OFF for putbyte call 0734 F468 0735 F468 A9 02 LDAIM OUTOPN 0736 F46A 20 44 F3 JSR ORSTAT ;Indicate file open for output 0737 F46D 0738 F46D A9 02 LDAIM OUTHND Acorn macro assembler Page 125 C.F.S Main Routines - FIND 0739 F46F 0740 F46F 85 BC OPENEX STA TEMP 0741 F471 FINDEX ;Common exit for PUT/GETBYTE and FIND 0742 F471 68 GBEXX PLA 0743 F472 A8 TAY 0744 F473 68 PLA 0745 F474 AA TAX 0746 F475 A5 BC LDA TEMP 0747 F477 FINDXX 0748 F477 60 RTS 0749 F478 0750 F478 0751 F478 0752 F478 0753 F478 0754 F478 0755 F478 SHUTW 0756 F478 0757 F478 A9 02 LDAIM OUTHND 0758 F47A 25 E2 AND CFSTAT 0759 F47C F0 F9 BEQ FINDXX ;If already shut, dont bother 0760 F47E 0761 F47E A9 00 LDAIM &00 0762 F480 8D 97 03 STA OUTHDR +BKSZEH 0763 F483 0764 F483 A9 80 LDAIM LASTBK 0765 F485 AE 9D 03 LDX OUTPTR 0766 F488 8E 96 03 STX OUTHDR +BKSZEL 0767 F48B 8D 98 03 STA OUTHDR +BKFLAG 0768 F48E 20 96 F4 JSR WRTBFR ;Write out block 0769 F491 A9 FD LDAIM NOUTHD 0770 F493 4C 3D F3 JMP ANDSTA ;Mark file as closed 0771 F496 0772 F496 0773 F496 WRTBFR ;Write out buffer 0774 F496 0775 F496 20 1A FB JSR SETSDF ;Set sequential defaults 0776 F499 0777 F499 A2 11 LDXIM BKLAST -BKLOAD 0778 F49B BD 8C 03 WRTBL3 LDAAX OUTHDR +BKLOAD 0779 F49E 9D BE 03 STAAX INFO +BKLOAD 0780 F4A1 CA DEX 0781 F4A2 10 F7 BPL WRTBL3 0782 F4A4 0783 F4A4 ; Set buffer address for WBLOCK call 0784 F4A4 0785 F4A4 86 B2 STX BKADDR +&02 0786 F4A6 86 B3 STX BKADDR +&03 ;Output buffer is in IO proc. 0787 F4A8 0788 F4A8 0000 T * OUTBFR:SHL: 8 0789 F4A8 [ T=0 0790 F4A8 E8 INX 0791 F4A9 86 B0 STX BKADDR ;If OUTBFR on page boundary, set lo byte = 0 0792 F4AB | 0795 F4AB ] 0796 F4AB 0797 F4AB A9 09 LDAIM /(OUTBFR ) 0798 F4AD 85 B1 STA BKADDR +&01 0799 F4AF 0800 F4AF A2 7F LDXIM OUTHDR -&01 0801 F4B1 20 81 FB JSR MOVFN ;File name -> FILNAM etc. 0802 F4B4 8D DF 03 STA OLDFLG 0803 F4B7 0804 F4B7 20 8E FB JSR MOTONW ;Motor on and select output drive 0805 F4BA 20 E2 FB JSR BUGFIX 0806 F4BD 20 EC F7 JSR WBLOCK ;Write out block 0807 F4C0 EE 94 03 INC OUTHDR +BKNOLO ;Next block 0808 F4C3 D0 03 BNE WRTBL4 0809 F4C5 EE 95 03 INC OUTHDR +BKNOHI 0810 F4C8 60 WRTBL4 RTS 0811 F4C9 0812 F4C9 0813 F4C9 0814 F4C9 0815 F4C9 0816 F4C9 0817 F4C9 0818 F4C9 0819 F4C9 TTL C.F.S. Main Routines - GETBYTE 0820 F4C9 OPT &01 0821 F4C9 0822 F4C9 0823 F4C9 ;****************** 0824 F4C9 ;* G E T B Y T E * 0825 F4C9 ;****************** 0826 F4C9 0827 F4C9 0828 F4C9 GETBYT 0829 F4C9 0830 F4C9 8A TXA 0831 F4CA 48 PHA 0832 F4CB 98 TYA 0833 F4CC 48 PHA 0834 F4CD A9 01 LDAIM INHAND 0835 F4CF 20 9C FB JSR CHKHND ;Is handle open ? 0836 F4D2 0837 F4D2 A5 E2 LDA CFSTAT 0838 F4D4 0A ASLA 0839 F4D5 B0 4C BCS GBEOF ;=> Going past end of file 0840 F4D7 0A ASLA 0841 F4D8 90 09 BCC GBLF ;=> Not getting last byte 0842 F4DA 0843 F4DA ;Here indicate next GB call 0844 F4DA ;goes off end of file 0845 F4DA 0846 F4DA A9 80 LDAIM EOFBIT 0847 F4DC 20 44 F3 JSR ORSTAT 0848 F4DF 0849 F4DF ;Carry still set from above 0850 F4DF 0851 F4DF A9 FE LDAIM ENDBYT ;Byte after end of file 0852 F4E1 B0 38 BCS GBEXY 0853 F4E3 0854 F4E3 AE 9E 03 GBLF LDX INPTR 0855 F4E6 E8 INX 0856 F4E7 EC EA 02 CPX INBSZE ;Is last byte of buffer ? 0857 F4EA D0 2A BNE GBLDE ;Nope -> continue 0858 F4EC 0859 F4EC 0860 F4EC 2C EC 02 BIT BUFFLG ;Check if in last block. If so, are reading 0861 F4EF 30 22 BMI GBLH ;last byte of last block => exit Acorn macro assembler Page 126 C.F.S. Main Routines - GETBYTE 0862 F4F1 0863 F4F1 ;Read last byte of block. NOTE this is kept in a location 0864 F4F1 ;separate from the rest of the block buffer, so that if the 0865 F4F1 ;next block being read aborts and corrupts the block buffer, 0866 F4F1 ;a subsequent retry will still provide the last byte of the 0867 F4F1 ;previous block. The variable FINBYT is updated in RDBFER after 0868 F4F1 ;the background block read has succesfully completed. 0869 F4F1 0870 F4F1 AD ED 02 LDA FINBYT 0871 F4F4 48 PHA ;Store final byte of this block 0872 F4F5 20 1A FB JSR SETSDF ;Set sequential defaults 0873 F4F8 08 PHP ;Store I'rupt status 0874 F4F9 20 AC F6 JSR RDBFER ;Read buffer for next GETBYTE call 0875 F4FC 28 PLP ;Restore I'rupt status 0876 F4FD 68 PLA ;Restore final byte of previous buffer 0877 F4FE 85 BC STA TEMP ;Store for later use 0878 F500 0879 F500 18 CLC ;Prepare for non-end of file exit 0880 F501 2C EC 02 BIT BUFFLG 0881 F504 10 17 BPL GBEXIT ;Exit, result = TEMP, carry clear 0882 F506 0883 F506 AD EA 02 LDA INBSZE ;If here, is last block 0884 F509 0D EB 02 ORA INBSZE +&01 0885 F50C D0 0F BNE GBEXIT ;Last block, is not empty 0886 F50E 20 42 F3 JSR ORLST ;If is last block, and empty 0887 F511 D0 0A BNE GBEXIT ;then this is the last byte 0888 F513 ;So set last byte bit and exit, C = 0 0889 F513 0890 F513 GBLH 0891 F513 20 42 F3 JSR ORLST ;Otherwise, reading last byte. 0892 F516 0893 F516 ;So exit, carry clear 0894 F516 0895 F516 CA GBLDE DEX 0896 F517 18 CLC ;Carry clear unless byte AFTER last byte of file 0897 F518 BD 00 0A LDAAX INBUFR ;GET BYTE ! 0898 F51B 85 BC GBEXY STA TEMP 0899 F51D EE 9E 03 GBEXIT INC INPTR ;Inc. buffer ptr. for next time 0900 F520 4C 71 F4 JMP GBEXX ;Share exit with PUTBYT 0901 F523 0902 F523 00 GBEOF BRK 0903 F524 DF = CFSERD 0904 F525 45 = "E" 0905 F526 4F = "O" 0906 F527 46 = "F" 0907 F528 00 = &00 0908 F529 0909 F529 TTL C.F.S. Main Routines - PUTBYTE 0910 F529 OPT &01 0911 F529 0912 F529 0913 F529 ;****************** 0914 F529 ;* P U T B Y T E * 0915 F529 ;****************** 0916 F529 0917 F529 0918 F529 PUTBYT 0919 F529 85 C4 STA IADDR 0920 F52B 0921 F52B ;Note, IADDR not used in this 0922 F52B ;function coz RX interrupts are "disabled" 0923 F52B ;by TXFLAG (see IRUPT) 0924 F52B 0925 F52B 8A TXA 0926 F52C 48 PHA 0927 F52D 98 TYA 0928 F52E 48 PHA 0929 F52F A9 02 LDAIM OUTHND 0930 F531 20 9C FB JSR CHKHND ;Check handle open 0931 F534 0932 F534 AE 9D 03 LDX OUTPTR 0933 F537 A5 C4 LDA IADDR ;Restore byte to put 0934 F539 9D 00 09 STAAX OUTBFR 0935 F53C E8 INX 0936 F53D D0 06 BNE PBEXIT ;Test if last byte of buffer 0937 F53F 20 96 F4 JSR WRTBFR ;Buffer full, write out. 0938 F542 20 F2 FA JSR CASMOF 0939 F545 0940 F545 EE 9D 03 PBEXIT INC OUTPTR 0941 F548 0942 F548 ;Increment pointer after writing block out so that 0943 F548 ;user can retry if block is interrupted 0944 F548 ;by ESCAPE. 0945 F548 0946 F548 A5 C4 LDA IADDR 0947 F54A 4C 6F F4 JMP OPENEX 0948 F54D 0949 F54D 0950 F54D 0951 F54D 0952 F54D LNK MOS74 0001 F54D 0002 F54D ;File - MOS74 0003 F54D 0004 F54D TTL C.F.S Main Routines - OPT 0005 F54D OPT &01 0006 F54D 0007 F54D ;Entered with two args in X & Y decoded from 0008 F54D ;command line by MOS. 0009 F54D 0010 F54D 8A CFSOPT TXA 0011 F54E F0 2E BEQ DEF ;X=0/Y=0 => default 0012 F550 E0 03 CPXIM &03 0013 F552 F0 1F BEQ SETGAP 0014 F554 C0 03 CPYIM &03 0015 F556 B0 06 BCS OPTERR 0016 F558 CA DEX 0017 F559 F0 06 BEQ MSGS 0018 F55B CA DEX 0019 F55C F0 0A BEQ ERRS 0020 F55E 0021 F55E 4C 10 E3 OPTERR JMP MBDCMD 0022 F561 0023 F561 A9 33 MSGS LDAIM MSGMSK 0024 F563 C8 INY 0025 F564 C8 INY 0026 F565 C8 INY 0027 F566 D0 02 BNE XSETFLG ;[ALWAYS jump] 0028 F568 0029 F568 A9 CC ERRS LDAIM ERRMSK ;Mask out error and default bits 0030 F56A C8 XSETFLG INY Acorn macro assembler Page 127 C.F.S Main Routines - OPT 0031 F56B 25 E3 AND OPTS 0032 F56D 19 81 F5 SETFL1 ORAAY OPTTAB 0033 F570 85 E3 STA OPTS 0034 F572 60 RTS 0035 F573 0036 F573 98 SETGAP TYA 0037 F574 30 02 BMI SETGP2 ; >127 => default 0038 F576 D0 02 BNE SETGP1 ; 0 < gap < 128 => OK 0039 F578 A9 19 SETGP2 LDAIM DEFGAP 0040 F57A 8D D1 03 SETGP1 STA SEQGAP 0041 F57D 60 RTS 0042 F57E 0043 F57E A8 DEF TAY ;Must be zero from OPT 0044 F57F F0 EC BEQ SETFL1 0045 F581 0046 F581 A1 OPTTAB = DEFLT 0047 F582 00 = IGBIT 0048 F583 22 = RETBIT 0049 F584 11 = ABTBIT 0050 F585 00 = &00 ;Messages off 0051 F586 88 = MSGS1 ;Short messages 0052 F587 CC = MSGS2 ;Long messages 0053 F588 0054 F588 TTL Main Routines - Interrupt routine 0055 F588 OPT &01 0056 F588 0057 F588 IRUPT 0058 F588 0059 F588 C6 C0 DEC IFLAG 0060 F58A AD 47 02 LDA SROMSW ;Is SFS active ? 0061 F58D F0 07 BEQ NOTSPK ;Nope 0062 F58F 0063 F58F 20 51 EE JSR RDSPCH ;Yes, get next byte from ROM 0064 F592 A8 TAY 0065 F593 18 CLC ;Clear carry => no DCD 0066 F594 90 1A BCC DOIRPT ;Do as per cassette irupt 0067 F596 0068 F596 AD 08 FE NOTSPK LDA STATUS 0069 F599 48 PHA 0070 F59A 29 02 ANDIM TXBIT 0071 F59C F0 0B BEQ ITXON ;No TX interrupt 0072 F59E A4 CA LDY TXFLAG 0073 F5A0 F0 07 BEQ ITXON ;0 => receiving 0074 F5A2 0075 F5A2 ;Here, transmiting byte .... 0076 F5A2 0077 F5A2 68 PLA ;Restore stack 0078 F5A3 A5 BD LDA IBUF 0079 F5A5 8D 09 FE STA PORT 0080 F5A8 60 RTS 0081 F5A9 0082 F5A9 0083 F5A9 ITXON 0084 F5A9 0085 F5A9 ;If receiving byte, check IFLAG to see 0086 F5A9 ;where to put it. 0087 F5A9 0088 F5A9 AC 09 FE LDY PORT ;Cancel interrupt 0089 F5AC 68 PLA ;Pull status 0090 F5AD 4A LSRA 0091 F5AE 4A LSRA 0092 F5AF 4A LSRA ;C = 1 => DCD; C = 0 => no DCD 0093 F5B0 A6 C2 DOIRPT LDX ITYPE 0094 F5B2 F0 69 BEQ IEX ;0 => no task pending 0095 F5B4 0096 F5B4 0097 F5B4 CA DEX 0098 F5B5 D0 06 BNE FNDHDR ;X <> 1 => not DCD task 0099 F5B7 90 64 BCC IEX ;=> DCD Not yet found 0100 F5B9 A0 02 LDYIM &02 0101 F5BB D0 5E BNE NEWINT ;Go on to look find hdr. 0102 F5BD 0103 F5BD CA FNDHDR DEX 0104 F5BE D0 13 BNE RDCHAR ;X <> 2 => not header task 0105 F5C0 B0 5B BCS IEX ;Ignore DCD if present 0106 F5C2 98 TYA ;Get stuff from port 0107 F5C3 20 78 FB JSR SETJOB ;Set CHKSUM etc. 0108 F5C6 A0 03 LDYIM &03 ;New task 0109 F5C8 0110 F5C8 [ GLYN=0 0114 F5C8 ] 0115 F5C8 0116 F5C8 C9 2A CMPIM "*" 0117 F5CA F0 4F BEQ NEWINT ;Set read chars 0118 F5CC 20 50 FB JSR RXINIT ;Reset ULA (should be BLIP) 0119 F5CF A0 01 LDYIM &01 0120 F5D1 D0 48 BNE NEWINT ;Otherwise, wait for DCD 0121 F5D3 0122 F5D3 CA RDCHAR DEX 0123 F5D4 D0 0C BNE RDBLK ;X <> 3 => not RDCHAR task 0124 F5D6 B0 04 BCS GOTDCD ;DCD found, not char 0125 F5D8 84 BD STY IBUF ;Store char read 0126 F5DA F0 41 BEQ IEX 0127 F5DC A9 80 GOTDCD LDAIM &80 0128 F5DE 85 C0 STA IFLAG ;Indicate DCD 0129 F5E0 D0 3B BNE IEX 0130 F5E2 0131 F5E2 CA RDBLK DEX ;X <> 4=> not RDBLK 0132 F5E3 D0 29 BNE SUMIN 0133 F5E5 B0 2F BCS IFIN ;If DCD, finish immediately 0134 F5E7 98 TYA 0135 F5E8 20 B0 F7 JSR ADDCRC 0136 F5EB A4 BC LDY TEMP ;(pointer) 0137 F5ED E6 BC INC TEMP 0138 F5EF 24 BD BIT IBUF 0139 F5F1 30 0D BMI RDBLKA ;=> just verify, don't store 0140 F5F3 0141 F5F3 [ TUBESW=0 0142 F5F3 20 D3 FB JSR TUBCHK ;Check tube present and top bytes of address 0143 F5F6 F0 05 BEQ RDBLKB ;No need to tube. (NOTE TUBCHK DOES TAX to preserve A) 0144 F5F8 0145 F5F8 8E E5 FE STX TREG3 ;Otherwise, push to tube R3 0146 F5FB D0 03 BNE RDBLKA ;And continue 0147 F5FD 0148 F5FD 8A RDBLKB TXA 0149 F5FE 91 B0 STAIY BKADDR ;Store in IO proc. 0150 F600 | 0152 F600 ] 0153 F600 0154 F600 C8 RDBLKA INY 0155 F601 CC C8 03 CPY INFO +BKSZEL ;** 1 BYTE SIZE ONLY ** Acorn macro assembler Page 128 Main Routines - Interrupt routine 0156 F604 D0 17 BNE IEX ;Keep going 0157 F606 0158 F606 ;Have here finished reading data, so 0159 F606 ;read two more bytes of CRC without storing 0160 F606 0161 F606 A9 01 LDAIM &01 ;Set counter 0162 F608 85 BC STA TEMP 0163 F60A A0 05 LDYIM &05 0164 F60C D0 0D BNE NEWINT 0165 F60E 0166 F60E 0167 F60E SUMIN 0168 F60E 0169 F60E ;Here, assumed X = 5 0170 F60E 0171 F60E 98 TYA 0172 F60F 20 B0 F7 JSR ADDCRC 0173 F612 C6 BC DEC TEMP 0174 F614 10 07 BPL IEX ;One more to go 0175 F616 0176 F616 ;If here, finished, so mark BG job finished 0177 F616 0178 F616 20 46 FB IFIN JSR CRESET 0179 F619 A0 00 LDYIM &00 0180 F61B 84 C2 NEWINT STY ITYPE 0181 F61D 60 IEX RTS 0182 F61E 0183 F61E TTL C.F.S. Main routines - EOF 0184 F61E OPT MOS74 Acorn macro assembler Page 129 C.F.S. Main routines - EOF 0185 F61E 0186 F61E 48 CFSEOF PHA ;First store Y and A 0187 F61F 98 TYA 0188 F620 48 PHA 0189 F621 8A TXA ;Transfer handle to Y 0190 F622 A8 TAY ;for checking. 0191 F623 A9 03 LDAIM HNDS ;Both handles 0192 F625 20 9C FB JSR CHKHND ;NOTE - CORRUPTS Y 0193 F628 0194 F628 A5 E2 LDA CFSTAT 0195 F62A 29 40 ANDIM LSTBYT 0196 F62C AA TAX ;Result (zero or non-zero) in X 0197 F62D 68 PLA 0198 F62E A8 TAY 0199 F62F 68 PLA ;Restore A and Y 0200 F630 60 RTS 0201 F631 0202 F631 TTL C.F.S. UTILITIES - MOS74 0203 F631 OPT &01 0204 F631 0205 F631 ;****** CASSETTE UTILITIES ****** 0206 F631 0207 F631 0208 F631 A9 00 SRCH0 LDAIM &00 0209 F633 85 B4 STA BLOKNO 0210 F635 85 B5 STA BLOKNO +&01 0211 F637 0212 F637 SEARCH 0213 F637 0214 F637 0215 F637 ;File title pointed to by FTPTR. 0216 F637 ;Block number in BLOKNO. 0217 F637 0218 F637 ;Tool through tape until found. If messages 0219 F637 ;on, print header info and checksum messages. 0220 F637 0221 F637 A5 B4 LDA BLOKNO 0222 F639 48 PHA 0223 F63A 85 B6 STA SRCHBK 0224 F63C A5 B5 LDA BLOKNO +&01 0225 F63E 48 PHA 0226 F63F 85 B7 STA SRCHBK +&01 ;Set block to search for 0227 F641 20 46 FA JSR MSGOUT 0228 F644 53 65 61 = "Searching",MCR,&00 0229 F64F A9 FF LDAIM &FF ;=> search and validate 0230 F651 20 48 F3 JSR LOOK 0231 F654 68 PLA 0232 F655 85 B5 STA BLOKNO +&01 0233 F657 68 PLA 0234 F658 85 B4 STA BLOKNO 0235 F65A A5 B6 LDA SRCHBK 0236 F65C 05 B7 ORA SRCHBK+&01 0237 F65E D0 0D BNE SRCHXX 0238 F660 0239 F660 ;If finding first block, set next expected 0240 F660 ;block to zero so that a load will not 0241 F660 ;fail because of a new file breaking into 0242 F660 ;a previous one thus causing non-sequential 0243 F660 ;blocks and therefore a block? error. 0244 F660 0245 F660 85 B4 STA BLOKNO ;If first block, no block error 0246 F662 85 B5 STA BLOKNO +&01 0247 F664 0248 F664 ;Check header CRC so that we only latch 0249 F664 ;onto non-corrupt file names 0250 F664 0251 F664 A5 C1 LDA HDRCRC 0252 F666 D0 05 BNE SRCHXX 0253 F668 A2 B1 LDXIM INFO -&01 ;Make sure looking for 0254 F66A 20 81 FB JSR MOVFN ;file name found in subsequent blocks 0255 F66D SRCHXX ;Check if run off the end of SROM system 0256 F66D 0257 F66D AD 47 02 LDA SROMSW 0258 F670 F0 13 BEQ SRCHYY ;In CFS, carry on 0259 F672 70 11 BVS SRCHYY ;Not end of ROM => continue 0260 F674 FNF 0261 F674 00 BRK 0262 F675 D6 = SFSER1 0263 F676 46 69 6C = "File not found",&00 0264 F685 0265 F685 A0 FF SRCHYY LDYIM &FF ;For LOAD and RDBFER 0266 F687 8C DF 03 STY OLDFLG ;Fool PRTHDR to print 0267 F68A ;extra blank line after "Loading" message 0268 F68A 60 RTS 0269 F68B 0270 F68B 0271 F68B ECLOSE ;close EXEC file 0272 F68B 0273 F68B A9 00 LDAIM ZERO 0274 F68D ; 0275 F68D EXEC ; EXEC 0276 F68D 0277 F68D ; XY -> filename 0278 F68D ; A = $00 0279 F68D ; 0280 F68D ; does not corrupt Y if just closing file (used by SHUTES) 0281 F68D ; 0282 F68D 08 PHP ;remember whether to just close exec file 0283 F68E 84 E6 STY EXECY ;save Y 0284 F690 ; close any previous exec file 0285 F690 AC 56 02 LDY EXECH 0286 F693 8D 56 02 STA EXECH ;clear execing 0287 F696 F0 03 BEQ EXEC2 ;[no current exec file, avoid closing all files] 0288 F698 ; A=0 0289 F698 20 CE FF JSR OSFIND ;close previous exec file (assumes X not corrupted) 0290 F69B EXEC2 0291 F69B A4 E6 LDY EXECY ;restore Y 0292 F69D 28 PLP 0293 F69E F0 0B BEQ EXEC0 ;[just stop execing] 0294 F6A0 ; try opening specified file 0295 F6A0 A9 40 LDAIM &40 ;open file for input 0296 F6A2 20 CE FF JSR OSFIND 0297 F6A5 A8 TAY 0298 F6A6 F0 CC BEQ FNF ;[file not found] 0299 F6A8 8D 56 02 STA EXECH ;remember exec file handle 0300 F6AB EXEC0 ;Z=1 0301 F6AB 60 RTS 0302 F6AC 0303 F6AC 0304 F6AC RDBFER 0305 F6AC Acorn macro assembler Page 130 C.F.S. UTILITIES - MOS74 0306 F6AC 0307 F6AC ;Read a block into input buffer. Used in GETBYTE 0308 F6AC 0309 F6AC A2 A6 LDXIM INFILE -&01 0310 F6AE 20 81 FB JSR MOVFN ;Set file searching for 0311 F6B1 20 7B F7 JSR RDHEAD 0312 F6B4 0313 F6B4 RDBFRS 0314 F6B4 0315 F6B4 AD CA 03 LDA INFO +BKFLAG ;Check protection bit 0316 F6B7 4A LSRA 0317 F6B8 90 03 BCC RDBFLL ;Not protected -> continue 0318 F6BA 4C F6 F1 JMP PROTER ;Protected -> error 0319 F6BD 0320 F6BD AD DD 03 RDBFLL LDA NEXTIN 0321 F6C0 85 B4 STA BLOKNO 0322 F6C2 AD DE 03 LDA NEXTIN +&01 0323 F6C5 85 B5 STA BLOKNO +&01 ;Set block no. to check 0324 F6C7 0325 F6C7 A9 00 LDAIM INBUFR 0326 F6C9 85 B0 STA BKADDR 0327 F6CB A9 0A LDAIM /(INBUFR ) 0328 F6CD 85 B1 STA BKADDR +&01 0329 F6CF A9 FF LDAIM &FF 0330 F6D1 85 B2 STA BKADDR +&02 0331 F6D3 85 B3 STA BKADDR +&03 ;Input buffer is in IO proc. 0332 F6D5 20 D5 F7 JSR READBK ;Read data into buffer 0333 F6D8 20 B4 F9 JSR LODHDR 0334 F6DB D0 25 BNE RDBERR 0335 F6DD 0336 F6DD ;Data read ok, inc. next expected block. 0337 F6DD 0338 F6DD AD FF 0A LDA INBUFR +&FF 0339 F6E0 8D ED 02 STA FINBYT ;Store final byte of this buffer in safe place 0340 F6E3 0341 F6E3 20 69 FB JSR NXTBLK ;Next block = current block + 1 0342 F6E6 ;NOTE - corrupts BLOKNO 0343 F6E6 0344 F6E6 8E DD 03 STX NEXTIN 0345 F6E9 8C DE 03 STY NEXTIN +&01 0346 F6EC 0347 F6EC A2 02 LDXIM &02 0348 F6EE 0349 F6EE ;Set block size and flag byte 0350 F6EE 0351 F6EE BD C8 03 RDBFL1 LDAAX INFO +BKSZEL 0352 F6F1 9D EA 02 STAAX INBSZE 0353 F6F4 CA DEX 0354 F6F5 10 F7 BPL RDBFL1 0355 F6F7 2C EC 02 BIT BUFFLG 0356 F6FA 10 03 BPL RDBFL8 0357 F6FC 20 49 F2 JSR NOOLN1 ;If last block, new line 0358 F6FF 0359 F6FF 4C F2 FA RDBFL8 JMP CASMOF ;Motor off, exit 0360 F702 0361 F702 ;From here down, dealing with errors 0362 F702 0363 F702 RDBERR 0364 F702 0365 F702 ;Retry - search for block number, and 0366 F702 ;then go back to RDBFRS. 0367 F702 0368 F702 20 37 F6 JSR SEARCH ;FTPTR already set by RDHEAD. 0369 F705 D0 AD BNE RDBFRS ;Restart (always jump back) 0370 F707 0371 F707 0372 F707 0373 F707 0374 F707 0375 F707 C9 2A RDHDLC CMPIM "*" 0376 F709 F0 37 BEQ RDHDLA ;Char OK, go on to rest of block 0377 F70B C9 23 CMPIM "#" ;Is this a short header ?? 0378 F70D D0 0F BNE ROMER ;No -> illegal char -> error 0379 F70F EE C6 03 INC INFO +BKNOLO ;Have "read" short block header, so 0380 F712 D0 03 BNE RDHDX2 ;increment block number as if we have read whole header 0381 F714 EE C7 03 INC INFO +BKNOHI 0382 F717 A2 FF RDHDX2 LDXIM &FF ;Prepare for non-DCD exit 0383 F719 2C B7 D9 BIT FFBYT ;Set the V flag => not end of SFS 0384 F71C D0 55 BNE RDHDX1 ;Assumed always +ve 0385 F71E 0386 F71E A9 F7 ROMER LDAIM NCTBIT 0387 F720 0388 F720 ;Switch CAT bit off so messages not in a funny 0389 F720 ;state if error occurs in *CAT 0390 F720 0391 F720 20 3D F3 JSR ANDSTA 0392 F723 00 BRK 0393 F724 D7 = SFSERR 0394 F725 42 61 64 = "Bad ROM" 0395 F72C 00 = &00 0396 F72D 0397 F72D RDHDL2 0398 F72D 0399 F72D ;Here, set motor on and 6850 init etc. 0400 F72D 0401 F72D A0 FF LDYIM READFX ;Indicate read 0402 F72F 20 90 FB JSR MOTON ;Motor ON and drive select 0403 F732 A9 01 LDAIM &01 0404 F734 85 C2 STA ITYPE 0405 F736 20 50 FB JSR RXINIT ;Init 6850 and blip motor 0406 F739 0407 F739 ;Wait for DCD and '* character indicating 0408 F739 ;start of block. 0409 F739 0410 F739 20 95 F9 GETHLP JSR ESCAPE 0411 F73C A9 03 LDAIM &03 0412 F73E C5 C2 CMP ITYPE 0413 F740 D0 F7 BNE GETHLP 0414 F742 0415 F742 A0 00 RDHDLA LDYIM &00 0416 F744 20 7C FB JSR SETJB1 ;Set cheksum etc. 0417 F747 0418 F747 20 97 F7 RDHDL1 JSR CASIN ;Read and add to checksum 0419 F74A 50 1A BVC RDHDEX ;Header interrupted by DCD 0420 F74C 99 B2 03 STAAY INFO ;Store in INFO 0421 F74F F0 06 BEQ RDHDL3 ;End of file title (Z set in CASIN) 0422 F751 C8 INY 0423 F752 C0 0B CPYIM FTSIZE ;Attempting to read over f.t. end 0424 F754 D0 F1 BNE RDHDL1 ;No, => continue 0425 F756 88 DEY 0426 F757 Acorn macro assembler Page 131 C.F.S. UTILITIES - MOS74 0427 F757 A2 0C RDHDL3 LDXIM BKINFO ;Now read all info. 0428 F759 20 97 F7 RDHDL4 JSR CASIN 0429 F75C 50 08 BVC RDHDEX ;Header interrupted by DCD 0430 F75E 9D B2 03 STAAX INFO 0431 F761 E8 INX 0432 F762 E0 1F CPXIM BKLAST +&02 0433 F764 D0 F3 BNE RDHDL4 0434 F766 0435 F766 98 RDHDEX TYA 0436 F767 AA TAX ;Preserve Y for exit 0437 F768 A9 00 LDAIM &00 0438 F76A 99 B2 03 STAAY INFO ;Terminate f.t. 0439 F76D A5 BE LDA CHKSUM 0440 F76F 05 BF ORA CHKSUM +&01 0441 F771 85 C1 STA HDRCRC ;Store CRC indication 0442 F773 20 78 FB RDHDX1 JSR SETJOB 0443 F776 84 C2 STY ITYPE ;If header interrupted => block fin. 0444 F778 0445 F778 8A TXA 0446 F779 D0 59 BNE RDHDXX 0447 F77B 0448 F77B RDHEAD 0449 F77B 0450 F77B ;Read header info into INFO. Check file title 0451 F77B ;against FTPTR, and print header info. 0452 F77B 0453 F77B ;First, wait for DCD followed by "*" 0454 F77B 0455 F77B AD 47 02 LDA SROMSW 0456 F77E F0 AD BEQ RDHDL2 ;SFS not enabled, carry on 0457 F780 0458 F780 ;Here, SFS enabled, so read first char 0459 F780 ;(assumed to be "*") and go on to read 0460 F780 ;rest of block. 0461 F780 0462 F780 RDHDLD 0463 F780 20 51 EE JSR RDSPCH 0464 F783 C9 2B CMPIM SFSEND ;Is "end of ROM" char ? 0465 F785 D0 80 BNE RDHDLC 0466 F787 A9 08 LDAIM CATBIT 0467 F789 25 E2 AND CFSTAT 0468 F78B F0 03 BEQ RDHDL5 ;If not in CAT, don't do new line 0469 F78D 0470 F78D 20 4D F2 JSR NOOLIN ;New line between ROMs 0471 F790 20 18 EE RDHDL5 JSR SRNEXT 0472 F793 0473 F793 ;Carry clear => not at end of filing system, so 0474 F793 ;read next character, assumed still to be start 0475 F793 ;of header although in new rom. 0476 F793 0477 F793 90 EB BCC RDHDLD 0478 F795 0479 F795 ;Carry set => end of filing system, so 0480 F795 ;indicate to outside world in V flag 0481 F795 B8 CLV 0482 F796 60 RTS 0483 F797 0484 F797 ;Note assumed exit with Y = 0 0485 F797 ;for LOAD and RDBFRS 0486 F797 0487 F797 0488 F797 0489 F797 0490 F797 0491 F797 CASIN 0492 F797 AD 47 02 LDA SROMSW ;is SFS on ? 0493 F79A F0 11 BEQ CASIN1 ;Nope, read from tape 0494 F79C 0495 F79C ;Force a read from ROM & set IRUPT flag 0496 F79C 0497 F79C 8A TXA 0498 F79D 48 PHA 0499 F79E 98 TYA 0500 F79F 48 PHA 0501 F7A0 20 51 EE JSR RDSPCH 0502 F7A3 85 BD STA IBUF 0503 F7A5 A9 FF LDAIM &FF 0504 F7A7 85 C0 STA IFLAG ;=> irupt occurred, no DCD 0505 F7A9 68 PLA 0506 F7AA A8 TAY 0507 F7AB 68 PLA 0508 F7AC AA TAX 0509 F7AD 0510 F7AD 20 84 F8 CASIN1 JSR IWAIT 0511 F7B0 0512 F7B0 ;Note A=IBUF after IWAIT 0513 F7B0 0514 F7B0 [ DEBUG=0 0520 F7B0 ] 0521 F7B0 0522 F7B0 0523 F7B0 08 ADDCRC PHP 0524 F7B1 48 PHA 0525 F7B2 0526 F7B2 0010 CCITTL * &10 0527 F7B2 0008 CCITTH * &08 0528 F7B2 0529 F7B2 38 SEC 0530 F7B3 66 CB ROR CRCCNT 0531 F7B5 45 BF EOR CHKSUM +&01 0532 F7B7 85 BF STA CHKSUM +&01 0533 F7B9 A5 BF CRC1 LDA CHKSUM +&01 0534 F7BB 2A ROLA 0535 F7BC 90 0C BCC CRC2 0536 F7BE 6A RORA 0537 F7BF 49 08 EORIM CCITTH 0538 F7C1 85 BF STA CHKSUM +&01 0539 F7C3 A5 BE LDA CHKSUM 0540 F7C5 49 10 EORIM CCITTL 0541 F7C7 85 BE STA CHKSUM 0542 F7C9 38 SEC 0543 F7CA CRC2 0544 F7CA 0545 F7CA 26 BE ROL CHKSUM 0546 F7CC 26 BF ROL CHKSUM +&01 0547 F7CE 46 CB LSR CRCCNT 0548 F7D0 D0 E7 BNE CRC1 0549 F7D2 68 PLA 0550 F7D3 28 PLP 0551 F7D4 60 RDHDXX RTS 0552 F7D5 Acorn macro assembler Page 132 C.F.S. UTILITIES - MOS74 0553 F7D5 0554 F7D5 0555 F7D5 0556 F7D5 RDBLOK 0557 F7D5 0558 F7D5 READBK 0559 F7D5 0560 F7D5 ;Sets up BG job to read data into BKADDR 0561 F7D5 ;and read CRC. 0562 F7D5 0563 F7D5 ;Note: must not corrupt Y ! 0564 F7D5 0565 F7D5 A9 00 LDAIM &00 0566 F7D7 85 BD CHKBIN STA IBUF ;Indicate read to memory 0567 F7D9 A2 00 LDXIM &00 0568 F7DB 86 BC STX TEMP ;Pointer into data 0569 F7DD ;If empty, data read finished, X=$00 0570 F7DD 50 0A BVC RDBKEM ;If V clear from header read 0571 F7DF ;just ignore all data (since hdr. 0572 F7DF ;interrupted by DCD). 0573 F7DF 0574 F7DF AD C8 03 LDA INFO +BKSZEL 0575 F7E2 0D C9 03 ORA INFO +BKSZEH 0576 F7E5 F0 02 BEQ RDBKEM ;Empty block => no BG job 0577 F7E7 0578 F7E7 A2 04 LDXIM &04 0579 F7E9 86 C2 RDBKEM STX ITYPE 0580 F7EB 0581 F7EB ;V not important from here on 0582 F7EB 0583 F7EB 60 RTS 0584 F7EC 0585 F7EC 0586 F7EC 0587 F7EC 0588 F7EC WRBLOK 0589 F7EC 0590 F7EC WBLOCK 0591 F7EC 0592 F7EC ;Write block pointed to by BKADDR. Expects header info 0593 F7EC ;to be in INFO and file name in FILNAM. 0594 F7EC 0595 F7EC ;Assumes 6850 is in reset state, and SERPROC 0596 F7EC ;is set with motor on. 0597 F7EC 0598 F7EC 08 PHP ;Save I'rupt state 0599 F7ED A2 03 LDXIM &03 ;Set spare bytes 0600 F7EF A9 00 LDAIM &00 0601 F7F1 9D CB 03 SETSPR STAAX INFO +BKSPAR 0602 F7F4 CA DEX 0603 F7F5 10 FA BPL SETSPR 0604 F7F7 0605 F7F7 AD C6 03 LDA INFO +BKNOLO 0606 F7FA 0D C7 03 ORA INFO +BKNOHI 0607 F7FD D0 05 BNE WRBKL5 ;Not first block, continue 0608 F7FF 20 92 F8 JSR LEADER 0609 F802 F0 03 BEQ WRBKL4 ;Always Z exit 0610 F804 0611 F804 20 96 F8 WRBKL5 JSR PUTGAP ;Put out inter-block gap 0612 F807 0613 F807 A9 2A WRBKL4 LDAIM "*" 0614 F809 85 BD STA IBUF ;Start of block char is output IMMEDIATELY 0615 F80B ;on TXINIT. 0616 F80B 0617 F80B 20 78 FB JSR SETJOB 0618 F80E 0619 F80E 20 4A FB JSR TXINIT ;Get 6850 ready 0620 F811 20 84 F8 JSR IWAIT ;Wait for * to go out 0621 F814 0622 F814 88 DEY ;Set zero by SETJOB 0623 F815 C8 WRBKL1 INY 0624 F816 B9 D2 03 LDAAY FILNAM ;Set Z flag if file terminator 0625 F819 99 B2 03 STAAY INFO ;PRTHDR expects INFO to have f.t. in it 0626 F81C 20 75 F8 JSR PUTCHK 0627 F81F 0628 F81F ;Note Z flag kept over PUTCHK 0629 F81F 0630 F81F D0 F4 BNE WRBKL1 ;File title out. 0631 F821 0632 F821 A2 0C LDXIM BKINFO 0633 F823 BD B2 03 WRBKL2 LDAAX INFO ;Rest of header to tape 0634 F826 20 75 F8 JSR PUTCHK 0635 F829 E8 INX 0636 F82A E0 1D CPXIM BKLAST 0637 F82C D0 F5 BNE WRBKL2 0638 F82E 0639 F82E 20 7B F8 JSR PUTCRC 0640 F831 0641 F831 AD C8 03 LDA INFO +BKSZEL 0642 F834 0D C9 03 ORA INFO +BKSZEH 0643 F837 F0 1C BEQ WRBKEM ;Empty block 0644 F839 0645 F839 A0 00 LDYIM &00 0646 F83B 20 7C FB JSR SETJB1 0647 F83E WRBKL3 0648 F83E [ TUBESW=0 0649 F83E B1 B0 LDAIY BKADDR ;Load byte from IO proc. 0650 F840 0651 F840 20 D3 FB JSR TUBCHK ;Check tube present and top two bytes of address 0652 F843 F0 03 BEQ WRBKL6 ;Yes, continue. (Note TAX done in TUBCHK) 0653 F845 AE E5 FE LDX TREG3 ;No, get from tube 0654 F848 0655 F848 8A WRBKL6 TXA ;Restore byte from RAM 0656 F849 | 0658 F849 ] 0659 F849 0660 F849 20 75 F8 JSR PUTCHK ;Output data 0661 F84C C8 INY 0662 F84D CC C8 03 CPY INFO +BKSZEL 0663 F850 D0 EC BNE WRBKL3 0664 F852 0665 F852 20 7B F8 JSR PUTCRC 0666 F855 20 84 F8 WRBKEM JSR IWAIT ;Wait for irupt => char on tape 0667 F858 20 84 F8 JSR IWAIT 0668 F85B 20 46 FB JSR CRESET ;Reset for interblock gap 0669 F85E A9 01 LDAIM &01 0670 F860 20 98 F8 JSR PAUSE ;1/10 sec delay to clear heads 0671 F863 28 PLP ;Restore I'rupt status 0672 F864 0673 F864 20 B9 F8 JSR SAVHDR ;Finally, print info 0674 F867 2C CA 03 BIT INFO +BKFLAG Acorn macro assembler Page 133 C.F.S. UTILITIES - MOS74 0675 F86A 10 08 BPL WRBKEX ;Not last block 0676 F86C 08 PHP 0677 F86D 20 92 F8 JSR TAIL 0678 F870 20 46 F2 JSR FINOP 0679 F873 28 PLP 0680 F874 0681 F874 ;Exit MI if last block, PL otherwise 0682 F874 60 WRBKEX RTS 0683 F875 0684 F875 0685 F875 0686 F875 0687 F875 0688 F875 0689 F875 PUTCHK 0690 F875 0691 F875 ;Output byte to cassette and add to check sum. 0692 F875 0693 F875 20 82 F8 JSR PUTCAS 0694 F878 4C B0 F7 JMP ADDCRC 0695 F87B 0696 F87B 0697 F87B 0698 F87B 0699 F87B A5 BF PUTCRC LDA CHKSUM +&01 0700 F87D 20 82 F8 JSR PUTCAS 0701 F880 A5 BE LDA CHKSUM 0702 F882 0703 F882 0704 F882 PUTCAS 0705 F882 0706 F882 ;Put byte to cassette 0707 F882 0708 F882 85 BD STA IBUF 0709 F884 0710 F884 20 95 F9 IWAIT JSR ESCAPE 0711 F887 24 C0 BIT IFLAG 0712 F889 10 F9 BPL IWAIT 0713 F88B 0714 F88B A9 00 LDAIM &00 0715 F88D 85 C0 STA IFLAG ;Zero IFLAG 0716 F88F A5 BD LDA IBUF ;Restore A 0717 F891 60 RTS ;Note V preserved 0718 F892 0719 F892 0720 F892 0721 F892 LEADER 0722 F892 0723 F892 TAIL 0724 F892 0725 F892 ;Assumes RESET done by WRBLOK 0726 F892 0727 F892 A9 32 LDAIM &32 0728 F894 D0 02 BNE PAUSE ;5 secs hitone altogether. 0729 F896 0730 F896 0731 F896 0732 F896 PUTGAP 0733 F896 0734 F896 ;Note is assumed indivisible by PUTBYT 0735 F896 0736 F896 A5 C7 LDA GAPTIM 0737 F898 0738 F898 PAUSE 0739 F898 0740 F898 ;Pause for A/10 secs (while putting out 0741 F898 ;leaders and gaps mainly). 0742 F898 0743 F898 A2 05 LDXIM &05 0744 F89A 8D 40 02 PSLOP1 STA CYCLE 0745 F89D 20 95 F9 PSLOOP JSR ESCAPE 0746 F8A0 2C 40 02 BIT CYCLE 0747 F8A3 10 F8 BPL PSLOOP 0748 F8A5 CA DEX 0749 F8A6 D0 F2 BNE PSLOP1 0750 F8A8 60 RTS 0751 F8A9 0752 F8A9 0753 F8A9 0754 F8A9 PRTHDR 0755 F8A9 0756 F8A9 ;Print header details. 0757 F8A9 ;Keeps count of file size and prints 0758 F8A9 ;total file length when last block is indicated. 0759 F8A9 ;Expects block info to be in INFO. 0760 F8A9 0761 F8A9 0762 F8A9 AD C6 03 LDA INFO +BKNOLO 0763 F8AC 0D C7 03 ORA INFO +BKNOHI 0764 F8AF F0 05 BEQ PRTHL8 ;If first block, is new file 0765 F8B1 2C DF 03 BIT OLDFLG ;If previous block = last block 0766 F8B4 10 03 BPL PRTHL3 ;then new line 0767 F8B6 0768 F8B6 PRTHDL 0769 F8B6 20 49 F2 PRTHL8 JSR NOOLN1 ;New line if messages on and no error 0770 F8B9 0771 F8B9 SAVHDR 0772 F8B9 0773 F8B9 ;Entry from WRBLOK 0774 F8B9 0775 F8B9 A0 00 PRTHL3 LDYIM &00 0776 F8BB 84 BA STY ERRSW 0777 F8BD AD CA 03 LDA INFO +BKFLAG 0778 F8C0 8D DF 03 STA OLDFLG ;Set prev. flag 0779 F8C3 0780 F8C3 0781 F8C3 20 DC E7 JSR MSGON 0782 F8C6 F0 6B BEQ PRTHLX ;Messages off => exit 0783 F8C8 0784 F8C8 A9 0D LDAIM MCR 0785 F8CA 20 EE FF JSR OSWRCH 0786 F8CD 0787 F8CD ; Note assumed here Y is preserved over 0788 F8CD ;calls to MSGON and OSWRCH. 0789 F8CD 0790 F8CD B9 B2 03 PRTHL1 LDAAY INFO 0791 F8D0 F0 10 BEQ PRTHL2 ;Zero terminator for filename 0792 F8D2 0793 F8D2 C9 20 CMPIM &20 0794 F8D4 90 04 BCC PRTHLD ;A<$20 => control char => invalid 0795 F8D6 C9 7F CMPIM &7F Acorn macro assembler Page 134 C.F.S. UTILITIES - MOS74 0796 F8D8 90 02 BCC PRTHLC ;$20<=A<$7F => Valid 0797 F8DA 0798 F8DA A9 3F PRTHLD LDAIM "?" ;Otherwise, print ?? 0799 F8DC 20 EE FF PRTHLC JSR OSWRCH ;Write file title 0800 F8DF C8 INY 0801 F8E0 D0 EB BNE PRTHL1 0802 F8E2 0803 F8E2 AD 47 02 PRTHL2 LDA SROMSW 0804 F8E5 F0 04 BEQ PRTHLF ;In CFS -> continue 0805 F8E7 24 BB BIT USFLGS 0806 F8E9 50 48 BVC PRTHLX ;SFS short msgs => file name only 0807 F8EB 0808 F8EB 20 91 F9 PRTHLF JSR PRTSP 0809 F8EE C8 INY 0810 F8EF C0 0B CPYIM FTSIZE 0811 F8F1 90 EF BCC PRTHL2 0812 F8F3 0813 F8F3 AD C6 03 LDA INFO +BKNOLO 0814 F8F6 AA TAX ;Store for final length 0815 F8F7 20 7A F9 JSR WHEX ;Write block no. lo 0816 F8FA 0817 F8FA 2C CA 03 BIT INFO +BKFLAG 0818 F8FD 10 34 BPL PRTHLX ;Not last block -> finish 0819 F8FF 0820 F8FF ;Here, is last block -> print total length 0821 F8FF 0822 F8FF 8A TXA ;X set at PRTHLA 0823 F900 18 CLC 0824 F901 6D C9 03 ADC INFO +BKSZEH ;Gross huh ? 0825 F904 [ LENSW=0 0826 F904 85 CD STA FSIZE + 1 ;Store for load to modify OSFILE block 0827 F906 ] 0828 F906 20 75 F9 JSR WSPHEX 0829 F909 AD C8 03 LDA INFO +BKSZEL 0830 F90C [ LENSW=0 0831 F90C 85 CC STA FSIZE ;Store for load to modify OSFILE block 0832 F90E ] 0833 F90E 20 7A F9 JSR WHEX 0834 F911 0835 F911 24 BB BIT USFLGS 0836 F913 50 1E BVC PRTHLX ;=> Short messages => exit 0837 F915 0838 F915 ;Here doing long messages 0839 F915 0840 F915 A2 04 LDXIM &04 0841 F917 20 91 F9 PRTHLV JSR PRTSP 0842 F91A CA DEX 0843 F91B D0 FA BNE PRTHLV 0844 F91D 0845 F91D A2 0F LDXIM BKLOAD +&03 0846 F91F 20 27 F9 JSR PRTHLT 0847 F922 20 91 F9 JSR PRTSP 0848 F925 A2 13 LDXIM BKEXEC +&03 0849 F927 0850 F927 A0 04 PRTHLT LDYIM &04 0851 F929 BD B2 03 PRTHLU LDAAX INFO 0852 F92C 20 7A F9 JSR WHEX 0853 F92F CA DEX 0854 F930 88 DEY 0855 F931 D0 F6 BNE PRTHLU 0856 F933 0857 F933 RECEXX 0858 F933 60 PRTHLX RTS 0859 F934 0860 F934 0861 F934 0862 F934 0863 F934 RECORD 0864 F934 0865 F934 AD 47 02 LDA SROMSW 0866 F937 F0 03 BEQ RECRD2 ;OK if not in SFS 0867 F939 4C 10 E3 JMP MBDCMD ;Otherwise bad command 0868 F93C 0869 F93C RECRD2 0870 F93C 20 8E FB JSR MOTONW ;Motor ON for OUTPUT 0871 F93F 20 E2 FB JSR BUGFIX 0872 F942 20 DC E7 JSR MSGON 0873 F945 F0 EC BEQ RECEXX 0874 F947 0875 F947 20 46 FA JSR MSGOUT ;If messages ON, prompt 0876 F94A 52 45 43 = "RECORD then RETURN" 0877 F95C 00 = &00 0878 F95D 0879 F95D 20 95 F9 GETCR1 JSR ESCAPE 0880 F960 20 E0 FF JSR OSRDCH 0881 F963 C9 0D CMPIM MCR 0882 F965 D0 F6 BNE GETCR1 0883 F967 4C E7 FF JMP OSNEWL 0884 F96A 0885 F96A 0886 F96A LNK MOS76 0001 F96A 0002 F96A TTL C.F.S. - I/O Utilities -> MOS76 0003 F96A OPT MOS76 Acorn macro assembler Page 135 C.F.S. - I/O Utilities -> MOS76 0004 F96A 0005 F96A 0006 F96A ;****** UTILITIES II ****** 0007 F96A 0008 F96A ADDBKA 0009 F96A 0010 F96A ;Increment block pointer by 256 bytes, assuming that 0011 F96A ;block received is 256 bytes long. Note BKADDR is 4 bytes 0012 F96A 0013 F96A E6 B1 INC BKADDR +&01 0014 F96C D0 06 BNE ADDBK1 0015 F96E E6 B2 INC BKADDR +&02 0016 F970 D0 02 BNE ADDBK1 0017 F972 E6 B3 INC BKADDR +&03 0018 F974 60 ADDBK1 RTS 0019 F975 0020 F975 0021 F975 0022 F975 0023 F975 48 WSPHEX PHA 0024 F976 20 91 F9 JSR PRTSP 0025 F979 68 PLA 0026 F97A 48 WHEX PHA 0027 F97B 4A LSRA 0028 F97C 4A LSRA 0029 F97D 4A LSRA 0030 F97E 4A LSRA 0031 F97F 20 83 F9 JSR WDIGIT 0032 F982 68 PLA 0033 F983 18 WDIGIT CLC 0034 F984 29 0F ANDIM &0F 0035 F986 69 30 ADCIM "0" 0036 F988 C9 3A CMPIM &3A 0037 F98A 90 02 BCC HXDSKP 0038 F98C 69 06 ADCIM &06 0039 F98E 4C EE FF HXDSKP JMP OSWRCH 0040 F991 0041 F991 0042 F991 0043 F991 0044 F991 A9 20 PRTSP LDAIM SPACE 0045 F993 D0 F9 BNE HXDSKP 0046 F995 0047 F995 0048 F995 ESCAPE 0049 F995 0050 F995 ;Checks ESCAPE happened. If so, does error 0051 F995 ;break with appropriate message after 0052 F995 ;acknowldging the ESCAPE. 0053 F995 0054 F995 ;Also switches off various status bits 0055 F995 ;Motor switched OFF 0056 F995 0057 F995 ;Note, no test is done if inside WRCH or RDCH 0058 F995 ;so that ESCAPE cannot occur inside EXEC/SPOOL 0059 F995 0060 F995 08 PHP 0061 F996 24 EB BIT ESSEMA 0062 F998 30 04 BMI ESCLL0 ;Inside WRCH or RDCH -> no ESCAPE 0063 F99A 24 FF BIT ESCADD 0064 F99C 30 02 BMI ESCERR 0065 F99E ESCLL0 0066 F99E 28 PLP 0067 F99F 60 RTS 0068 F9A0 0069 F9A0 ESCERR 0070 F9A0 0071 F9A0 20 3B F3 JSR CATOFF ;Switch CAT bit off 0072 F9A3 20 F2 FA JSR CASMOF ;Motor OFF/release 0073 F9A6 0074 F9A6 A9 7E LDAIM &7E 0075 F9A8 20 F4 FF JSR OSBYTE ;Acknowledge ESC to MOS 0076 F9AB 0077 F9AB 00 BRK ;Then error 0078 F9AC 11 45 73 = &11,"Escape",0 0079 F9B4 0080 F9B4 0081 F9B4 0082 F9B4 0083 F9B4 0084 F9B4 98 LODHDR TYA 0085 F9B5 F0 0D BEQ LODHD1 ;Print message depending on Y 0086 F9B7 20 46 FA JSR MSGOUT 0087 F9BA 0D 4C 6F = MCR,"Loading",MCR,0 0088 F9C4 0089 F9C4 0090 F9C4 0091 F9C4 LODHD1 0092 F9C4 0093 F9C4 85 BA STA ERRSW ;A always zero at this point 0094 F9C6 ;Set ERRSW so always extra line after "Loading" 0095 F9C6 ;and before file name. 0096 F9C6 0097 F9C6 0098 F9C6 A2 FF LDXIM &FF ;Set "abort if nesc." flag 0099 F9C8 A5 C1 LDA HDRCRC 0100 F9CA D0 0D BNE HDRCHK ;Header CRC error takes precedence over 0101 F9CC ;file and block errors, since a header error may 0102 F9CC ;spuriously cause either or both of these. 0103 F9CC 0104 F9CC 20 72 FA JSR CMPFT 0105 F9CF 0106 F9CF 08 PHP ;Store EQ bit from CMPFT 0107 F9D0 A2 FF LDXIM &FF ;Set "abort if nesc." flag 0108 F9D2 A0 99 LDYIM FILEER 0109 F9D4 A9 FA LDAIM /(FILEER ) ;Set error pointers 0110 F9D6 28 PLP 0111 F9D7 0112 F9D7 D0 1C BNE TAPER0 ;Files don't match 0113 F9D9 0114 F9D9 CATERR ;Entry from catalogue here 0115 F9D9 HDRCHK 0116 F9D9 A0 8E LDYIM DATAER ;Set lo byte of error pointer 0117 F9DB A5 C1 LDA HDRCRC ;Was header CRC ok ? 0118 F9DD F0 04 BEQ CHKBKN ;Yes, check block no. 0119 F9DF A9 FA LDAIM /(DATAER ) ;No, do error 0120 F9E1 D0 12 BNE TAPER0 0121 F9E3 0122 F9E3 0123 F9E3 AD C6 03 CHKBKN LDA INFO +BKNOLO ;Is expected block ?? 0124 F9E6 C5 B4 CMP BLOKNO Acorn macro assembler Page 136 C.F.S. - I/O Utilities -> MOS76 0125 F9E8 D0 07 BNE BLKERR 0126 F9EA AD C7 03 LDA INFO +BKNOHI 0127 F9ED C5 B5 CMP BLOKNO +&01 0128 F9EF F0 13 BEQ CHEKSM ;No error -> go on 0129 F9F1 0130 F9F1 A0 A4 BLKERR LDYIM BLOKER 0131 F9F3 A9 FA LDAIM /(BLOKER ) 0132 F9F5 0133 F9F5 48 TAPER0 PHA ;Store error ptr. 0134 F9F6 98 TYA 0135 F9F7 48 PHA 0136 F9F8 8A TXA ;Store "abort if nesc." flag 0137 F9F9 48 PHA 0138 F9FA 20 B6 F8 JSR PRTHDL ;Print header ON NEW LINE 0139 F9FD 68 PLA 0140 F9FE AA TAX 0141 F9FF 68 PLA 0142 FA00 A8 TAY 0143 FA01 68 PLA 0144 FA02 D0 14 BNE TAPERR 0145 FA04 0146 FA04 8A CHEKSM TXA 0147 FA05 48 PHA ;Store X over possible IRUPT call 0148 FA06 20 A9 F8 JSR PRTHDR ; Print header info. 0149 FA09 0150 FA09 20 D6 FA JSR CHEKLP ;Wait for end of BG job 0151 FA0C ;In SFS, CHEKLP reads next SFS block 0152 FA0C 0153 FA0C ;Note X & Y corrupted by IRUPT, which 0154 FA0C ;is only called when SROM system active. 0155 FA0C ;Y is restored at ERREXT. 0156 FA0C ; 0157 FA0C 68 PLA 0158 FA0D AA TAX ;Restore "abort if nesc." flag 0159 FA0E 0160 FA0E A5 BE LDA CHKSUM 0161 FA10 05 BF ORA CHKSUM +&01 0162 FA12 F0 79 BEQ ERREXX ;No errors, tape ok, exit 0163 FA14 0164 FA14 A0 8E LDYIM DATAER ;Set message ptr. 0165 FA16 A9 FA LDAIM /(DATAER ) 0166 FA18 0167 FA18 C6 BA TAPERR DEC ERRSW 0168 FA1A 48 PHA ;Store hi byte of error pointer 0169 FA1B 0170 FA1B 24 EB BIT ESSEMA 0171 FA1D 30 0D BMI ERRABT ;During EXEC/SPOOL can ABORT ONLY ! 0172 FA1F 0173 FA1F 8A TXA ;If X = 0 => print only, X = $FF abort if nesc. 0174 FA20 2D 47 02 AND SROMSW ;If not cataloging, and SROM => abort 0175 FA23 D0 07 BNE ERRABT 0176 FA25 8A TXA ;Otherwise, check if "abort on error" option set 0177 FA26 ;If so, do BRK 0178 FA26 0179 FA26 29 11 ANDIM ABTBIT 0180 FA28 25 BB AND USFLGS 0181 FA2A F0 10 BEQ PRTERR ;Abort not set => print 0182 FA2C 0183 FA2C 68 ERRABT PLA 0184 FA2D 85 B9 STA FTPTR +&01 ;Set error pointer 0185 FA2F 84 B8 STY FTPTR 0186 FA31 20 8B F6 JSR ECLOSE ;close EXEC file 0187 FA34 46 EB LSR ESSEMA ;Switch off critical region 0188 FA36 20 E8 FA JSR BEEPOF ;Motor off/BEEP 0189 FA39 6C B8 00 JMI FTPTR ;Abort = break with error msg. 0190 FA3C 0191 FA3C 68 PRTERR PLA ;Restore hi byte of pointer 0192 FA3D 0193 FA3D ;Now must add ONE to pointer to get past BRK 0194 FA3D ;at front of message. Note MSGOUT does an INC 0195 FA3D ;before printing, so don't have to add 2. 0196 FA3D 0197 FA3D C8 INY ;Inc lo byte past BRK instruction 0198 FA3E D0 03 BNE PRTEON 0199 FA40 18 CLC 0200 FA41 69 01 ADCIM &01 0201 FA43 48 PRTEON PHA ;Set stack for MSGOUT 0202 FA44 98 TYA 0203 FA45 48 PHA 0204 FA46 ; Print message and enter code 0205 FA46 ; directly AFTER message 0206 FA46 ; 0207 FA46 MSGOUT 0208 FA46 0209 FA46 ;Enter here for messages printed if MSGON 0210 FA46 ;Note, X must be preserved 0211 FA46 0212 FA46 20 DC E7 JSR MSGON 0213 FA49 A8 TAY ;Store for STROUT 0214 FA4A 0215 FA4A STROUT 0216 FA4A 0217 FA4A 0218 FA4A 68 PLA 0219 FA4B 85 B8 STA FTPTR 0220 FA4D 68 PLA 0221 FA4E 85 B9 STA FTPTR +&01 0222 FA50 98 TYA 0223 FA51 08 PHP ;Z bit => print 0224 FA52 E6 B8 VSTRLP INC FTPTR 0225 FA54 D0 02 BNE VSTRL1 0226 FA56 E6 B9 INC FTPTR +&01 0227 FA58 A0 00 VSTRL1 LDYIM &00 0228 FA5A B1 B8 LDAIY FTPTR 0229 FA5C F0 0A BEQ VSTREX 0230 FA5E 28 PLP 0231 FA5F 08 PHP 0232 FA60 F0 F0 BEQ VSTRLP ;If Z set => don't print 0233 FA62 20 E3 FF JSR OSASCI 0234 FA65 4C 52 FA JMP VSTRLP 0235 FA68 28 VSTREX PLP ;Restore stack 0236 FA69 E6 B8 INC FTPTR 0237 FA6B D0 02 BNE VSTREZ 0238 FA6D E6 B9 INC FTPTR +&01 0239 FA6F 0240 FA6F ;Exit always with Z CLEAR 0241 FA6F 0242 FA6F 6C B8 00 VSTREZ JMI FTPTR 0243 FA72 0244 FA72 0245 FA72 CMPFT Acorn macro assembler Page 137 C.F.S. - I/O Utilities -> MOS76 0246 FA72 A2 FF LDXIM &FF 0247 FA74 CMPFT2 0248 FA74 E8 INX 0249 FA75 CMPFT1 ;match filename, equating cases 0250 FA75 BD D2 03 LDAAX FILNAM 0251 FA78 D0 07 BNE CMPFT3 ;[not at end of filename] 0252 FA7A ; 0253 FA7A ; at end of filename, either: 0254 FA7A ; X=0 => match on filename "" (null filename) 0255 FA7A ; X<>0 => INFO(X)=0 => match, <>0 => no match 0256 FA7A ; 0257 FA7A 8A TXA 0258 FA7B F0 03 BEQ CMPFT0 ;[match on filename "", return EQ status] 0259 FA7D BD B2 03 LDAAX INFO 0260 FA80 CMPFT0 ;EQ => match, NE => no match 0261 FA80 60 RTS 0262 FA81 0263 FA81 CMPFT3 ;not at end of filename 0264 FA81 20 E3 E4 JSR CAPS 0265 FA84 5D B2 03 EORAX INFO 0266 FA87 B0 02 BCS NALPHA 0267 FA89 ; filename character is a letter 0268 FA89 29 DF ANDIM &DF ;equate cases 0269 FA8B NALPHA 0270 FA8B F0 E7 BEQ CMPFT2 0271 FA8D ; filenames not equal 0272 FA8D ; return NE status 0273 FA8D ERREXX ;Called from around CSON1 0274 FA8D 60 RTS 0275 FA8E 0276 FA8E 0277 FA8E 0278 FA8E 00 DATAER BRK 0279 FA8F D8 = CFSERJ 0280 FA90 0D 44 61 = MCR,"Data?",0 0281 FA97 0282 FA97 D0 15 BNE REWIND ;Z always CLEAR after MSGOUT 0283 FA99 00 FILEER BRK 0284 FA9A DB = CFSERF 0285 FA9B 0D 46 69 = MCR,"File?",0 0286 FAA2 0287 FAA2 D0 0A BNE REWIND ;Z always CLEAR after MSGOUT 0288 FAA4 00 BLOKER BRK 0289 FAA5 DA = CFSERH 0290 FAA6 0D 42 6C = MCR,"Block?",0 0291 FAAE 0292 FAAE 0293 FAAE A5 BA REWIND LDA ERRSW 0294 FAB0 F0 21 BEQ ERROEX ;If no error, leave 0295 FAB2 8A TXA 0296 FAB3 F0 1E BEQ ERROEX ;If only printing, no retry 0297 FAB5 A9 22 LDAIM RETBIT ;Otherwise, see if RETRY set 0298 FAB7 24 BB BIT USFLGS 0299 FAB9 F0 18 BEQ ERROEX 0300 FABB 20 46 FB JSR CRESET 0301 FABE A8 TAY ;Assume A is non-zero from RESET 0302 FABF 20 4A FA JSR STROUT 0303 FAC2 0D 07 52 = MCR,BEL,"Rewind tape",MCR,MCR,0 0304 FAD2 0305 FAD2 0306 FAD2 ;Note NZ set by VSTRIN here 0307 FAD2 60 CSON1 RTS 0308 FAD3 0309 FAD3 0310 FAD3 20 4D F2 ERROEX JSR NOOLIN ;New line if msgs on 0311 FAD6 0312 FAD6 ;Wait for BG job to finish since if IGNORE set, must 0313 FAD6 ;allow LOADs etc. to complete. 0314 FAD6 0315 FAD6 A5 C2 CHEKLP LDA ITYPE 0316 FAD8 F0 F8 BEQ CSON1 ;If BG job finished exit with EQ status 0317 FADA 0318 FADA ;Note: loop must check ITYPE first, coz may be no 0319 FADA ;BG job in the case of zero length file. Therefore 0320 FADA ;don't want to read next SROM byte. 0321 FADA 0322 FADA 20 95 F9 JSR ESCAPE 0323 FADD AD 47 02 LDA SROMSW 0324 FAE0 F0 F4 BEQ CHEKLP ;If no speech, wait for end 0325 FAE2 20 88 F5 JSR IRUPT ;Otherwise, get next byte 0326 FAE5 4C D6 FA JMP CHEKLP ;And loop 0327 FAE8 0328 FAE8 0329 FAE8 0330 FAE8 ;CHIP CONTROL 0331 FAE8 0332 FAE8 20 DC E7 BEEPOF JSR MSGON 0333 FAEB F0 05 BEQ CASMOF 0334 FAED A9 07 LDAIM &07 0335 FAEF 20 EE FF JSR OSWRCH ;Cannot use MSGOUT, coz called from inside it 0336 FAF2 A9 80 CASMOF LDAIM TUBERL ;Tube release number 0337 FAF4 20 BD FB JSR TBINIT ;Release tube 0338 FAF7 0339 FAF7 ;NOTE - TBINIT checks BKADDR. However, either at this point 0340 FAF7 ;the tube has been claimed, in which case BKADDR is still a 0341 FAF7 ;tube address and the release will go through; or the tube 0342 FAF7 ;has not been claimed, in which case it don't matter if the 0343 FAF7 ;release don't happen. NOTE also that a claim is done in 0344 FAF7 ;TBINIT before the release, so that spurious claims may 0345 FAF7 ;result depending on the values in BKADDR. These will, however 0346 FAF7 ;be immediately released again. 0347 FAF7 0348 FAF7 A2 00 LDXIM &00 0349 FAF9 20 95 FB JSR CMOTOR ;Motor off: drive set in MOTOR. 0350 FAFC ; 0351 FAFC RELEAS 0352 FAFC ; called by CFS on exit from any cassette operation 0353 FAFC ; N.B. RS423 might not have been claimed beforehand 0354 FAFC ; 0355 FAFC 08 PHP 0356 FAFD 78 SEI ;must disable interrupts 0357 FAFE ; 0358 FAFE ; restore MOS 6850 and serproc byte 0359 FAFE ; 0360 FAFE AD 82 02 LDA SPREGA 0361 FB01 8D 10 FE STA SERPRC 0362 FB04 ; 0363 FB04 A9 00 LDAIM ZERO 0364 FB06 85 EA STA RSTUT 0365 FB08 F0 01 BEQ RELX ;[ALWAYS jump] 0366 FB0A ; Acorn macro assembler Page 138 C.F.S. - I/O Utilities -> MOS76 0367 FB0A MC6850 0368 FB0A 08 PHP 0369 FB0B ; 0370 FB0B RELX 0371 FB0B ; CORRUPTS A 0372 FB0B ; setup MC6850 0373 FB0B ; disable Rx/Tx interrupts 0374 FB0B ; divide by 64, 7 data bits + 1 stop bit, even parity 0375 FB0B ; or 8 bits, one stop bit, no parity!! 0376 FB0B ; 0377 FB0B 20 46 FB JSR CRESET ;master reset 0378 FB0E ; 0379 FB0E ; reset data format bits 0380 FB0E ; 0381 FB0E AD 50 02 LDA RSCTFL 0382 FB11 ; 0383 FB11 4C 89 E1 JMP STARSC ;share code with 'RS423' 0384 FB14 0385 FB14 0386 FB14 RSWT1 0387 FB14 28 PLP 0388 FB15 24 FF BIT ESCFLG 0389 FB17 10 18 BPL CLAIM ;[no escape, ALWAYS jump] 0390 FB19 ; 0391 FB19 ; escape condition 0392 FB19 ; 0393 FB19 60 RTS 0394 FB1A 0395 FB1A 0396 FB1A A5 E3 SETSDF LDA OPTS ;Set options for sequential access 0397 FB1C 0A ASLA ;=> bottom nybble of OPTS 0398 FB1D 0A ASLA 0399 FB1E 0A ASLA 0400 FB1F 0A ASLA 0401 FB20 85 BB STA USFLGS 0402 FB22 AD D1 03 LDA SEQGAP ;Set (variable) PUTBYTE gap time 0403 FB25 D0 08 BNE GAPOUT ;[ALWAYS JUMP] 0404 FB27 ; 0405 FB27 A5 E3 SETDEF LDA OPTS 0406 FB29 29 F0 ANDIM &F0 ;Chop out seq. opts 0407 FB2B 85 BB STA USFLGS ;Set options for load/save operation 0408 FB2D [ GLYN =0 ;If special system for glyn 0410 FB2D | 0411 FB2D A9 06 LDAIM GAP ;Set SAVE gap -> unchangeable 0412 FB2F ] 0413 FB2F 85 C7 GAPOUT STA GAPTIM 0414 FB31 ; 0415 FB31 ; fall thru into CLAIM 0416 FB31 ; 0417 FB31 CLAIM 0418 FB31 ; Claim RS423 h/w interface 0419 FB31 ; Called by CFS 0420 FB31 58 CLI 0421 FB32 08 PHP 0422 FB33 78 SEI 0423 FB34 2C 4F 02 BIT RSFLAG 0424 FB37 10 DB BPL RSWT1 ;[RS423 busy] 0425 FB39 A5 EA LDA RSTUT 0426 FB3B 30 D7 BMI RSWT1 ;[RS423 dormant, but still timing out] 0427 FB3D ; RS423 dormant and timed out OR claimed => RS423 available 0428 FB3D ; RSTUT>=0 0429 FB3D ; headline: 'CFS Claims RS423' 0430 FB3D A9 01 LDAIM &01 ;allow for many call claims 0431 FB3F 85 EA STA RSTUT ;RSTUT := 1 0432 FB41 0433 FB41 [ &00=0 0434 FB41 20 46 FB JSR CRESET 0435 FB44 28 PLP 0436 FB45 60 RTS 0437 FB46 | 0440 FB46 ] 0441 FB46 0442 FB46 0443 FB46 A9 03 CRESET LDAIM &03 0444 FB48 D0 1B BNE SETCHP 0445 FB4A 0446 FB4A 0447 FB4A TXINIT 0448 FB4A A9 30 LDAIM TXSTAT 0449 FB4C 85 CA STA TXFLAG 0450 FB4E D0 13 BNE CHPINT 0451 FB50 0452 FB50 A9 05 RXINIT LDAIM SEROFF 0453 FB52 0454 FB52 ;Switch motor off without going through OS 0455 FB52 ;coz don't want user to be bothered with each 0456 FB52 ;motor blip 0457 FB52 0458 FB52 8D 10 FE STA SERPRC 0459 FB55 0460 FB55 A2 FF LDXIM &FF ;250 * 2.5 usecs = 1 millisec 0461 FB57 CA RXINL1 DEX 0462 FB58 D0 FD BNE RXINL1 0463 FB5A 86 CA STX TXFLAG 0464 FB5C 0465 FB5C A9 85 LDAIM SERON 0466 FB5E 8D 10 FE STA SERPRC ;Motor on again 0467 FB61 0468 FB61 A9 D0 LDAIM RXSTAT 0469 FB63 05 C6 CHPINT ORA SPEED ;Put in bottom bit, set in INIT from MOS 0470 FB65 8D 08 FE SETCHP STA STATUS 0471 FB68 60 RTS 0472 FB69 0473 FB69 0474 FB69 AE C6 03 NXTBLK LDX INFO +BKNOLO 0475 FB6C AC C7 03 LDY INFO +BKNOHI 0476 FB6F E8 INX 0477 FB70 86 B4 STX BLOKNO 0478 FB72 D0 01 BNE NXTBLX 0479 FB74 C8 INY 0480 FB75 84 B5 NXTBLX STY BLOKNO +&01 0481 FB77 60 RTS 0482 FB78 0483 FB78 A0 00 SETJOB LDYIM &00 0484 FB7A 84 C0 STY IFLAG 0485 FB7C 84 BE SETJB1 STY CHKSUM 0486 FB7E 84 BF STY CHKSUM +&01 0487 FB80 60 RTS 0488 FB81 0489 FB81 0490 FB81 A0 FF MOVFN LDYIM &FF Acorn macro assembler Page 139 C.F.S. - I/O Utilities -> MOS76 0491 FB83 C8 MOVFNL INY 0492 FB84 E8 INX 0493 FB85 BD 00 03 LDAAX VARPGE 0494 FB88 99 D2 03 STAAY FILNAM 0495 FB8B D0 F6 BNE MOVFNL 0496 FB8D 60 RTS 0497 FB8E 0498 FB8E 0499 FB8E A0 00 MOTONW LDYIM WRITFX ;Motor on for output 0500 FB90 58 MOTON CLI ;Ensure can talk to tape 0501 FB91 A2 01 LDXIM &01 ;Motor on 0502 FB93 84 C3 STY CURDRV ;Store current drive 0503 FB95 A9 89 CMOTOR LDAIM FXMOTR ;=> motor function 0504 FB97 0505 FB97 ;Load drive number into Y, so switching motor 0506 FB97 ;off is always done with the drive most recently 0507 FB97 ;switched on (seems logical). 0508 FB97 0509 FB97 A4 C3 LDY CURDRV 0510 FB99 4C F4 FF JMP OSBYTE 0511 FB9C 0512 FB9C CHKHND 0513 FB9C 0514 FB9C ;Check handle in Y is open 0515 FB9C ;and corresponds to mask in A 0516 FB9C 0517 FB9C 85 BC STA TEMP 0518 FB9E 98 TYA 0519 FB9F 4D 47 02 EOR SROMSW ;Reverse SFS bit in handle if in SFS 0520 FBA2 A8 TAY 0521 FBA3 A5 E2 LDA CFSTAT 0522 FBA5 25 BC AND TEMP ;Mask out bits not required 0523 FBA7 4A LSRA 0524 FBA8 88 DEY 0525 FBA9 F0 04 BEQ CHKHN1 0526 FBAB 4A LSRA 0527 FBAC 88 DEY 0528 FBAD D0 02 BNE HNDERR 0529 FBAF B0 4D CHKHN1 BCS CHKHXX 0530 FBB1 0531 FBB1 0532 FBB1 00 HNDERR BRK 0533 FBB2 DE = CFSERB 0534 FBB3 43 68 61 = "Channel",0 0535 FBBB 0536 FBBB 0537 FBBB 0538 FBBB TWINIT 0539 FBBB A9 01 LDAIM TUBEW ;Write init. for tube 0540 FBBD TBINIT 0541 FBBD ;Check the address at BKADDR is accross tube 0542 FBBD ;and that tube is present. If so, claim tube, and call 0543 FBBD ;address routine with value origionally in A on entry. 0544 FBBD 0545 FBBD 20 D3 FB JSR TUBCHK ;Check address + tube present. 0546 FBC0 F0 3C BEQ TINIT0 ;Don't tube. (NOTE TAX done in TUBCHK) 0547 FBC2 8A TXA ;Restore tube reason code 0548 FBC3 A2 B0 LDXIM BKADDR 0549 FBC5 A0 00 LDYIM /(BKADDR ) ;Address for tube routine 0550 FBC7 48 TBINT1 PHA ;Entry from RUN with non-BKADDR address 0551 FBC8 A9 C0 LDAIM TUBECL ;"Claim" reason code 0552 FBCA 20 06 04 TUBELP JSR TBADDR ;Attempt claim 0553 FBCD 90 FB BCC TUBELP ;Continue to try and claim 0554 FBCF 68 PLA ;Restore address reason code 0555 FBD0 4C 06 04 JMP TBADDR 0556 FBD3 0557 FBD3 0558 FBD3 0559 FBD3 AA TUBCHK TAX ;Store A 0560 FBD4 A5 B2 LDA BKADDR +&02 0561 FBD6 25 B3 AND BKADDR +&03 0562 FBD8 C9 FF CMPIM &FF ;If $FF, address is IO proc., so exit 0563 FBDA F0 05 BEQ TUBCHX 0564 FBDC AD 7A 02 LDA TUBE 0565 FBDF 29 80 ANDIM &80 ;Returns NZ if tube present, EQ if not 0566 FBE1 60 TUBCHX RTS 0567 FBE2 0568 FBE2 0569 FBE2 0570 FBE2 BUGFIX 0571 FBE2 0572 FBE2 ;When the 6850 counter divide bits are reset, it 0573 FBE2 ;is possible for the SERPROC to get out of synch. 0574 FBE2 ;for a few bits. This has the effect of corrupting 0575 FBE2 ;the first character of the first block of a SAVE, 0576 FBE2 ;or the first character of ANY block during sequential 0577 FBE2 ;access (since the 6850 is reset for every block 0578 FBE2 ;during putbytes). 0579 FBE2 ; The cure is to write a dummy byte to tape at the 0580 FBE2 ;start of a SAVE, and at the start of every block 0581 FBE2 ;during putbytes. This must be done by polling, 0582 FBE2 ;since there must be a period of high-tone after 0583 FBE2 ;the dummy byte, which is difficult to accomplish 0584 FBE2 ;if the 6850 is interrupting all the time. 0585 FBE2 ; BUGFIX is thus called after the SERPROC is set 0586 FBE2 ;and before the 6850 is set to interrupt during 0587 FBE2 ;a block write operation. 0588 FBE2 0589 FBE2 A9 85 LDAIM SERON 0590 FBE4 8D 10 FE STA SERPRC ;Set SERPROC on 0591 FBE7 20 46 FB JSR CRESET ;Reset 6850 to be on safe side 0592 FBEA A9 10 LDAIM &10 0593 FBEC 20 63 FB JSR CHPINT ;Set 6850 at appropriate clock rate 0594 FBEF 0595 FBEF 20 95 F9 BUGLP JSR ESCAPE 0596 FBF2 AD 08 FE LDA STATUS 0597 FBF5 29 02 ANDIM &02 ;Ready to TX ? 0598 FBF7 F0 F6 BEQ BUGLP ;Nope -> loop 0599 FBF9 A9 AA LDAIM &AA 0600 FBFB 8D 09 FE STA PORT ;Shove out the dummy byte 0601 FBFE CHKHXX 0602 FBFE TINIT0 0603 FBFE 60 RTS 0604 FBFF 0605 FBFF 0606 FBFF END 0607 FBFF 0608 FBFF [ $Tutu 0610 FBFF ] 0611 FBFF 0612 FBFF ; pad with zero bytes to ensure ROM CRCs consistent Acorn macro assembler Page 140 C.F.S. - I/O Utilities -> MOS76 0613 FBFF 00 00 00 % &100 0614 FCFF 0615 FCFF < 1 0616 FCFF 0617 FCFF LNK MOS99 0001 FCFF ; MOS99 0002 FCFF TTL MOS99 Operating system ROM entry points and hardware vectors 0003 FCFF OPT MOS99 Acorn macro assembler Page 141 MOS99 Operating system ROM entry points and hardware vectors 0004 FCFF 0005 FCFF ;(c) 1981 ACORN Computers Limited 0006 FCFF ;BBC Microcomputer Machine Operating System (MOS) 0007 FCFF 0008 FCFF ;Change record: 0009 FCFF 0010 FCFF ;Author(s): 0011 FCFF ;PB Paul Bond 0012 FCFF 0013 FCFF 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 CD = 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 51 FF JSR OSROM 0100 FF03 0101 FF03 ROMBRK 0102 FF03 20 51 FF JSR OSROM 0103 FF06 0104 FF06 ROMIRA 0105 FF06 20 51 FF JSR OSROM 0106 FF09 0107 FF09 ROMIRB 0108 FF09 20 51 FF JSR OSROM 0109 FF0C 0110 FF0C ROMCOM 0111 FF0C 20 51 FF JSR OSROM 0112 FF0F 0113 FF0F ROMBYT 0114 FF0F 20 51 FF JSR OSROM 0115 FF12 0116 FF12 ROMWRD 0117 FF12 20 51 FF JSR OSROM 0118 FF15 0119 FF15 ROMWRC 0120 FF15 20 51 FF JSR OSROM 0121 FF18 0122 FF18 ROMRDC 0123 FF18 20 51 FF JSR OSROM 0124 FF1B Acorn macro assembler Page 142 MOS99 Operating system ROM entry points and hardware vectors 0125 FF1B ROMFIL 0126 FF1B 20 51 FF JSR OSROM 0127 FF1E 0128 FF1E ROMARG 0129 FF1E 20 51 FF JSR OSROM 0130 FF21 0131 FF21 ROMBGT 0132 FF21 20 51 FF JSR OSROM 0133 FF24 0134 FF24 ROMBPT 0135 FF24 20 51 FF JSR OSROM 0136 FF27 0137 FF27 ROMGPB 0138 FF27 20 51 FF JSR OSROM 0139 FF2A 0140 FF2A ROMFND 0141 FF2A 20 51 FF JSR OSROM 0142 FF2D 0143 FF2D ROMFSC 0144 FF2D 20 51 FF JSR OSROM 0145 FF30 0146 FF30 ROMEVT 0147 FF30 20 51 FF JSR OSROM 0148 FF33 0149 FF33 ROMUPT 0150 FF33 20 51 FF JSR OSROM 0151 FF36 0152 FF36 ROMNET 0153 FF36 20 51 FF JSR OSROM 0154 FF39 0155 FF39 ROMVDU 0156 FF39 20 51 FF JSR OSROM 0157 FF3C 0158 FF3C ROMKEY 0159 FF3C 20 51 FF JSR OSROM 0160 FF3F 0161 FF3F ROMINS 0162 FF3F 20 51 FF JSR OSROM 0163 FF42 0164 FF42 ROMREM 0165 FF42 20 51 FF JSR OSROM 0166 FF45 0167 FF45 ROMCNP 0168 FF45 20 51 FF JSR OSROM 0169 FF48 0170 FF48 20 51 FF JSR OSROM 0171 FF4B 0172 FF4B 20 51 FF JSR OSROM 0173 FF4E 0174 FF4E 20 51 FF JSR OSROM 0175 FF51 0176 FF51 OSROM ;call routine in paged ROM 0177 FF51 ; This routine zaps the stack a great deal. 0178 FF51 ; 0179 FF51 ; current state of stack is: 0180 FF51 ; 2 hi-byte return address (ignored) 0181 FF51 ; [will be used for final PLP prior to return to caller] 0182 FF51 ; 1 lo-byte return address => which ROM vector to use 0183 FF51 ; (this is of the form 3*n+2, n=0,1,2...) 0184 FF51 ; [will be used for final PLA prior to return to caller] 0185 FF51 48 PHA ;make room for current ROMid 0186 FF52 0187 FF52 48 PHA ;make room for ... 0188 FF53 48 PHA ;... return link to OSROM2 0189 FF54 0190 FF54 48 PHA ;make room for ... 0191 FF55 48 PHA ;... interrupt return address ... 0192 FF56 08 PHP ;... to enter paged ROM with status as on entry 0193 FF57 0194 FF57 48 PHA ;save A 0195 FF58 8A TXA 0196 FF59 48 PHA ;save X 0197 FF5A 98 TYA 0198 FF5B 48 PHA ;save Y 0199 FF5C 0200 FF5C ; stack currently looks like: 0201 FF5C ; 11 future PLP stored after return from paged ROM 0202 FF5C ; 10 future PLA restoring A after using A to restore ROM status 0203 FF5C ; 9 will hold current ROMid 0204 FF5C ; 0205 FF5C ; 8 return link ... 0206 FF5C ; 7 ... to OSROM2 0207 FF5C ; 0208 FF5C ; 6 interrupt state ... 0209 FF5C ; 5 ... to enter ... 0210 FF5C ; 4 ... at paged ROM address 0211 FF5C ; 0212 FF5C ; 3 A on entry 0213 FF5C ; 2 X on entry 0214 FF5C ; 1 Y on entry 0215 FF5C BA TSX ;prepare to fudge stack 0216 FF5D ; fudge return from paged ROM to OSROM2 0217 FF5D A9 FF LDAIM /(OSROM2-&01 ) 0218 FF5F 9D 08 01 STAAX &0108 0219 FF62 A9 88 LDAIM OSROM2-&01 0220 FF64 9D 07 01 STAAX &0107 0221 FF67 ; fudge paged ROM entry address 0222 FF67 BC 0A 01 LDYAX &010A ;Y -> indirection vector 0223 FF6A B9 9D 0D LDAAY ROMVEC-&02+&00 ;routine address lo-byte 0224 FF6D 9D 05 01 STAAX &0105 0225 FF70 B9 9E 0D LDAAY ROMVEC-&02+&01 ;routine address hi-byte 0226 FF73 9D 06 01 STAAX &0106 0227 FF76 ; deal with swopping of ROMs 0228 FF76 A5 F4 LDA ROMID 0229 FF78 9D 09 01 STAAX &0109 ;save current ROMid 0230 FF7B B9 9F 0D LDAAY ROMVEC-&02+&02 ;routine paged ROMid 0231 FF7E 85 F4 STA ROMID 0232 FF80 8D 30 FE STA ROM 0233 FF83 ; restore registers 0234 FF83 68 PLA 0235 FF84 A8 TAY 0236 FF85 68 PLA 0237 FF86 AA TAX 0238 FF87 68 PLA 0239 FF88 40 RTI ;enter paged ROM at specified address 0240 FF89 OSROM2 ;routine will return here 0241 FF89 08 PHP 0242 FF8A 48 PHA 0243 FF8B 8A TXA 0244 FF8C 48 PHA 0245 FF8D ; stack looks like: Acorn macro assembler Page 143 MOS99 Operating system ROM entry points and hardware vectors 0246 FF8D ; 6 slot for final PLP 0247 FF8D ; 5 slot for final PLA 0248 FF8D ; 4 previous ROMid 0249 FF8D ; 3 processor status upon return from paged ROM 0250 FF8D ; 2 A 0251 FF8D ; 1 X 0252 FF8D BA TSX 0253 FF8E BD 02 01 LDAAX &0102 0254 FF91 9D 05 01 STAAX &0105 ;move A down stack 0255 FF94 BD 03 01 LDAAX &0103 0256 FF97 9D 06 01 STAAX &0106 ;move P down stack 0257 FF9A ; restore X 0258 FF9A 68 PLA 0259 FF9B AA TAX 0260 FF9C ; purge A and P from stack 0261 FF9C 68 PLA 0262 FF9D 68 PLA 0263 FF9E ; restore previous ROMid 0264 FF9E 68 PLA 0265 FF9F 85 F4 STA ROMID 0266 FFA1 8D 30 FE STA ROM 0267 FFA4 ; return to caller restoring P to that upon return from paged ROM 0268 FFA4 68 PLA 0269 FFA5 28 PLP 0270 FFA6 DEFEVT ;default EVENT routine 0271 FFA6 DEFUPT ;default user print routine (simulate printer busy) 0272 FFA6 DEFNET ;default net routine (simulate printer busy) 0273 FFA6 RTS 0274 FFA6 60 RTS 0275 FFA7 0276 FFA7 0277 FFA7 FXBPUT ;FX entry, C=1 0278 FFA7 8A TXA ;A = character 0279 FFA8 B0 2A BCS OSBPUT ;[ALWAYS jump] 0280 FFAA 0281 FFAA 0282 FFAA RFRED 0283 FFAA BC 00 FC LDYAX FRED 0284 FFAD 60 RTS 0285 FFAE 0286 FFAE RJIM 0287 FFAE BC 00 FD LDYAX JIM 0288 FFB1 60 RTS 0289 FFB2 0290 FFB2 RSHEIL 0291 FFB2 BC 00 FE LDYAX SHEIL 0292 FFB5 60 RTS 0293 FFB6 0294 FFB6 0295 FFB6 ; security copy of indirection data 0296 FFB6 36 = VLEN 0297 FFB7 40 = IPAGE2 0298 FFB8 D9 = /(IPAGE2 ) 0299 FFB9 ; 0300 FFB9 4C 0B DC JMP RPROM ;read byte from paged ROM 0301 FFBC 4C C0 C4 JMP VDU ;raw VDU WRCH (corrupts A, X and Y) 0302 FFBF 4C 94 E4 JMP EVENT ;signal event 0303 FFC2 4C 1E EA JMP GSINTS ;used by paged ROMs 0304 FFC5 4C 2F EA JMP GSREAD ;used by paged ROMs 0305 FFC8 4C C5 DE JMP RDCH ;used by tube 0306 FFCB 4C A4 E0 JMP WRCH ;used by tube 0307 FFCE 6C 1C 02 OSFIND JMI FNDVEC 0308 FFD1 0309 FFD1 6C 1A 02 OSBGPB JMI GPBVEC 0310 FFD4 6C 18 02 OSBPUT JMI BPTVEC 0311 FFD7 6C 16 02 OSBGET JMI BGTVEC 0312 FFDA 6C 14 02 OSARGS JMI ARGVEC 0313 FFDD 6C 12 02 OSFILE JMI FILVEC 0314 FFE0 6C 10 02 OSRDCH JMI RDCVEC 0315 FFE3 C9 0D OSASCI CMPIM MCR 0316 FFE5 D0 07 BNE OSWRCH 0317 FFE7 A9 0A OSNEWL LDAIM MLF 0318 FFE9 20 EE FF JSR OSWRCH 0319 FFEC A9 0D LDAIM MCR 0320 FFEE 6C 0E 02 OSWRCH JMI WRCVEC 0321 FFF1 6C 0C 02 OSWORD JMI WORVEC 0322 FFF4 6C 0A 02 OSBYTE JMI BYTVEC 0323 FFF7 6C 08 02 OSCLI JMI COMVEC 0324 FFFA 0325 FFFA ; hardware vectors 0326 FFFA 00 = NMI ;non-maskable interrupt 0327 FFFB 0D = /(NMI ) 0328 FFFC CD = MRESET ;hardware reset 0329 FFFD D9 = /(MRESET ) 0330 FFFE 1C = IRQ ;interrupt 0331 FFFF DC = /(IRQ ) 0332 0000 ENDROM ;end of ROM 0333 0000 0334 0000 [ ENDROM=0 0335 0000 | 0337 0000 ] 0338 0000 0339 0000 TTL BBC Microcomputer Machine Operating System (MOS) 0340 0000 0341 0000 OPT OPPON 0342 0000 0343 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 MOS1_20.asm.txt >MOS1_20-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 MOS1_20-slack.txt