err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 1 1 list x 2 ; This is the modified september atari 400/800 computer operating 3 ; system listing, modified to assemble on the microtec cross 4 ; assembler. 5 ; This version is the one which was burned into ROM. 6 ; There is a residual piece of code which is for lnbug. This 7 ; is at location $9000 which is not in ROM. 8 ; 9 ; This is the revision B EPROM version \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 2 10 .page 11 ; 12 ; 13 ; colleen operating system equate file 14 ; 15 ; NTSC/PAL assembly flag 16 ; 17 0000 PALFLG = 0 ;0 = NTSC 1 = PAL 18 ; 19 ; 20 ; module origin table 21 ; 22 e000 chrorg = $e000 ;character set 23 e400 vectbl = $e400 ;vector table 24 e480 vctabl = $e480 ;RAM vector initial value table 25 e4a6 cioorg = $e4a6 ;central I/O handler 26 e6d5 intorg = $e6d5 ;interrupt handler 27 e944 sioorg = $e944 ;serial I/O driver 28 edea dskorg = $edea ;disk handler 29 ee78 prnorg = $ee78 ;printer handler 30 ef41 casorg = $ef41 ;cassette handler 31 f0e3 monorg = $f0e3 ;monitor/power up module 32 f3e4 kbdorg = $f3e4 ;keyboard/display handler 33 ; 34 ; 35 ; 36 ; 37 ; vector table 38 ; 39 ;Handler entry points are called out in the following vector 40 ;table. These are the addresses minus one. 41 ; 42 ; 43 ;example for editor 44 ; 45 ; e400 open 46 ; 2 close 47 ; 4 get 48 ; 6 put 49 ; 8 status 50 ; a special 51 ; c jump to power on initialization routine 52 ; f not used 53 ; 54 ; 55 e400 editrv = $e400 ;editor 56 e410 screnv = $e410 ;television screen 57 e420 keybdv = $e420 ;keyboard 58 e430 printv = $e430 ;printer 59 e440 casetv = $e440 ;cassette 60 ; 61 ; jump vector table 62 ; 63 ;the following is a table of jump instructions \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 3 64 ;to various entry points in the operating system. 65 ; 66 e450 diskiv = $e450 ;disk initialization 67 e453 dskinv = $e453 ;disk interface 68 e456 ciov = $e456 ;central input output routine 69 e459 siov = $e459 ;serial input output routine 70 e45c setvbv = $e45c ;set system timers routine 71 e45f sysvbv = $e45f ;system vertical blank calculations 72 e462 xitvbv = $e462 ;exit vertical blank calculations 73 e465 sioinv = $e465 ;serial input output initialization 74 e468 sendev = $e468 ;send enable routine 75 e46b intinv = $e46b ;interrupt handler initialization 76 e46e cioinv = $e46e ;central input output initialization 77 e471 blkbdv = $e471 ;blackboard mode 78 e474 warmsv = $e474 ;warm start entry point 79 e477 coldsv = $e477 ;cold start entry point 80 e47a rblokv = $e47a ;cassette read block entry point vector 81 e47d csopiv = $e47d ;cassette open for input vector 82 ;vctabl = $e480 83 ; 84 ; 85 ; operating system equates 86 ; 87 ; command codes for IOCB 88 0003 open = 3 ;open for input/output 89 0005 getrec = 5 ;get record (text) 90 0007 getchr = 7 ;get character(s) 91 0009 putrec = 9 ;put record (text) 92 000b putchr = $b ;put character(s) 93 000c close = $c ;close device 94 000d statis = $d ;status request 95 000e specil = $e ;beginning of special entry commands 96 ; 97 ; special entry commands 98 0011 drawln = $11 ;draw line 99 0012 fillin = $12 ;draw line with right fill 100 0020 rename = $20 ;rename disk file 101 0021 delete = $21 ;delete disk file 102 0022 format = $22 ;format 103 0023 lockfl = $23 ;lock file to read only 104 0024 unlock = $24 ;unlock locked file 105 0025 point = $25 ;point sector 106 0026 note = $26 ;note sector 107 00ff iocfre = $ff ;IOCB "free" 108 ; 109 ; aux1 equates 110 ; () indicates which devices use bit 111 0001 append = $1 ;open for write append (D), or screen read ( 112 0002 direct = $2 ;open for directory access (D) 113 0004 opnin = $4 ;open for input (all devices) 114 0008 opnot = $8 ;open for output (all devices) 115 000c opnino = opnin+opnot ;open for input and output (all devices) 116 0010 mxdmod = $10 ;open for mixed mode (E,S) 117 0020 insclr = $20 ;open without clearing screen (E,S) \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 4 118 ; 119 ; device names 120 0045 scredt = 'E ;screen editor (R/W) 121 004b kbd = 'K ;keyboard (R only) 122 0053 disply = 'S ;screen display (R/W) 123 0050 printr = 'P ;printer (W only) 124 0043 casset = 'C ;cassette 125 004d modem = 'M ;modem 126 0044 disk = 'D ;disk (R/W) 127 ; 128 ; system EOL (carriage return) 129 009b CR = $9b 130 ; 131 ; 132 ; operating system status codes 133 ; 134 0001 succes = $01 ;successful operation 135 ; 136 0080 brkabt = $80 ;break key abort 137 0081 prvopn = $81 ;IOCB already open 138 0082 nondev = $82 ;non-existant device 139 0083 wronly = $83 ;IOCB opened for write only 140 0084 nvalid = $84 ;invalid command 141 0085 notopn = $85 ;device or file not open 142 0086 badioc = $86 ;invalid IOCB number 143 0087 rdonly = $87 ;IOCB opened for read only 144 0088 eoferr = $88 ;end of file 145 0089 trnrcd = $89 ;truncated record 146 008a timout = $8a ;peripheral device time out 147 008b dnack = $8b ;device does not acknowledge command 148 008c frmerr = $8c ;serial bus framing error 149 008d crsror = $8d ;cursor overrange 150 008e ovrrun = $8e ;serial bus data overrun 151 008f chkerr = $8f ;serial bus checksum error 152 ; 153 0090 derror = $90 ;peripheral device error (operation not comp 154 0091 badmod = $91 ;bad screen mode number 155 0092 fncnot = $92 ;function not implemented in handler 156 0093 scrmem = $93 ;insufficient memory for screen mode 157 ; 158 ; 159 ; 160 ; 161 ; 162 ; 163 ; page zero RAM assignments 164 ; 165 *=$0000 166 0000 linzbs: .res 2 ;linbug RAM (will be replaced by monitor RAM 167 ; 168 ; these locations are not cleared 169 0002 casini: .res 2 ;cassette init location 170 0004 ramlo: .res 2 ;RAM pointer for memory test 171 0006 tramsz: .res 1 ;temporary register for RAM size \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 5 172 0007 tstdat: .res 1 ;RAM test data register 173 ; 174 ; cleared on coldstart only 175 0008 warmst: .res 1 ;warm start flag 176 0009 boot?: .res 1 ;successful boot flag 177 000a dosvec: .res 2 ;disk software start vector 178 000c dosini: .res 2 ;disk software init address 179 000e appmhi: .res 2 ;applications memory hi limit 180 ; 181 ; cleared on cold or warm start 182 0010 intzbs =* ;interrupt handler 183 0010 pokmsk: .res 1 ;system mask for POKEY IRQ enable 184 0011 brkkey: .res 1 ;break key flag 185 0012 rtclok: .res 3 ;real time clock (in 16 msec units) 186 ; 187 0015 bufadr: .res 2 ;indirect buffer address register 188 ; 189 0017 iccomt: .res 1 ;command for vector 190 ; 191 0018 dskfms: .res 2 ;disk file manager pointer 192 001a dskutl: .res 2 ;disk utilities pointer 193 ; 194 001c ptimot: .res 1 ;printer time out register 195 001d pbpnt: .res 1 ;print buffer pointer 196 001e pbufsz: .res 1 ;print buffer size 197 001f ptemp: .res 1 ;temporary register 198 ; 199 0020 ziocb =* ;zero page I/O control block 200 0010 iocbsz = 16 ;number of bytes per IOCB 201 0080 maxioc = 8*iocbsz ;length of the IOCB area 202 0020 iocbas =* 203 0020 ichidz: .res 1 ;handler index number (ff = IOCB free) 204 0021 icdnoz: .res 1 ;device number (drive number) 205 0022 iccomz: .res 1 ;command code 206 0023 icstaz: .res 1 ;status of last IOCB action 207 0024 icbalz: .res 1 ;buffer address low byte 208 0025 icbahz: .res 1 209 0026 icptlz: .res 1 ;put byte routine address - 1 210 0027 icpthz: .res 1 211 0028 icbllz: .res 1 ;buffer length low byte 212 0029 icblhz: .res 1 213 002a icax1z: .res 1 ;auxiliary information first byte 214 002b icax2z: .res 1 215 002c icsprz: .res 4 ;two spare bytes (CIO local use) 216 002e icidno = icsprz+2 ;IOCB number x 16 217 002f ciochr = icsprz+3 ;character byte for current operation 218 ; 219 0030 status: .res 1 ;internal status storage 220 0031 chksum: .res 1 ;checksum (single byte sum with carry) 221 0032 bufrlo: .res 1 ;pointer to data buffer (lo byte) 222 0033 bufrhi: .res 1 ;pointer to data buffer (hi byte) 223 0034 bfenlo: .res 1 ;next byte past end of the data buffer (lo b 224 0035 bfenhi: .res 1 ;next byte past end of the data buffer (hi b 225 0036 cretry: .res 1 ;number of command frame retries \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 6 226 0037 dretry: .res 1 ;number of device retries 227 0038 bufrfl: .res 1 ;data buffer full flag 228 0039 recvdn: .res 1 ;receive done flag 229 003a xmtdon: .res 1 ;transmission done flag 230 003b chksnt: .res 1 ;checksum sent flag 231 003c nocksm: .res 1 ;no checksum follows data flag 232 ; 233 ; 234 003d bptr: .res 1 235 003e ftype: .res 1 236 003f feof: .res 1 237 0040 freq: .res 1 238 0041 soundr: .res 1 ;noisy I/O flag. (zero is quiet) 239 0042 critic: .res 1 ;defines critical section (critical if non-z 240 ; 241 0043 fmszpg: .res 7 ;disk file manager system zero page 242 ; 243 ; 244 004a ckey: .res 1 ;flag set when game start pressed 245 004b cassbt: .res 1 ;cassette boot flag 246 004c dstat: .res 1 ;display status 247 ; 248 004d atract: .res 1 ;atract flag 249 004e drkmsk: .res 1 ;dark atract mask 250 004f colrsh: .res 1 ;atract color shifter (eor'ed with playfield 251 ; 252 0002 ledge = 2 ;lmargn's value at cold start 253 0027 redge = 39 ;rmargn's value at cold start 254 0050 tmpchr: .res 1 255 0051 hold1: .res 1 256 0052 lmargn: .res 1 ;left margin (set to 1 at power on) 257 0053 rmargn: .res 1 ;right margin (set to 38 at power on) 258 0054 rowcrs: .res 1 ;cursor counters 259 0055 colcrs: .res 2 260 0057 dindex: .res 1 261 0058 savmsc: .res 2 262 005a oldrow: .res 1 263 005b oldcol: .res 2 264 005d oldchr: .res 1 ;data under cursor 265 005e oldadr: .res 2 266 0060 newrow: .res 1 ;point draw draw goes to 267 0061 newcol: .res 2 268 0063 logcol: .res 1 ;points at column in logical line 269 0064 adress: .res 2 270 0066 mlttmp: .res 2 271 0066 opntmp = mlttmp ;first byte is used in open as temp 272 0068 savadr: .res 2 273 006a ramtop: .res 1 ;RAM size defined by power on logic 274 006b bufcnt: .res 1 ;buffer count 275 006c bufstr: .res 2 ;editor getch pointer 276 006e bitmsk: .res 1 ;bit mask 277 006f shfamt: .res 1 278 0070 rowac: .res 2 279 0072 colac: .res 2 \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 7 280 0074 endpt: .res 2 281 0076 deltar: .res 1 282 0077 deltac: .res 2 283 0079 rowinc: .res 1 284 007a colinc: .res 1 285 007b swpflg: .res 1 ;non-0 if txt and regular RAM is swapped 286 007c holdch: .res 1 ;ch is moved here in kgetch before cntl & sh 287 007d insdat: .res 1 288 007e countr: .res 2 289 ; 290 ; 291 ; 292 ; 293 ; 80 - ff are reserved for user applications 294 ; 295 ; 296 ; 297 ; note : see floating point subroutine area for zero page cells 298 ; 299 ; 300 ; 301 ; 302 ; page 1 - stack 303 ; 304 ; 305 ; 306 ; 307 ; page two RAM assignments 308 ; 309 *=$200 310 0200 intabs =* ;interrupt RAM 311 0200 vdslst: .res 2 ;display list NMI vector 312 0202 vprced: .res 2 ;proceed line IRQ vector 313 0204 vinter: .res 2 ;interrupt line IRQ vector 314 0206 vbreak: .res 2 ;software break (00) instruction IRQ vector 315 0208 vkeybd: .res 2 ;POKEY keyboard IRQ vector 316 020a vserin: .res 2 ;POKEY serial input ready IRQ 317 020c vseror: .res 2 ;POKEY serial output ready IRQ 318 020e vseroc: .res 2 ;POKEY serial output complete IRQ 319 0210 vtimr1: .res 2 ;POKEY timer 1 IRQ 320 0212 vtimr2: .res 2 ;POKEY timer 2 IRQ 321 0214 vtimr4: .res 2 ;POKEY timer 4 IRQ 322 0216 vimirq: .res 2 ;immediate IRQ vector 323 0218 cdtmv1: .res 2 ;count down timer 1 324 021a cdtmv2: .res 2 ;count down timer2 325 021c cdtmv3: .res 2 ;count down timer 3 326 021e cdtmv4: .res 2 ;count down timer 4 327 0220 cdtmv5: .res 2 ;count down timer 5 328 0222 vvblki: .res 2 ;immediate vertical blank NMI vector 329 0224 vvblkd: .res 2 ;deferred vertical blank NMI vector 330 0226 cdtma1: .res 2 ;count down timer 1 jsr address 331 0228 cdtma2: .res 2 ;count down timer 2 jsr address 332 022a cdtmf3: .res 1 ;count down timer 3 flag 333 022b srtimr: .res 1 ;software repeat timer \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 8 334 022c cdtmf4: .res 1 ;count down timer 4 flag 335 022d intemp: .res 1 ;Ian's temp (renamed from T1 by popular dema 336 022e cdtmf5: .res 1 ;count down timer flag 5 337 022f sdmctl: .res 1 ;save dmactl register 338 0230 sdlstl: .res 1 ;save display list low byte 339 0231 sdlsth: .res 1 ;save display list hi byte 340 0232 sskctl: .res 1 ;skctl register RAM 341 0233 .res 1 ; 342 ; 343 0234 lpenh: .res 1 ;light pen horizontal value 344 0235 lpenv: .res 1 ;light pen vertical value 345 0236 brkky: .res 2 ;break key vector 346 ; 347 0238 .res 2 ;spare 348 ; 349 023a cdevic: .res 1 ;command frame buffer - device 350 023b ccomnd: .res 1 ;command 351 023c caux1: .res 1 ;command aux byte 1 352 023d caux2: .res 1 ;command aux byte 2 353 ; note: may not be the last word on a page 354 023e temp: .res 1 ;temporary RAM cell 355 ; note: may not be the last word on a page 356 023f errflg: .res 1 ;error flag - any device error except time o 357 ; 358 0240 dflags: .res 1 ;disk flags from sector one 359 0241 dbsect: .res 1 ;number of disk boot sectors 360 0242 bootad: .res 2 ;address where disk boot loader will be put 361 0244 coldst: .res 1 ;coldstart flag (1=in middle of coldstart) 362 ; 363 0245 .res 1 ;spare 364 ; 365 0246 dsktim: .res 1 ;disk time out register 366 ; 367 0247 linbuf: .res 40 ;char line buffer 368 ; 369 026f gprior: .res 1 ;global priority cell 370 ; 371 0270 paddl0: .res 1 ;potentiometer 0 RAM cell 372 0271 paddl1: .res 1 373 0272 paddl2: .res 1 374 0273 paddl3: .res 1 375 0274 paddl4: .res 1 376 0275 paddl5: .res 1 377 0276 paddl6: .res 1 378 0277 paddl7: .res 1 379 0278 stick0: .res 1 ;joystick 0 RAM cell 380 0279 stick1: .res 1 381 027a stick2: .res 1 382 027b stick3: .res 1 383 027c ptrig0: .res 1 ;paddle trigger 0 384 027d ptrig1: .res 1 385 027e ptrig2: .res 1 386 027f ptrig3: .res 1 387 0280 ptrig4: .res 1 \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 9 388 0281 ptrig5: .res 1 389 0282 ptrig6: .res 1 390 0283 ptrig7: .res 1 391 0284 strig0: .res 1 ;joystick trigger 0 392 0285 strig1: .res 1 393 0286 strig2: .res 1 394 0287 strig3: .res 1 395 ; 396 0288 cstat: .res 1 397 0289 wmode: .res 1 398 028a blim: .res 1 399 028b imask: .res 1 400 028c jveck: .res 2 401 ; 402 028e .res 2 ;spare 403 ; 404 ; 405 ; 406 ; 407 0290 txtrow: .res 1 ;text rowcrs 408 0291 txtcol: .res 2 ;text colcrs 409 0293 tindex: .res 1 ;text index 410 0294 txtmsc: .res 2 ;fools convrt into new msc 411 0296 txtold: .res 6 ;oldrow & oldcol for text (and then some) 412 029c tmpx1: .res 1 413 029d hold3: .res 1 414 029e subtmp: .res 1 415 029f hold2: .res 1 416 02a0 dmask: .res 1 417 02a1 tmplbt: .res 1 418 02a2 escflg: .res 1 ;escape flag 419 02a3 tabmap: .res 15 420 02b2 logmap: .res 4 ;logical line start bit map 421 02b6 invflg: .res 1 ;inverse video flag (toggled by atari key) 422 02b7 filflg: .res 1 ;right fill flag for draw 423 02b8 tmprow: .res 1 424 02b9 tmpcol: .res 2 425 02bb scrflg: .res 1 ;set if scroll occurs 426 02bc hold4: .res 1 ;temp cell used in draw only 427 02bd hold5: .res 1 ;ditto 428 02be shflok: .res 1 429 02bf botscr: .res 1 ;bottom of screen : 24 norm 4 split 430 ; 431 ; 432 02c0 pcolr0: .res 1 ;P0 color 433 02c1 pcolr1: .res 1 ;P1 color 434 02c2 pcolr2: .res 1 ;P2 color 435 02c3 pcolr3: .res 1 ;P3 color 436 02c4 color0: .res 1 ;color 0 437 02c5 color1: .res 1 438 02c6 color2: .res 1 439 02c7 color3: .res 1 440 02c8 color4: .res 1 441 ; \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 10 442 ; 443 02c9 .res 23 ;spare 444 ; 445 ; 446 ; 447 02e0 glbabs =* ;global variables 448 ; 449 02e0 .res 4 ;spare 450 ; 451 02e4 ramsiz: .res 1 ;RAM size (hi byte only) 452 02e5 memtop: .res 2 ;top of available user memory 453 02e7 memlo: .res 2 ;bottom of available user memory 454 02e9 .res 1 ;spare 455 02ea dvstat: .res 4 ;status buffer 456 02ee cbaudl: .res 1 ;cassette baud rate low byte 457 02ef cbaudh: .res 1 458 ; 459 02f0 crsinh: .res 1 ;cursor inhibit (00 = cursor on) 460 02f1 keydel: .res 1 ;key delay 461 02f2 ch1: .res 1 462 ; 463 02f3 chact: .res 1 ;chactl register RAM 464 02f4 chbas: .res 1 ;chbas register RAM 465 ; 466 02f5 .res 5 ;spare bytes 467 ; 468 02fa char: .res 1 469 02fb atachr: .res 1 ;atascii character 470 02fc ch: .res 1 ;global variable for keyboard 471 02fd fildat: .res 1 ;right fill data (draw) 472 02fe dspflg: .res 1 ;display flag : display cntls if non-zero 473 02ff ssflag: .res 1 ;start/stop flag for paging (cntl 1). cleare 474 ; 475 ; 476 ; 477 ; 478 ; 479 ; 480 ; 481 ; page three RAM assignments 482 ; 483 0300 dcb =* ;device control block 484 0300 ddevic: .res 1 ;peripheral unit 1 bus i.d. number 485 0301 dunit: .res 1 ;unit number 486 0302 dcomnd: .res 1 ;bus command 487 0303 dstats: .res 1 ;command type/status return 488 0304 dbuflo: .res 1 ;data buffer pointer low byte 489 0305 dbufhi: .res 1 490 0306 dtimlo: .res 1 ;device time out in 1 second units 491 0307 dunuse: .res 1 ;unused byte 492 0308 dbytlo: .res 1 ;number of bytes to be transferred low byte 493 0309 dbythi: .res 1 494 030a daux1: .res 1 ;command auxiliary byte 1 495 030b daux2: .res 1 \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 11 496 ; 497 030c timer1: .res 2 ;initial timer value 498 030e addcor: .res 1 ;addition correction 499 030f casflg: .res 1 ;cassette mode when set 500 0310 timer2: .res 2 ;final timer value. these two timer values 501 ; are used to compute interval for baud rate 502 0312 temp1: .res 2 ;temporary storage register 503 0314 temp2: .res 1 ;temporary storage register 504 0315 temp3: .res 1 ;temporary storage register 505 0316 savio: .res 1 ;save serial in data port 506 0317 timflg: .res 1 ;time out flag for baud rate correction 507 0318 stackp: .res 1 ;SIO stack pointer save cell 508 0319 tstat: .res 1 ;temporary status holder 509 ; 510 ; 511 ; 512 031a hatabs: .res 38 ;handler address table 513 0021 maxdev = *-hatabs-5 ;maximum handler address index 514 ; 515 ; note : the entire IOCB definitions have been modified 516 ; 517 iocb: .org * ;I/O control blocks 518 0340 ichid: .res 1 ;handler index number (ff = IOCB free) 519 0341 icdno: .res 1 ;device number (drive number) 520 0342 iccom: .res 1 ;command code 521 0343 icsta: .res 1 ;status of last IOCB action 522 0344 icbal: .res 1 ;buffer address low byte 523 0345 icbah: .res 1 524 0346 icptl: .res 1 ;put byte routine address - 1 525 0347 icpth: .res 1 526 0348 icbll: .res 1 ;buffer length low byte 527 0349 icblh: .res 1 528 034a icax1: .res 1 ;auxiliary information first byte 529 034b icax2: .res 1 530 034c icspr: .res 4 ;four spare bytes 531 0350 .res maxioc-iocbsz 532 ; 533 03c0 prnbuf: .res 40 ;printer buffer 534 ; 535 03e8 .res 21 ;spare bytes 536 ; 537 ; 538 ; 539 ; 540 ; 541 ; 542 ; 543 ; page four RAM assignments 544 ; 545 03fd casbuf: .res 131 ;cassette buffer 546 ; 547 ; user area starts here and goes to end of page five 548 0480 usarea: .res 128 ;spare 549 ; \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 12 550 ; 551 ; 552 ; 553 ; 554 ; 555 ; 556 ; page five RAM assignments 557 ; 558 ; page five is reserved as a user work space 559 ; 560 ; note: see floating point subroutine area for page five cells 561 ; 562 ; 563 ; page six RAM assignments 564 ; 565 ; page six is reserved as a user's user work space 566 ; 567 ; 568 ; 569 ; 570 ; floating point subroutines 571 ; 572 0006 fprec = 6 ;floating pt precision (# of bytes) 573 ; if carry used then carry clear => no error, carr 574 d800 afp = $d800 ;ascii->floating point (fp) 575 ; inbuff+cix -> fr0, cix, carry 576 d8e6 fasc = $d8e6 ;fp -> ascii fr0-> lbuff (inbuff) 577 d9aa ifp = $d9aa ;integer -> fp 578 ; 0-$ffff (LSB,MSB) in fr0,fr0+1->fr0 579 d9d2 fpi = $d9d2 ;fp -> integer fr0 -> fr0,fr0+1, carry 580 da60 fsub = $da60 ;fr0 <- fr0 - fr1 ,carry 581 da66 fadd = $da66 ;fr0 <- fr0 + fr1 ,carry 582 dadb fmul = $dadb ;fr0 <- fr0 * fr1 ,carry 583 db28 fdiv = $db28 ;fr0 <- fr0 / fr1 ,carry 584 dd89 fld0r = $dd89 ;floating load reg0 fr0 <- (X,Y) 585 dd8d fld0p = $dd8d ; " " " fr0 <- (flptr) 586 dd98 fld1r = $dd98 ; " " reg1 fr1 <- (X,Y) 587 dd9c fld1p = $dd9c ; " " " fr1 <- (flptr) 588 dda7 fstor = $dda7 ;floating store reg0 (X,Y) <- fr0 589 ddab fstop = $ddab ; " " " (flptr) <- fr0 590 ddb6 fmove = $ddb6 ;fr1 <- fr0 591 dd40 plyevl = $dd40 ;fr0 <- p(z) = sum(i=n to 0) (a(i)*z**i) car 592 ; input: (X,Y) = a(n),a(n-1)...a(0) -> plyarg 593 ; acc = # of coefficients = degree+1 594 ; fr0 = z 595 ddc0 exp = $ddc0 ;fr0 <- e**fr0 = exp10(fr0 * log10(e)) carry 596 ddcc exp10 = $ddcc ;fr0 <- 10**fr0 carry 597 decd log = $decd ;fr0 <- ln(fr0) = log10(fr0)/log10(e) carry 598 ded1 log10 = $ded1 ;fr0 <- log10 (fr0) carry 599 ; the following are in basic cartridge: 600 bd81 sin = $bd81 ;fr0 <- sin(fr0) degflg=0 =>rads, 6=>deg. ca 601 bd73 cos = $bd73 ;fr0 <- cos(fr0) carry 602 be43 atan = $be43 ;fr0 <- atan(fr0) carry 603 beb1 sqr = $beb1 ;fr0 <- squareroot(fr0) carry \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 13 604 ; floating point routines zero page (needed only if f.p. routines are ca 605 *=$d4 606 00d4 fr0: .res fprec ;fp reg0 607 00da fre: .res fprec 608 00e0 fr1: .res fprec ;fp reg1 609 00e6 fr2: .res fprec 610 00ec frx: .res 1 ;fp spare 611 00ed eexp: .res 1 ;value of e 612 00ee nsign: .res 1 ;sign of # 613 00ef esign: .res 1 ;sign of exponent 614 00f0 fchrflg:.res 1 ;1st char flag 615 00f1 digrt: .res 1 ;# of digits right of decimal 616 00f2 cix: .res 1 ;current input index 617 00f3 inbuff: .res 2 ;points to user's line input buffer 618 00f5 ztemp1: .res 2 619 00f7 ztemp4: .res 2 620 00f9 ztemp3: .res 2 621 00fb degflg: 622 00fb radflg: .res 1 ;0=radians, 6=degrees 623 0000 radon = 0 ;indicates radians 624 0006 degon = 6 ;indicates degrees 625 00fc flptr: .res 2 ;points to user's floating pt number 626 00fe fptr2: .res 2 627 ; floating pt routines' non-zero page RAM 628 ; (needed only if f.p. routines called) 629 *=$57e 630 057e lbpr1: .res 1 ;lbuff prefix 1 631 057f lbpr2: .res 1 ;lbuff prefix 2 632 0580 lbuff: .res 128 ;line buffer 633 05e0 plyarg = lbuff+$60 ;polynomial arguments 634 05e6 fpscr = plyarg+fprec 635 05ec fpscr1 = fpscr+fprec 636 05e6 fscr = fpscr 637 05ec fscr1 = fpscr1 638 05ff lbfend = *-1 ;end of lbuff 639 ; 640 ; 641 ; 642 ; 643 ; 644 ; 645 ; 646 ; 647 ; 648 ; colleen mnemonics 649 ; 650 d200 pokey = $d200 ;vblank action: description: 651 d200 pot0 = pokey+0 ;pot0-->paddl0 0-227 in RAM cell 652 d201 pot1 = pokey+1 ;pot1-->paddl1 0-227 in RAM cell 653 d202 pot2 = pokey+2 ;pot2-->paddl2 0-227 in RAM cell 654 d203 pot3 = pokey+3 ;pot3-->paddl3 0-227 in RAM cell 655 d204 pot4 = pokey+4 ;pot4-->paddl4 0-227 in RAM cell 656 d205 pot5 = pokey+5 ;pot5-->paddl5 0-227 in RAM cell 657 d206 pot6 = pokey+6 ;pot6-->paddl6 0-227 in RAM cell \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 14 658 d207 pot7 = pokey+7 ;pot7-->paddl7 0-227 in RAM cell 659 d208 allpot = pokey+8 ;??? 660 d209 kbcode = pokey+9 661 d20a random = pokey+10 662 d20b potgo = pokey+11 ;strobed 663 d20d serin = pokey+13 664 d20e irqst = pokey+14 665 d20f skstat = pokey+15 666 d200 audf1 = pokey+0 667 d201 audc1 = pokey+1 668 d202 audf2 = pokey+2 669 d203 audc2 = pokey+3 670 d204 audf3 = pokey+4 671 d205 audc3 = pokey+5 672 d206 audf4 = pokey+6 673 d207 audc4 = pokey+7 674 d208 audctl = pokey+8 ;none audctl<--[SIO] 675 d209 stimer = pokey+9 676 d20a skres = pokey+10 ;none skres<--[SIO] 677 d20d serout = pokey+13 ;none serout<--[SIO] 678 d20e irqen = pokey+14 ;pokmsk-->irqen (affected by open S: or E:) 679 d20f skctl = pokey+15 ;sskctl-->skctl sskctl<--[SIO] 680 ; 681 d000 ctia = $d000 ;vblank action: description: 682 d000 hposp0 = ctia+0 683 d001 hposp1 = ctia+1 684 d002 hposp2 = ctia+2 685 d003 hposp3 = ctia+3 686 d004 hposm0 = ctia+4 687 d005 hposm1 = ctia+5 688 d006 hposm2 = ctia+6 689 d007 hposm3 = ctia+7 690 d008 sizep0 = ctia+8 691 d009 sizep1 = ctia+9 692 d00a sizep2 = ctia+10 693 d00b sizep3 = ctia+11 694 d00c sizem = ctia+12 695 d00d grafp0 = ctia+13 696 d00e grafp1 = ctia+14 697 d00f grafp2 = ctia+15 698 d010 grafp3 = ctia+16 699 d011 grafm = ctia+17 700 d012 colpm0 = ctia+18 ;pcolr0-->colpm0 with attract mode 701 d013 colpm1 = ctia+19 ;pcolr1-->colpm1 with attract mode 702 d014 colpm2 = ctia+20 ;pcolr2-->colpm2 with attract mdqe 703 d015 colpm3 = ctia+21 ;pcolr3-->colpm3 with attract mode 704 d016 colpf0 = ctia+22 ;color0-->colpf0 with attract mode 705 d017 colpf1 = ctia+23 ;color1-->colpf1 with attract mode 706 d018 colpf2 = ctia+24 ;color2-->colpf2 with attract mode 707 d019 colpf3 = ctia+25 ;color3-->colpf3 with attract mode 708 d01a colbk = ctia+26 ;color4-->colbk with attract mode 709 d01b prior = ctia+27 ;(on open S: or E:) gprior-->prior 710 d01c vdelay = ctia+28 711 d01d gractl = ctia+29 \newpage err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 15 712 d01e hitclr = ctia+30 713 d01f consol = ctia+31 ;$08-->consol turn off speaker 714 d000 m0pf = ctia+0 715 d001 m1pf = ctia+1 716 d002 m2pf = ctia+2 717 d003 m3pf = ctia+3 718 d004 p0pf = ctia+4 719 d005 p1pf = ctia+5 720 d006 p2pf = ctia+6 721 d007 p3pf = ctia+7 722 d008 m0pl = ctia+8 723 d009 m1pl = ctia+9 724 d00a m2pl = ctia+10 725 d00b m3pl = ctia+11 726 d00c p0pl = ctia+12 727 d00d p1pl = ctia+13 728 d00e p2pl = ctia+14 729 d00f p3pl = ctia+15 730 d010 trig0 = ctia+16 ;trig0-->strig0 731 d011 trig1 = ctia+17 ;trig1-->strig1 732 d012 trig2 = ctia+18 ;trig2-->strig2 733 d013 trig3 = ctia+19 ;trig3-->strig3 734 ; 735 d400 antic = $d400 ;vblank action description 736 d400 dmactl = antic+0 ;dmactl<--sdmctl on open S: or E: 737 d401 chactl = antic+1 ;chactl<--chact on open S: or E: 738 d402 dlistl = antic+2 ;dlistl<--sdlstl on open S: or E: 739 d403 dlisth = antic+3 ;dlisth<--sdlsth on open S: or E: 740 d404 hscrol = antic+4 741 d405 vscrol = antic+5 742 d407 pmbase = antic+7 743 d409 chbase = antic+9 ;chbase<--chbas on open S: or E: 744 d40a wsync = antic+10 745 d40b vcount = antic+11 746 d40c penh = antic+12 747 d40d penv = antic+13 748 d40e nmien = antic+14 ;nmien<--40 power on and [setvbv] 749 d40f nmires = antic+15 ;strobed 750 d40f nmist = antic+15 751 d300 pia = $d300 ;vblank action description 752 d300 porta = pia+0 ;porta-->stick0,1 x-y controllers 753 d301 portb = pia+1 ;portb-->stick2,3 x-y controllers 754 d302 pactl = pia+2 ;none pactl<--3c [init] 755 d303 pbctl = pia+3 ;none pbctl<--3c [init] 756 ; 757 ; 758 ; 759 ; .page \newfile err line addr b1 b2 b3 b4 6500 assembler ver 1.0mr page 16 760 .page 761 list s 762 .title 'central input/output (CIO) 2-7-79' 763 ; updated by Al Miller 3-9-79 764 0030 asczer = '0 ;ascii zero 765 003a colon = $3a ;ascii colon 766 009b EOL = $9b ;end of record \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 17 767 .page 768 ; 769 ; CIO jump vector for users 770 *=ciov 771 e456 4c c4 e4 jmp cio ;go to CIO 772 ; 773 ; CIO init jump vector for power up 774 *=cioinv 775 e46e 4c a6 e4 jmp cioint ;go to init 776 ; 777 ; 778 ; error routine address equate 779 ; errtnh =errtn/256 "moved to line 788" 780 ; errtnl =-errtnh*256+errtn "moved to line 789" 781 ; 782 ; 783 *=cioorg 784 ; 785 ; CIO initialization (called by monitor at power up) 786 e4a6 a2 00 cioint: ldx #0 787 e4a8 a9 ff cioi1: lda #iocfre ;set all IOCB's to free 788 e4aa 9d 40 03 sta ichid,x ;by setting handler id's=$ff 789 e4ad a9 c0 lda #errtnl 790 e4af 9d 46 03 sta icptl,x ;point put to error routine 791 e4b2 a9 e4 lda #errtnh 792 e4b4 9d 47 03 sta icpth,x 793 e4b7 8a txa 794 e4b8 18 clc 795 e4b9 69 10 adc #iocbsz ;bump index by size 796 e4bb aa tax 797 e4bc c9 80 cmp #maxioc ;done? 798 e4be 90 e8 bcc cioi1 ;no 799 e4c0 60 rts ;yes, return 800 ; 801 ; error routine for illegal put 802 e4c0 errtn =*-1 803 00e4 errtnh =errtn/256 804 00c0 errtnl =(-errtnh)*256+errtn 805 e4c1 a0 85 ldy #notopn ;IOCB not open 806 e4c3 60 rts \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 18 807 .page 808 ; 809 ; CIO local RAM (uses spare bytes in zero page IOCB) 810 002c entvec = icsprz 811 ; 812 ; CIO main routine 813 ; 814 ; CIO interfaces between user and input/output de 815 e4c4 85 2f cio: sta ciochr ;save possible output character 816 e4c6 86 2e stx icidno ;save IOCB number * n 817 ; 818 ; check for legal IOCB 819 e4c8 8a txa 820 e4c9 29 0f and #$f ;is IOCB multiple of 16? 821 e4cb d0 04 bne cierr1 ;no, error 822 e4cd e0 80 cpx #maxioc ;is index too large? 823 e4cf 90 05 bcc ioc1 ;no 824 ; 825 ; invalid IOCB number -- return error 826 e4d1 a0 86 cierr1: ldy #badioc ;error code 827 e4d3 4c 1b e6 jmp cirtn1 ;return 828 ; 829 ; move user IOCB to zero page 830 e4d6 a0 00 ioc1: ldy #0 831 e4d8 bd 40 03 ioc1a: lda iocb,x ;user IOCB 832 e4db 99 20 00 sta iocbas,y ;to zero page 833 e4de e8 inx 834 e4df c8 iny 835 e4e0 c0 0c cpy #12 ;12 bytes 836 e4e2 90 f4 bcc ioc1a 837 ; 838 ; compute CIO internal vector for command 839 e4e4 a0 84 ldy #nvalid ;assume invalid code 840 e4e6 a5 22 lda iccomz ;command code to index 841 e4e8 c9 03 cmp #open ;is command legal? 842 e4ea 90 25 bcc cierr4 ;no 843 e4ec a8 tay 844 ; 845 ; move command to zero base for index 846 e4ed c0 0e cpy #specil ;is command special? 847 e4ef 90 02 bcc ioc2 ;no 848 e4f1 a0 0e ldy #specil ;yes, set special offset index 849 e4f3 84 17 ioc2: sty iccomt ;save command for vector 850 e4f5 b9 c6 e6 lda comtab-3,y ;get vector offset from table 851 e4f8 f0 0f beq ciopen ;go if open command 852 e4fa c9 02 cmp #2 ;is it close? 853 e4fc f0 35 beq ciclos ;yes 854 e4fe c9 08 cmp #8 ;is it status or special? 855 e500 b0 4c bcs cistsp ;yes 856 e502 c9 04 cmp #4 ;is it read? 857 e504 f0 63 beq ciread ;yes 858 e506 4c c9 e5 jmp ciwrit ;else, must be write \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 19 859 .page 860 ; 861 ; open command 862 ; 863 ; find device handler in handler address table 864 e509 a5 20 ciopen: lda ichidz ;get handler id 865 e50b c9 ff cmp #iocfre ;is this IOCB closed? 866 e50d f0 05 beq ioc6 ;yes 867 ; 868 ; error -- IOCB already open 869 e50f a0 81 cierr3: ldy #prvopn ;error code 870 e511 4c 1b e6 cierr4: jmp cirtn1 ;return 871 ; 872 ; go find device 873 e514 20 9e e6 ioc6: jsr devsrc ;call device search 874 e517 b0 f8 bcs cierr4 ;go if device not found 875 ; 876 ; device found, initialize IOCB for open 877 ; 878 ; compute handler entry point 879 e519 20 3d e6 ioc7: jsr coment 880 e51c b0 f3 bcs cierr4 ;go if error in compute 881 ; 882 ; go to handler for initialization 883 e51e 20 89 e6 jsr gohand ;use indirect jump 884 ; 885 ; store put byte address-1 into IOCB 886 e521 a9 0b lda #putchr ;simulate put character 887 e523 85 17 sta iccomt 888 e525 20 3d e6 jsr coment ;compute entry point 889 e528 a5 2c lda icsprz ;move computed value 890 e52a 85 26 sta icptlz ;to put byte address 891 e52c a5 2d lda icsprz+1 892 e52e 85 27 sta icpthz 893 e530 4c 1d e6 jmp cirtn2 ;return to user \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 20 894 .page 895 ; 896 ; 897 ; close command 898 e533 a0 01 ciclos: ldy #succes ;assume good close 899 e535 84 23 sty icstaz 900 e537 20 3d e6 jsr coment ;compute handler entry point 901 e53a b0 03 bcs ciclo2 ;go if error in compute 902 e53c 20 89 e6 jsr gohand ;go to handler to close device 903 e53f a9 ff ciclo2: lda #iocfre ;get IOCB "free" value 904 e541 85 20 sta ichidz ;set handler id 905 e543 a9 e4 lda #errtnh 906 e545 85 27 sta icpthz ;set put byte to point to error 907 e547 a9 c0 lda #errtnl 908 e549 85 26 sta icptlz 909 e54b 4c 1d e6 jmp cirtn2 ;return 910 ; 911 ; 912 ; status and special requests 913 ; do implied open if necessary and go to device 914 e54e a5 20 cistsp: lda ichidz ;is there a handler id? 915 e550 c9 ff cmp #iocfre 916 e552 d0 05 bne cist1 ;yes 917 ; 918 ; IOCB is free, do implied open 919 e554 20 9e e6 jsr devsrc ;find device in table 920 e557 b0 b8 bcs cierr4 ;go if error in compute 921 ; 922 ; compute and go to entry point in handler 923 e559 20 3d e6 cist1: jsr coment ;computer handler entry vector 924 e55c 20 89 e6 jsr gohand ;go to handler 925 ; 926 ; restore handler index (do implied close) 927 e55f a6 2e ldx icidno ;IOCB index 928 e561 bd 40 03 lda ichid,x ;get original handler id 929 e564 85 20 sta ichidz ;restore zero page 930 e566 4c 1d e6 jmp cirtn2 ;return \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 21 931 .page 932 ; 933 ; read -- do get commands 934 e569 a5 22 ciread: lda iccomz ;get command byte 935 e56b 25 2a and icax1z ;is this read legal? 936 e56d d0 05 bne rci1a ;yes 937 ; 938 ; illegal read -- IOCB opened for write only 939 e56f a0 83 ldy #wronly ;error code 940 e571 4c 1b e6 rci1b: jmp cirtn1 ;return 941 ; 942 ; compute and check entry point 943 e574 20 3d e6 rci1a: jsr coment ;compute entry point 944 e577 b0 f8 bcs rci1b ;go if error in compute 945 ; 946 ; get record or characters 947 e579 a5 28 lda icbllz 948 e57b 05 29 ora icbllz+1 ;is buffer length zero? 949 e57d d0 08 bne rci3 ;no 950 e57f 20 89 e6 jsr gohand 951 e582 85 2f sta ciochr 952 e584 4c 1d e6 jmp cirtn2 953 ; 954 ; loop to fill buffer or end record 955 e587 20 89 e6 rci3: jsr gohand ;go to handler to get byte 956 e58a 85 2f sta ciochr ;save byte 957 e58c 30 35 bmi rci4 ;end transfer if error 958 e58e a0 00 ldy #0 959 e590 91 24 sta (icbalz),y ;put byte in user buffer 960 e592 20 70 e6 jsr incbfp ;increment buffer pointer 961 e595 a5 22 lda iccomz ;get command code 962 e597 29 02 and #2 ;is it get record? 963 e599 d0 0c bne rci1 ;no 964 ; 965 ; check for EOL on text records 966 e59b a5 2f lda ciochr ;get byte 967 e59d c9 9b cmp #EOL ;is it an EOL? 968 e59f d0 06 bne rci1 ;no 969 e5a1 20 63 e6 jsr decbfl ;yes, decrement buffer length 970 e5a4 4c c3 e5 jmp rci4 ;end transfer 971 ; 972 ; check buffer full 973 e5a7 20 63 e6 rci1: jsr decbfl ;decrement buffer length 974 e5aa d0 db bne rci3 ;continue if non zero \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 22 975 .page 976 ; 977 ; buffer full, record not ended 978 ; discard bytes until end of record 979 e5ac a5 22 rci2: lda iccomz ;get command byte 980 e5ae 29 02 and #2 ;is it get character? 981 e5b0 d0 11 bne rci4 ;yes, end transfer 982 ; 983 ; loop to wait for EOL 984 e5b2 20 89 e6 rci6: jsr gohand ;get byte from handler 985 e5b5 85 2f sta ciochr ;save character 986 e5b7 30 0a bmi rci4 ;go if error 987 ; 988 ; text record, wait for EOL 989 e5b9 a5 2f lda ciochr ;get got byte 990 e5bb c9 9b cmp #EOL ;is it EOL? 991 e5bd d0 f3 bne rci6 ;no, continue 992 ; 993 ; end of record, buffer full -- send truncated record message 994 e5bf a9 89 rci11: lda #trnrcd ;error code 995 e5c1 85 23 sta icstaz ;store in IOCB 996 ; 997 ; transfer done 998 e5c3 20 77 e6 rci4: jsr subbfl ;set final buffer length 999 e5c6 4c 1d e6 jmp cirtn2 ;return \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 23 1000 .page 1001 ; 1002 ; write -- do put commands 1003 e5c9 a5 22 ciwrit: lda iccomz ;get command byte 1004 e5cb 25 2a and icax1z ;is this write legal? 1005 e5cd d0 05 bne wci1a ;yes 1006 ; 1007 ; illegal write -- device opened for read only 1008 e5cf a0 87 ldy #rdonly ;error code 1009 e5d1 4c 1b e6 wci1b: jmp cirtn1 ;return 1010 ; 1011 ; compute and check entry point 1012 e5d4 20 3d e6 wci1a: jsr coment ;compute handler entry point 1013 e5d7 b0 f8 bcs wci1b ;go if error in compute 1014 ; 1015 ; put record or characters 1016 e5d9 a5 28 lda icbllz 1017 e5db 05 29 ora icbllz+1 ;is buffer length zero? 1018 e5dd d0 06 bne wci3 ;no 1019 e5df a5 2f lda ciochr ;get character 1020 e5e1 e6 28 inc icbllz ;set buffer length=1 1021 e5e3 d0 06 bne wci4 ;then just transfer one byte 1022 ; 1023 ; loop to transfer bytes from buffer to handler 1024 e5e5 a0 00 wci3: ldy #0 1025 e5e7 b1 24 lda (icbalz),y ;get byte from buffer 1026 e5e9 85 2f sta ciochr ;save 1027 e5eb 20 89 e6 wci4: jsr gohand ;go put byte 1028 e5ee 30 25 bmi wci5 ;end if error 1029 e5f0 20 70 e6 jsr incbfp ;increment buffer pointer 1030 ; 1031 ; check for text record 1032 e5f3 a5 22 lda iccomz ;get command byte 1033 e5f5 29 02 and #2 ;is it put record? 1034 e5f7 d0 0c bne wci1 ;no 1035 ; 1036 ; text record -- check for EOL transfer 1037 e5f9 a5 2f lda ciochr ;get last character 1038 e5fb c9 9b cmp #EOL ;is it an EOL? 1039 e5fd d0 06 bne wci1 ;no 1040 e5ff 20 63 e6 jsr decbfl ;decrement buffer length 1041 e602 4c 15 e6 jmp wci5 ;end transfer 1042 ; 1043 ; check for buffer empty 1044 e605 20 63 e6 wci1: jsr decbfl ;decrement buffer length 1045 e608 d0 db bne wci3 ;continue if non zero \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 24 1046 .page 1047 ; 1048 ; buffer empty, record not filled 1049 ; check type of transfer 1050 e60a a5 22 wci2: lda iccomz ;get command code 1051 e60c 29 02 and #2 ;is it put character? 1052 e60e d0 05 bne wci5 ;yes, end transfer 1053 ; 1054 ; put record (text), buffer empty, send EOL 1055 e610 a9 9b lda #EOL 1056 e612 20 89 e6 jsr gohand ;go to handler 1057 ; 1058 ; end put transfer 1059 e615 20 77 e6 wci5: jsr subbfl ;set actual put buffer length 1060 e618 4c 1d e6 jmp cirtn2 ;return \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 25 1061 .page 1062 ; 1063 ; CIO returns 1064 ; returns with Y=status 1065 e61b 84 23 cirtn1: sty icstaz ;save status 1066 ; 1067 ; returns with status stored in icstaz 1068 ; move IOCB in zero page back to user area 1069 e61d a4 2e cirtn2: ldy icidno ;get IOCB index 1070 e61f b9 44 03 lda icbal,y 1071 e622 85 24 sta icbalz ;restore user buffer pointer 1072 e624 b9 45 03 lda icbah,y 1073 e627 85 25 sta icbahz 1074 e629 a2 00 ldx #0 ;loop count and index 1075 e62b b5 20 cirt3: lda iocbas,x ;zero page 1076 e62d 99 40 03 sta iocb,y ;to user area 1077 e630 e8 inx 1078 e631 c8 iny 1079 e632 e0 0c cpx #12 ;12 bytes 1080 e634 90 f5 bcc cirt3 1081 ; 1082 ; restore A,X, & Y 1083 e636 a5 2f lda ciochr ;get last character 1084 e638 a6 2e ldx icidno ;IOCB index 1085 e63a a4 23 ldy icstaz ;get status and set flags 1086 e63c 60 rts ;return to user \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 26 1087 .page 1088 ; 1089 ; 1090 ; CIO subroutines 1091 ; 1092 ; coment -- check and compute handler entry point 1093 e63d a4 20 coment: ldy ichidz ;get handler index 1094 e63f c0 22 cpy #maxdev+1 ;is it a legal index? 1095 e641 90 04 bcc com1 ;yes 1096 ; 1097 ; illegal handler index means device not open for operation 1098 e643 a0 85 ldy #notopn ;error code 1099 e645 b0 1b bcs com2 ;return 1100 ; 1101 ; use handler address table and command table to get vector 1102 e647 b9 1b 03 com1: lda hatabs+1,y ;get low byte of address 1103 e64a 85 2c sta icsprz ;and save in pointer 1104 e64c b9 1c 03 lda hatabs+2,y ;get hi byte of address 1105 e64f 85 2d sta icsprz+1 1106 e651 a4 17 ldy iccomt ;get command code 1107 e653 b9 c6 e6 lda comtab-3,y ;get command offset 1108 e656 a8 tay 1109 e657 b1 2c lda (icsprz),y ;get low byte of vector from 1110 e659 aa tax ;handler itself and save 1111 e65a c8 iny 1112 e65b b1 2c lda (icsprz),y ;get hi byte of vector 1113 e65d 85 2d sta icsprz+1 1114 e65f 86 2c stx icsprz ;set lo byte 1115 e661 18 clc ;show no error 1116 e662 60 com2: rts 1117 ; 1118 ; 1119 ; decbfl -- decrement buffer length double byte 1120 ; Z flag = 0 on return if length = 0 after decrement 1121 e663 c6 28 decbfl: dec icbllz ;decrement low byte 1122 e665 a5 28 lda icbllz ;check it 1123 e667 c9 ff cmp #$ff ;did it go below? 1124 e669 d0 02 bne decbf1 ;no 1125 e66b c6 29 dec icbllz+1 ;decrement hi byte 1126 e66d 05 29 decbf1: ora icbllz+1 ;set Z if both are zero 1127 e66f 60 rts 1128 ; 1129 ; 1130 ; incbfp -- increment working buffer pointer 1131 e670 e6 24 incbfp: inc icbalz ;bump low byte 1132 e672 d0 02 bne incbf1 ;go if not zero 1133 e674 e6 25 inc icbalz+1 ;else, bump hi byte 1134 e676 60 incbf1: rts 1135 ; 1136 ; 1137 ; subbfl -- set buffer length = buffer length - working byte count 1138 e677 a6 2e subbfl: ldx icidno ;get IOCB index 1139 e679 38 sec 1140 e67a bd 48 03 lda icbll,x ;get low byte of initial length \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 27 1141 e67d e5 28 sbc icbllz ;subtract final low byte 1142 e67f 85 28 sta icbllz ;and save back 1143 e681 bd 49 03 lda icblh,x ;get hi byte 1144 e684 e5 29 sbc icbllz+1 1145 e686 85 29 sta icblhz 1146 e688 60 rts 1147 ; 1148 ; 1149 ; gohand -- go indirect to a device handler 1150 ; Y= status on return, N flag=1 if error on return 1151 e689 a0 92 gohand: ldy #fncnot ;prepare no function status for handler rts 1152 e68b 20 93 e6 jsr cijump ;use the indirect jump 1153 e68e 84 23 sty icstaz ;save status 1154 e690 c0 00 cpy #0 ;and set N flag 1155 e692 60 rts 1156 ; 1157 ; indirect jump to handler by Paul's method 1158 e693 aa cijump: tax ;save A 1159 e694 a5 2d lda icsprz+1 ;get jump address hi byte 1160 e696 48 pha ;put on stack 1161 e697 a5 2c lda icsprz ;get jump address lo byte 1162 e699 48 pha ;put on stack 1163 e69a 8a txa ;restore A 1164 e69b a6 2e ldx icidno ;get IOCB index 1165 e69d 60 rts ;go to handler indirectly \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 28 1166 .page 1167 ; 1168 ; devsrc -- device search, find device in handler address table 1169 ; 1170 ; loop to find device 1171 e69e a0 00 devsrc: ldy #0 1172 e6a0 b1 24 lda (icbalz),y ;get device name from user 1173 e6a2 f0 0c beq cierr2 1174 e6a4 a0 21 ldy #maxdev ;initial compare index 1175 e6a6 d9 1a 03 devs1: cmp hatabs,y ;is this the device? 1176 e6a9 f0 0a beq devs2 ;yes 1177 e6ab 88 dey 1178 e6ac 88 dey ;else, point to next device name 1179 e6ad 88 dey 1180 e6ae 10 f6 bpl devs1 ;continue for all devices 1181 ; 1182 ; no device found, declare non-existent device error 1183 e6b0 a0 82 cierr2: ldy #nondev ;error code 1184 e6b2 38 sec ;show error 1185 e6b3 b0 13 bcs devs4 ;and return 1186 ; 1187 ; found device, set ichid,icdno, and init device 1188 e6b5 98 devs2: tya 1189 e6b6 85 20 sta ichidz ;save handler index 1190 e6b8 38 sec 1191 e6b9 a0 01 ldy #1 1192 e6bb b1 24 lda (icbalz),y ;get device number (drive number) 1193 e6bd e9 30 sbc #asczer ;subtract ascii zero 1194 e6bf c9 0a cmp #$a ;is number in range? 1195 e6c1 90 02 bcc devs3 ;yes 1196 e6c3 a9 01 lda #1 ;no, default to one 1197 e6c5 85 21 devs3: sta icdnoz ;save device number 1198 e6c7 18 clc ;show no error 1199 ; 1200 ; return 1201 e6c8 60 devs4: rts \newpage err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 29 1202 .page 1203 ; 1204 ; 1205 ; CIO ROM tables 1206 ; 1207 ; command table 1208 ; maps each command to offset for appropriate vector in handler 1209 e6c9 00 04 04 04 comtab: .byte 0,4,4,4,4,6,6,6,6,2,8,10 1210 e6cd 04 06 06 06 1211 e6d1 06 02 08 0a 1212 022f length =*-cioint 1213 e6d5 crntp1 =* 1214 *=$14 1215 0014 00 ciospr: .byte intorg-crntp1 ;^gciol is too long \newfile err line addr b1 b2 b3 b4 central input/output (CIO) 2-7-79 page 30 1216 1217 .title 'interrupt handler' 1218 ;lives on dk1:inthv.src 1219 0006 srtim2 = 6 ;second repeat interval 1220 ; 1221 ; this is to make DOS 2 work which used an absolute address 1222 ; 1223 *=$e912 1224 e912 4c ed e8 jmp setvbl 1225 *=setvbv 1226 e45c 4c ed e8 jmp setvbl 1227 e45f 4c ae e7 jmp sysvbl 1228 e462 4c 05 e9 jmp xitvbl 1229 *=intinv 1230 e46b 4c d5 e6 jmp ihinit 1231 ; 1232 *=vctabl+intabs-vdslst 1233 ; 1234 e480 90 e7 .word syrti ;vdslst 1235 e482 8f e7 .word syirqb ;vprced 1236 e484 8f e7 .word syirqb ;vinter 1237 e486 8f e7 .word syirqb ;vbreak 1238 ; 1239 e488 .res 8 1240 e490 8f e7 .word syirqb ;vtimr1 1241 e492 8f e7 .word syirqb ;vtimr2 1242 e494 8f e7 .word syirqb ;vtimr4 1243 e496 06 e7 .word syirq ;vimirq 1244 e498 00 00 00 00 .word 0,0,0,0,0 ;cdtmv1-4 1245 e49c 00 00 00 00 1246 e4a0 00 00 1247 e4a2 ae e7 .word sysvbl ;vvblki 1248 e4a4 05 e9 .word xitvbl ;vvblkd 1249 ; 1250 *=$900c 1251 ; 1252 900c a9 e6 lda #pirqh ;set up RAM vectors for linbug version 1253 900e 8d f9 ff sta $fff9 1254 9011 a9 f3 lda #pirql 1255 9013 8d f8 ff sta $fff8 1256 9016 a9 e7 lda #pnmih 1257 9018 8d fb ff sta $fffb 1258 901b a9 91 lda #pnmil 1259 901d 8d fa ff sta $fffa 1260 9020 60 rts \newpage err line addr b1 b2 b3 b4 interrupt handler page 31 1261 .page 1262 ; 1263 ; IRQ handler 1264 ; 1265 ; jump thru immediate IRQ vector, which ordinarily points to 1266 ; system IRQ: determine & clear cause, jump thru software vector. 1267 ; 1268 *=intorg 1269 e6d5 a9 40 ihinit: lda #$40 ;vbl on buf dlist off***for now*** 1270 e6d7 8d 0e d4 sta nmien ;enable display list, vertical blank 1271 e6da a9 38 lda #$38 ;look at data direction registers in PIA 1272 e6dc 8d 02 d3 sta pactl 1273 e6df 8d 03 d3 sta pbctl 1274 e6e2 a9 00 lda #0 ;make all inputs 1275 e6e4 8d 00 d3 sta porta 1276 e6e7 8d 01 d3 sta portb 1277 e6ea a9 3c lda #$3c ;back to ports 1278 e6ec 8d 02 d3 sta pactl 1279 e6ef 8d 03 d3 sta pbctl 1280 e6f2 60 rts 1281 e6f3 6c 16 02 pirq: jmp (vimirq) 1282 e6f6 80 cmptab: .byte $80 ;break key 1283 e6f7 40 .byte $40 ;key stroke 1284 e6f8 04 .byte $04 ;timer 4 1285 e6f9 02 .byte $02 ;timer 2 1286 e6fa 01 .byte $01 ;timer 1 1287 e6fb 08 .byte $08 ;serial out complete 1288 e6fc 10 .byte $10 ;serial out ready 1289 e6fd 20 .byte $20 ;serial in ready 1290 e6fe 1291 ; this is a table of offsets into page 2. they point to 1292 e6fe 36 adrtab: .byte brkky-intabs 1293 e6ff 08 .byte vkeybd-intabs 1294 e700 14 .byte vtimr4-intabs 1295 e701 12 .byte vtimr2-intabs 1296 e702 10 .byte vtimr1-intabs 1297 e703 0e .byte vseroc-intabs 1298 e704 0c .byte vseror-intabs 1299 e705 0a .byte vserin-intabs 1300 e706 1301 e706 48 syirq: pha ;save accumulator 1302 e707 ad 0e d2 lda irqst ; check for serial in 1303 e70a 29 20 and #$20 1304 e70c d0 0d bne syirq2 1305 e70e a9 df lda #$df ; mask all others 1306 e710 8d 0e d2 sta irqen 1307 e713 a5 10 lda pokmsk 1308 e715 8d 0e d2 sta irqen 1309 e718 6c 0a 02 jmp (vserin) 1310 e71b 8a syirq2: txa ;put X into acc 1311 e71c 48 pha ;save X onto stack 1312 e71d a2 06 ldx #$6 ;start with six offset 1313 e71f bd f6 e6 loopm: lda cmptab,x ;load mask 1314 e722 e0 05 cpx #5 ;check to see if complete is set \newpage err line addr b1 b2 b3 b4 interrupt handler page 32 1315 e724 d0 04 bne loopm2 1316 e726 25 10 and pokmsk ;is this interupt enabled? 1317 e728 f0 05 beq ll 1318 e72a 2c 0e d2 loopm2: bit irqst ; is it the interrupt? 1319 e72d f0 06 beq jmpp 1320 e72f ca ll: dex ;no dec X and try next mask 1321 e730 10 ed bpl loopm ;if not neg goto loopm 1322 e732 4c 62 e7 jmp syirq8 ;done but no interrupt 1323 e735 49 ff jmpp: eor #$ff ;complement mask 1324 e737 8d 0e d2 sta irqen ;enable all others 1325 e73a a5 10 lda pokmsk ; get poke mask 1326 e73c 8d 0e d2 sta irqen ; enable those in poke mask 1327 e73f bd fe e6 lda adrtab,x 1328 e742 aa tax 1329 e743 bd 00 02 lda intabs,x ; get address low part 1330 e746 8d 8c 02 sta jveck ; put in vector 1331 e749 bd 01 02 lda intabs+1,x ; get address high part 1332 e74c 8d 8d 02 sta jveck+1 ; put in vector high part 1333 e74f 68 pla ; pull X register from stack 1334 e750 aa tax ; put it into X 1335 e751 6c 8c 02 jmp (jveck) ; jump to the proper routine 1336 e754 a9 00 brkky2: lda #0 ; break key routine 1337 e756 85 11 sta brkkey ; set break key flag 1338 e758 8d ff 02 sta ssflag ; start/stop flag 1339 e75b 8d f0 02 sta crsinh ; cursor inhibit 1340 e75e 85 4d sta atract ; turn off atract mode 1341 e760 68 pla 1342 e761 40 rti ;exit from int 1343 e762 68 syirq8: pla 1344 e763 aa tax 1345 e764 2c 02 d3 bit pactl ;proceed ***i guess*** 1346 e767 10 06 bpl syirq9 1347 e769 ad 00 d3 lda porta clear int status bit 1348 e76c 6c 02 02 jmp (vprced) 1349 e76f 2c 03 d3 syirq9: bit pbctl ;interrupt ***i guess*** 1350 e772 10 06 bpl syirqa 1351 e774 ad 01 d3 lda portb ;clear int status 1352 e777 6c 04 02 jmp (vinter) 1353 e77a 68 syirqa: pla 1354 e77b 8d 8c 02 sta jveck 1355 e77e 68 pla 1356 e77f 48 pha 1357 e780 29 10 and #$10 ;B bit of P register 1358 e782 f0 07 beq syrti2 1359 e784 ad 8c 02 lda jveck 1360 e787 48 pha 1361 e788 6c 06 02 jmp (vbreak) 1362 e78b ad 8c 02 syrti2: lda jveck 1363 e78e 48 pha 1364 e78f 68 syirqb: pla 1365 e790 40 syrti: rti ;unidentified interrupt, just return. \newpage err line addr b1 b2 b3 b4 interrupt handler page 33 1366 .page 1367 ; 1368 ; NMI handler 1369 ; 1370 ; determine cause and jump thru vector 1371 ; 1372 e791 2c 0f d4 pnmi: bit nmist 1373 e794 10 03 bpl pnmi1 ;see if display list 1374 e796 6c 00 02 jmp (vdslst) 1375 e799 48 pnmi1: pha 1376 e79a ad 0f d4 lda nmist 1377 e79d 29 20 and #$20 ;see if reset 1378 e79f f0 03 beq *+5 1379 e7a1 4c 74 e4 jmp warmsv ;go thru warm start jump 1380 e7a4 8a txa ;save registers 1381 e7a5 48 pha 1382 e7a6 98 tya 1383 e7a7 48 pha 1384 e7a8 8d 0f d4 sta nmires ;reset interrupt status 1385 e7ab 6c 22 02 jmp (vvblki) ;jump thru vector \newpage err line addr b1 b2 b3 b4 interrupt handler page 34 1386 .page 1387 ; 1388 ; system vblank routine 1389 ; 1390 ; inc frame counter. process countdown timers. exit if I was set, clear 1391 ; set dlistl, dlisth, dmactl from RAM cells. do software repeat. 1392 ; 1393 e7ae e6 14 sysvbl: inc rtclok+2 ;inc frame counter 1394 e7b0 d0 08 bne sysvb1 1395 e7b2 e6 4d inc atract ;increment atract (causes atract when minus) 1396 e7b4 e6 13 inc rtclok+1 1397 e7b6 d0 02 bne sysvb1 1398 e7b8 e6 12 inc rtclok 1399 e7ba a9 fe sysvb1: lda #$fe ;{atract] set dark mask to normal 1400 e7bc a2 00 ldx #0 ;set colrsh to normal 1401 e7be a4 4d ldy atract ;test atract for negative 1402 e7c0 10 06 bpl vbatra ;while positive, dont go into atract 1403 e7c2 85 4d sta atract ;in atract, so stay by sta $fe 1404 e7c4 a6 13 ldx rtclok+1 ;color shift follows rtclok+1 1405 e7c6 a9 f6 lda #$f6 ;set dark mask to dark 1406 e7c8 85 4e vbatra: sta drkmsk 1407 e7ca 86 4f stx colrsh 1408 e7cc a2 00 ldx #0 ;point to timer1 1409 e7ce 20 d0 e8 jsr dctimr ;go decrement timer1 1410 e7d1 d0 03 bne sysvb2 ;branch if still counting 1411 e7d3 20 ca e8 jsr jtimr1 ;go jump to routine 1412 e7d6 a5 42 sysvb2: lda critic 1413 e7d8 d0 08 bne xxit ;go if critical set 1414 e7da ba tsx ;see if I was set 1415 e7db bd 04 01 lda $104,x ;get stacked P 1416 e7de 29 04 and #$04 ;I bit 1417 e7e0 f0 03 beq sysvb3 ;branch if ok 1418 e7e2 4c 05 e9 xxit: jmp xitvbl ;I was set, exit 1419 e7e5 ad 0d d4 sysvb3: lda penv 1420 e7e8 8d 35 02 sta lpenv 1421 e7eb ad 0c d4 lda penh 1422 e7ee 8d 34 02 sta lpenh 1423 e7f1 ad 31 02 lda sdlsth 1424 e7f4 8d 03 d4 sta dlisth 1425 e7f7 ad 30 02 lda sdlstl 1426 e7fa 8d 02 d4 sta dlistl 1427 e7fd ad 2f 02 lda sdmctl 1428 e800 8d 00 d4 sta dmactl 1429 e803 ad 6f 02 lda gprior ;global prior 1430 e806 8d 1b d0 sta prior 1431 e809 a2 08 ldx #$08 ;turn off keyboard speaker 1432 e80b 8e 1f d0 stx consol 1433 e80e 58 scollp: cli ;disable interupts 1434 e80f bd c0 02 lda pcolr0,x ;load color registers from RAM 1435 e812 45 4f eor colrsh ;do color shift 1436 e814 25 4e and drkmsk ;and dark atract 1437 e816 9d 12 d0 sta colpm0,x 1438 e819 ca dex 1439 e81a 10 f2 bpl scollp \newpage err line addr b1 b2 b3 b4 interrupt handler page 35 1440 e81c ad f4 02 lda chbas 1441 e81f 8d 09 d4 sta chbase 1442 e822 ad f3 02 lda chact 1443 e825 8d 01 d4 sta chactl 1444 e828 a2 02 ldx #2 ;point to timer 2 1445 e82a 20 d0 e8 jsr dctimr 1446 e82d d0 03 bne sysvb4 ;if didnt go zero 1447 e82f 20 cd e8 jsr jtimr2 ;go jump to timer2 routine 1448 e832 a2 02 sysvb4: ldx #2 ;restore X 1449 e834 e8 sysvbb: inx 1450 e835 e8 inx 1451 e836 bd 18 02 lda cdtmv1,x 1452 e839 1d 19 02 ora cdtmv1+1,x 1453 e83c f0 06 beq sysvba 1454 e83e 20 d0 e8 jsr dctimr ;decrement and set flag if nonzero 1455 e841 9d 26 02 sta cdtmf3-4,x 1456 e844 e0 08 sysvba: cpx #8 ;see if all done 3 1457 e846 d0 ec bne sysvbb ;loop 1458 ; check debounce counter 1459 e848 ad 0f d2 lda skstat 1460 e84b 29 04 and #$04 ;key down bit 1461 e84d f0 08 beq syvb6a ;if key down 1462 ; key up so count it 1463 e84f ad f1 02 lda keydel ;key delay counter 1464 e852 f0 03 beq syvb6a ;if counted down already 1465 e854 ce f1 02 dec keydel ;count it 1466 ; check software repeat timer 1467 e857 ad 2b 02 syvb6a: lda srtimr 1468 e85a f0 17 beq sysvb7 ;doesn't count 1469 e85c ad 0f d2 lda skstat 1470 e85f 29 04 and #$04 ;check key down bit 1471 e861 d0 60 bne sysvb6 ;branch if no longer down 1472 e863 ce 2b 02 dec srtimr ;count frame of key down 1473 e866 d0 0b bne sysvb7 ;branch if not run out 1474 ; timer ran out - reset and simulate keyboard IRQ 1475 e868 a9 06 lda #srtim2 ;timer value 1476 e86a 8d 2b 02 sta srtimr ;set timer 1477 e86d ad 09 d2 lda kbcode ;get the key 1478 e870 8d fc 02 sta ch ;put into ch 1479 ; read game controllers 1480 e873 a0 01 sysvb7: ldy #1 1481 e875 a2 03 ldx #3 1482 e877 b9 00 d3 stloop: lda porta,y 1483 e87a 4a lsr a 1484 e87b 4a lsr a 1485 e87c 4a lsr a 1486 e87d 4a lsr a 1487 e87e 9d 78 02 sta stick0,x ;store joystick 1488 e881 ca dex 1489 e882 b9 00 d3 lda porta,y 1490 e885 29 0f and #$f 1491 e887 9d 78 02 sta stick0,x ;store joystick 1492 e88a ca dex 1493 e88b 88 dey \newpage err line addr b1 b2 b3 b4 interrupt handler page 36 1494 e88c 10 e9 bpl stloop 1495 ; 1496 e88e a2 03 ldx #3 1497 e890 bd 10 d0 strl: lda trig0,x ;move joystick triggers 1498 e893 9d 84 02 sta strig0,x 1499 e896 bd 00 d2 lda pot0,x ;move pot values 1500 e899 9d 70 02 sta paddl0,x 1501 e89c bd 04 d2 lda pot4,x 1502 e89f 9d 74 02 sta paddl4,x 1503 e8a2 ca dex 1504 e8a3 10 eb bpl strl 1505 e8a5 8d 0b d2 sta potgo ;start pots for next time 1506 ; 1507 e8a8 a2 06 ldx #6 1508 e8aa a0 03 ldy #3 1509 e8ac b9 78 02 ptrlp: lda stick0,y ;transfer bits from joysticks 1510 e8af 4a lsr a ;to paddle triggers 1511 e8b0 4a lsr a 1512 e8b1 4a lsr a 1513 e8b2 9d 7d 02 sta ptrig1,x 1514 e8b5 a9 00 lda #0 1515 e8b7 2a rol a 1516 e8b8 9d 7c 02 sta ptrig0,x 1517 e8bb ca dex 1518 e8bc ca dex 1519 e8bd 88 dey 1520 e8be 10 ec bpl ptrlp 1521 ; 1522 e8c0 6c 24 02 jmp (vvblkd) ;go to deferred vblank routine 1523 00e8 sv7h = sysvb7/256 1524 0073 sv7l = (-256)*sv7h+sysvb7 1525 e8c3 a9 00 sysvb6: lda #0 1526 e8c5 8d 2b 02 sta srtimr ;zero timer 1527 e8c8 f0 a9 beq sysvb7 ;uncond 1528 e8ca 6c 26 02 jtimr1: jmp (cdtma1) 1529 e8cd 6c 28 02 jtimr2: jmp (cdtma2) 1530 ; 1531 ; subroutine to decrement a countdown timer 1532 ; entry X=offset from timer 1 1533 ; exit A,P=zero if went zero, ff otherwise 1534 ; 1535 e8d0 bc 18 02 dctimr: ldy cdtmv1,x ;lo byte 1536 e8d3 d0 08 bne dctim1 ;nonzero, go dec it 1537 e8d5 bc 19 02 ldy cdtmv1+1,x ;see if both zero 1538 e8d8 f0 10 beq dctxf ;yes, exit nonzero 1539 e8da de 19 02 dec cdtmv1+1,x ;dec hi byte 1540 e8dd de 18 02 dctim1: dec cdtmv1,x ;dec lo byte 1541 e8e0 d0 08 bne dctxf 1542 e8e2 bc 19 02 ldy cdtmv1+1,x 1543 e8e5 d0 03 bne dctxf 1544 e8e7 a9 00 lda #0 ;went zero, return zero 1545 e8e9 60 rts 1546 e8ea a9 ff dctxf: lda #$ff ;return nonzero 1547 e8ec 60 rts \newpage err line addr b1 b2 b3 b4 interrupt handler page 37 1548 .page 1549 ; 1550 ; subroutine to set vertical blank vectors and timers 1551 ; entry X=hi,Y=lo byte to set 1552 ; A= 1-5 timers 1-5 1553 ; 6 imm vblank 1554 ; 7 def vblank 1555 ; 1556 e8ed 0a setvbl: asl a ;mul by 2 1557 e8ee 8d 2d 02 sta intemp 1558 e8f1 8a txa 1559 e8f2 a2 05 ldx #5 1560 e8f4 8d 0a d4 sta wsync ;waste 20 CPU cycles 1561 e8f7 ca setlop: dex ;to alowd vblank to happen 1562 e8f8 d0 fd bne setlop ;if this is line "7c" 1563 e8fa ae 2d 02 ldx intemp 1564 e8fd 9d 17 02 sta cdtmv1-1,x 1565 e900 98 tya 1566 e901 9d 16 02 sta cdtmv1-2,x 1567 e904 60 rts 1568 ; 1569 ; exit from vertical blank 1570 ; 1571 e905 68 xitvbl: pla ;unstack Y 1572 e906 a8 tay 1573 e907 68 pla ;unstack X 1574 e908 aa tax 1575 e909 68 pla ;unstack A 1576 e90a 40 rti ;and go back from whence. 1577 00e6 pirqh = pirq/256 1578 00f3 pirql = (-256)*pirqh+pirq 1579 00e7 pnmih = pnmi/256 1580 0091 pnmil = (-256)*pnmih+pnmi 1581 ; spare byte or module too long flag 1582 e90b crntp2 =* 1583 *=$14 1584 0014 39 intspr: .byte sioorg-crntp2 ;^ginthv is too long \newfile err line addr b1 b2 b3 b4 interrupt handler page 38 1585 1586 .title 'SIO ( serial bus input/output controller )' 1587 ; colleen operating system 1588 ; 1589 ; SIO ( serial bus input/output controller ) 1590 ; with software baud rate correction on cassette 1591 ; 1592 ; 1593 ; Al Miller 3-apr-79 1594 ; 1595 ; 1596 ; This module has one entry point. It is called by the device 1597 ; handlers. It interprets a previously established device control 1598 ; block (stored in global RAM) to issue commands 1599 ; to the serial bus to control transmitting and receiving data. 1600 ; 1601 ; 1602 ; 1603 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 39 1604 .page 1605 ; equates 1606 ; 1607 ; dcd device bus id numbers 1608 0030 floppy = $30 1609 ;printr = $40 1610 ;casset = $60 ;!!!!! ***** 1611 0060 caset = $60 ;!!!!! ***** 1612 ; 1613 ; 1614 ;bus commands 1615 ; 1616 0052 read = 'R 1617 0057 write = 'W 1618 ;statis = 'S 1619 ;format = '! 1620 ; 1621 ; 1622 ; command aux bytes 1623 ; 1624 0053 sidway = 'S ;print 16 characters sideways 1625 004e normal = 'N ;print 40 characters normally 1626 0044 double = 'D ;print 20 characters double wide 1627 0050 plot = 'P ;plot mode 1628 ; 1629 ; 1630 ; bus responses 1631 ; 1632 0041 ack = 'A ;device acknowledges information 1633 004e nack = 'N ;device did not understand 1634 0043 complt = 'C ;device successfully completed operation 1635 0045 error = 'E ;device incurred an error in an attempted op 1636 ; 1637 ; 1638 ; miscellaneous equates 1639 ; 1640 0028 b192lo = $28 ;19200 baud rate POKEY counter values (lo by 1641 0000 b192hi = $00 ;(hi byte) 1642 00cc b600lo = $cc ;600 baud (lo byte) 1643 0005 b600hi = $05 ;(hi byte) 1644 0005 hitone = $05 ;fsk hi freq POKEY counte value (5326 hz) 1645 0007 lotone = $07 ;fsk lo freq POKEY counter value (3995 hz) 1646 ; 1647 .if PALFLG 1648 wirglo = 150 ;write inter record gap (in 1/60 sec) 1649 rirglo = 100 ;read inter record gap (in 1/60 sec) 1650 wsirg = 13 ;short write inter record gap 1651 rsirg = 8 ;short read inter record gap 1652 .endif 1653 .if PALFLG-1 1654 00b4 wirglo = 180 ;write inter record gap (in 1/60 sec) 1655 0078 rirglo = 120 ;read inter record gap (in 1/60 sec) 1656 000f wsirg = 15 ;short write inter record gap 1657 000a rsirg = 10 ;short read inter record gap \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 40 1658 .endif 1659 0000 wirghi = 0 1660 0000 rirghi = 0 1661 ; 1662 0034 ncomlo = $34 ;PIA command to lower not command line 1663 003c ncomhi = $3c ;PIA command to raise not command line 1664 0034 motrgo = $34 ;PIA command to turn on cassette motor 1665 003c motrst = $3c ;PIA command to turn off motor 1666 ; 1667 0002 temphi = temp/256 ;address of temp cell (hi byte) 1668 003e templo = (-256)*temphi+temp ;(lo byte) 1669 0002 cbufhi = cdevic/256 ;address of command buffer (hi byte) 1670 003a cbuflo = (-256)*cbufhi+cdevic ;(lo byte) 1671 ; 1672 000d cretri = 13 ;number of command frame retries 1673 0001 dretri = 1 ;number of device retries 1674 0002 ctimlo = 2 ;command frame ack time out (lo byte) 1675 0000 ctimhi = 0 ;command frame ack time out (hi byte) 1676 ; 1677 ; 1678 ;jtadrh = jtimer/256 ;hi byte of jump timer routine addr "m 1679 ;jtadrl = (-256)*jtadrh+jtimer ;"moved to line 1428" 1680 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 41 1681 .page 1682 ; SIO 1683 ; 1684 ; 1685 *=siov 1686 e459 4c 59 e9 jmp sio ;SIO entry point 1687 ; 1688 *=sioinv 1689 e465 4c 44 e9 jmp sioint ;SIO initialization entry point 1690 ; 1691 *=sendev 1692 e468 4c f2 eb jmp senden ;send enable entry point 1693 ; 1694 *=vctabl-intabs+vserin 1695 ; 1696 e48a 0f eb .word isrsir ;vserin 1697 e48c 90 ea .word isrodn ;vseror 1698 e48e cf ea .word isrtd ;vseroc 1699 ; 1700 ; 1701 ; 1702 *=sioorg 1703 ; 1704 ; SIO initialization subroutine 1705 ; 1706 e944 a9 3c sioint: lda #motrst 1707 e946 8d 02 d3 sta pactl ;turn off motor 1708 ; 1709 e949 a9 3c lda #ncomhi 1710 e94b 8d 03 d3 sta pbctl ;raise not command line 1711 ; 1712 ; 1713 e94e a9 03 lda #3 1714 e950 8d 32 02 sta sskctl ;get POKEY out of initialize mode 1715 e953 85 41 sta soundr ;init poke address for quiet I/O 1716 e955 8d 0f d2 sta skctl 1717 ; 1718 ; 1719 e958 60 rts ;return 1720 ; 1721 ; 1722 ; 1723 ; 1724 ; 1725 ; 1726 e959 ba sio: tsx 1727 e95a 8e 18 03 stx stackp ;save stack pointer 1728 e95d a9 01 lda #1 1729 e95f 85 42 sta critic 1730 ; 1731 e961 ad 00 03 lda ddevic 1732 e964 c9 60 cmp #caset 1733 e966 d0 03 bne notcst ;branch if not cassette 1734 e968 4c 80 eb jmp casent ;otherwise jump to cassette enter \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 42 1735 ; 1736 ; all devices except cassette are intelligent 1737 ; 1738 e96b a9 00 notcst: lda #0 1739 e96d 8d 0f 03 sta casflg ;init cassette flag to no cassette 1740 ; 1741 e970 a9 01 lda #dretri ;set number of device retries 1742 e972 85 37 sta dretry 1743 e974 a9 0d commnd: lda #cretri ;set number of command frame retries 1744 e976 85 36 sta cretry 1745 ; 1746 ; send a command frame 1747 ; 1748 e978 a9 28 comfrm: lda #b192lo ;set baud rate to 19200 1749 e97a 8d 04 d2 sta audf3 1750 e97d a9 00 lda #b192hi 1751 e97f 8d 06 d2 sta audf4 1752 ; 1753 e982 18 clc ;set up command buffer 1754 e983 ad 00 03 lda ddevic 1755 e986 6d 01 03 adc dunit 1756 e989 69 ff adc #$ff ;subtract 1 1757 e98b 8d 3a 02 sta cdevic ;set bus id number 1758 ; 1759 e98e ad 02 03 lda dcomnd 1760 e991 8d 3b 02 sta ccomnd ;set bus command 1761 ; 1762 e994 ad 0a 03 lda daux1 ;store command frame aux bytes 1 and 2 1763 e997 8d 3c 02 sta caux1 1764 e99a ad 0b 03 lda daux2 1765 e99d 8d 3d 02 sta caux2 ;done setting up command buffer 1766 ; 1767 e9a0 18 clc ;set buffer pointer to command frame buffer 1768 e9a1 a9 3a lda #cbuflo 1769 e9a3 85 32 sta bufrlo ;and buffer end address 1770 e9a5 69 04 adc #4 1771 e9a7 85 34 sta bfenlo 1772 e9a9 a9 02 lda #cbufhi 1773 e9ab 85 33 sta bufrhi 1774 e9ad 85 35 sta bfenhi ;done setting up buffer pointer 1775 ; 1776 e9af a9 34 lda #ncomlo ;lower not command line 1777 e9b1 8d 03 d3 sta pbctl 1778 ; 1779 e9b4 20 8a ec jsr sendin ;send the command frame to a smart device 1780 ; 1781 e9b7 ad 3f 02 lda errflg 1782 e9ba d0 03 bne badcom ;branch if an error received 1783 ; 1784 e9bc 98 tya 1785 e9bd d0 07 bne ackrec ;branch if ack received 1786 ; 1787 ; 1788 e9bf c6 36 badcom: dec cretry ;a nack or time out occured \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 43 1789 e9c1 10 b5 bpl comfrm ;so branch if any retries left 1790 ; 1791 e9c3 4c 06 ea jmp derr1 ;otherwise, jump to return section 1792 ; 1793 ; 1794 e9c6 ad 03 03 ackrec: lda dstats ;ack was received 1795 e9c9 10 0c bpl watcom ;branch to wait for complete , 1796 ; if there is no data to be sent 1797 ; 1798 ; 1799 ; 1800 ; send a data frame to peripheral 1801 ; 1802 e9cb a9 0d lda #cretri ;set number of retries 1803 e9cd 85 36 sta cretry 1804 ; 1805 e9cf 20 6a eb jsr ldpntr ;load buffer pointer with DCB information 1806 ; 1807 e9d2 20 8a ec jsr sendin ;go send the data frame to a smart device 1808 ; 1809 e9d5 f0 e8 beq badcom ;branch if bad 1810 ; 1811 ; 1812 ; 1813 ; wait for complete signal from peripheral 1814 ; 1815 e9d7 20 75 ec watcom: jsr sttmot ;set ddevice time out values in Y,X 1816 ; 1817 e9da a9 00 lda #$00 1818 e9dc 8d 3f 02 sta errflg ;clear error flag 1819 ; 1820 e9df 20 9b ec jsr waiter ;set up timer and wait 1821 e9e2 f0 12 beq derr ;branch if time out 1822 ; 1823 ; 1824 ; device did not time out 1825 ; 1826 e9e4 2c 03 03 bit dstats 1827 e9e7 70 07 bvs modata ;branch if more data follows 1828 ; 1829 e9e9 ad 3f 02 lda errflg 1830 e9ec d0 18 bne derr1 ;branch if an error occurred 1831 e9ee f0 1d beq return ;otherwise return 1832 ; 1833 ; 1834 ; 1835 ; 1836 ; receive a data frame from peripheral 1837 ; 1838 e9f0 20 6a eb modata: jsr ldpntr ;load buffer pointer with DCB information 1839 ; 1840 e9f3 20 e0 ea jsr receiv ;go receive a data frame 1841 ; 1842 e9f6 ad 3f 02 derr: lda errflg \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 44 1843 e9f9 f0 05 beq noterr ;branch if no error preceeded data 1844 ; 1845 e9fb ad 19 03 lda tstat ;get temp status 1846 e9fe 85 30 sta status ;store in real status 1847 ; 1848 ; 1849 ea00 a5 30 noterr: lda status 1850 ea02 c9 01 cmp #succes 1851 ea04 f0 07 beq return ;branch if completely successful 1852 ; 1853 ea06 c6 37 derr1: dec dretry 1854 ea08 30 03 bmi return ;branch if out of device retries 1855 ; 1856 ea0a 4c 74 e9 jmp commnd ;otherwise, one more time 1857 ; 1858 ; 1859 ; 1860 ; 1861 ea0d 20 5f ec return: jsr sendds ;disable POKEY interrupts 1862 ea10 a9 00 lda #0 1863 ea12 85 42 sta critic 1864 ea14 a4 30 ldy status ;return status in Y 1865 ea16 8c 03 03 sty dstats ;and the DCB status word 1866 ea19 60 rts return 1867 ; 1868 ; 1869 ; 1870 ; 1871 ; wait subroutine 1872 ; 1873 ; waits for complete or ack 1874 ; returns Y=$ff if successful, Y=$00 if not 1875 ; 1876 ea1a a9 00 wait: lda #$00 1877 ea1c 8d 3f 02 sta errflg ;clear error flag 1878 ; 1879 ea1f 18 clc ;load buffer pointer with address 1880 ea20 a9 3e lda #templo ;of temporary RAM cell 1881 ea22 85 32 sta bufrlo 1882 ea24 69 01 adc #1 1883 ea26 85 34 sta bfenlo ;also set buffer end +1 address 1884 ea28 a9 02 lda #temphi 1885 ea2a 85 33 sta bufrhi 1886 ea2c 85 35 sta bfenhi ;done loading pointer 1887 ; 1888 ea2e a9 ff lda #$ff 1889 ea30 85 3c sta nocksm ;set no checksum follows data flag 1890 ; 1891 ea32 20 e0 ea jsr receiv ;go receive a byte 1892 ; 1893 ea35 a0 ff ldy #$ff ;assume success 1894 ea37 a5 30 lda status 1895 ea39 c9 01 cmp #succes 1896 ea3b d0 19 bne nwok ;branch if it did not work ok \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 45 1897 ; 1898 ; 1899 ; 1900 ; 1901 ea3d ad 3e 02 wok: lda temp ;make sure the byte successfully received 1902 ea40 c9 41 cmp #ack ;was actually an ack or complete 1903 ea42 f0 21 beq good 1904 ea44 c9 43 cmp #complt 1905 ea46 f0 1d beq good 1906 ; 1907 ea48 c9 45 cmp #error 1908 ea4a d0 06 bne notder ;branch if device did not send back 1909 ; a device error code 1910 ea4c a9 90 lda #derror 1911 ea4e 85 30 sta status ;set device error status 1912 ea50 d0 04 bne nwok 1913 ; 1914 ea52 a9 8b notder: lda #dnack ;otherwise set nack status 1915 ea54 85 30 sta status 1916 ; 1917 ea56 a5 30 nwok: lda status 1918 ea58 c9 8a cmp #timout 1919 ea5a f0 07 beq bad ;branch if time out 1920 ; 1921 ea5c a9 ff lda #$ff 1922 ea5e 8d 3f 02 sta errflg ;set some error flag 1923 ea61 d0 02 bne good ;return with out setting Y = 0 1924 ; 1925 ea63 a0 00 bad: ldy #0 1926 ; 1927 ea65 a5 30 good: lda status 1928 ea67 8d 19 03 sta tstat 1929 ea6a 60 rts ;return 1930 ; 1931 ; 1932 ; 1933 ; 1934 ; 1935 ; send subroutine 1936 ; 1937 ; sends a buffer of bytes out over the serial bus 1938 ; 1939 ; 1940 ea6b a9 01 send: lda #succes ;assume success 1941 ea6d 85 30 sta status 1942 ; 1943 ea6f 20 f2 eb jsr senden ;enable sending 1944 ; 1945 ea72 a0 00 ldy #0 1946 ea74 84 31 sty chksum ;clear check sum 1947 ea76 84 3b sty chksnt ;checksum sent flag 1948 ea78 84 3a sty xmtdon ;transmission done flag 1949 ; 1950 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 46 1951 ea7a b1 32 lda (bufrlo),y ;put first byte from buffer 1952 ea7c 8d 0d d2 sta serout ;into the serial output register 1953 ; 1954 ; 1955 ea7f 85 31 sta chksum ;put it in checksum 1956 ; 1957 ea81 a5 11 notdon: lda brkkey 1958 ea83 d0 03 bne ntbrko 1959 ea85 4c a0 ed jmp broke ;jump if break key pressed 1960 ; 1961 ea88 a5 3a ntbrko: lda xmtdon ;loop until transmission is done 1962 ea8a f0 f5 beq notdon 1963 ; 1964 ea8c 20 5f ec jsr sendds ;disable sending 1965 ; 1966 ea8f 60 rts ;return 1967 ; 1968 ; 1969 ; 1970 ; 1971 ; 1972 ; 1973 ; output data needed interrupt service routine 1974 ; 1975 ea90 98 isrodn: tya 1976 ea91 48 pha ;save Y reg on stack 1977 ; 1978 ea92 e6 32 inc bufrlo ;increment buffer pointer 1979 ea94 d0 02 bne nowrpo 1980 ea96 e6 33 inc bufrhi 1981 ; 1982 ea98 a5 32 nowrpo: lda bufrlo ;check if past end of buffer 1983 ea9a c5 34 cmp bfenlo 1984 ea9c a5 33 lda bufrhi ;high part 1985 ea9e e5 35 sbc bfenhi 1986 eaa0 90 1c bcc notend ;branch if not past end of buffer 1987 ; 1988 eaa2 a5 3b lda chksnt 1989 eaa4 d0 0b bne relone ;branch if checksum already sent 1990 ; 1991 eaa6 a5 31 lda chksum 1992 eaa8 8d 0d d2 sta serout ;send check sum 1993 eaab a9 ff lda #$ff 1994 eaad 85 3b sta chksnt ;set checksum sent flag 1995 eaaf d0 09 bne chkdon 1996 ; 1997 eab1 a5 10 relone: lda pokmsk ;enable transmit done interrupt 1998 eab3 09 08 ora #$08 1999 eab5 85 10 sta pokmsk 2000 eab7 8d 0e d2 sta irqen 2001 ; 2002 eaba 68 chkdon: pla 2003 eabb a8 tay ;restore Y reg 2004 eabc 68 pla ;return from interrupt \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 47 2005 eabd 40 rti 2006 ; 2007 ; 2008 eabe a0 00 notend: ldy #0 2009 eac0 b1 32 lda (bufrlo),y ;put next byte from buffer 2010 eac2 8d 0d d2 sta serout ;into the serial output register 2011 ; 2012 eac5 18 clc ;add it to checksum 2013 eac6 65 31 adc chksum 2014 eac8 69 00 adc #0 2015 eaca 85 31 sta chksum 2016 ; 2017 eacc 4c ba ea jmp chkdon ;go return 2018 ; 2019 ; 2020 ; 2021 ; 2022 ; 2023 ; 2024 ; transmit done interrupt service routine 2025 ; 2026 eacf a5 3b isrtd: lda chksnt 2027 ead1 f0 0b beq fooey ;branch if checksum not yet sent 2028 ; 2029 ead3 85 3a sta xmtdon ;otherwise set transmission done flag 2030 ; 2031 ead5 a5 10 lda pokmsk ;disable transmit done interrupt 2032 ead7 29 f7 and #$f7 2033 ead9 85 10 sta pokmsk 2034 eadb 8d 0e d2 sta irqen 2035 ; 2036 eade 68 fooey: pla ;return from interrupt 2037 eadf 40 rti 2038 ; 2039 ; 2040 ; 2041 ; 2042 ; 2043 ; 2044 ; 2045 ; 2046 ; receive subroutine 2047 ; 2048 eae0 a9 00 receiv: lda #0 2049 ; 2050 eae2 ac 0f 03 ldy casflg 2051 eae5 d0 02 bne noclr ;branch if cassette 2052 ; 2053 eae7 85 31 sta chksum ;clear chksum 2054 eae9 85 38 noclr: sta bufrfl ;buffer full flag 2055 eaeb 85 39 sta recvdn ;receive done flag 2056 ; 2057 ; 2058 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 48 2059 eaed a9 01 lda #succes 2060 eaef 85 30 sta status ;set good status for default case. 2061 eaf1 20 1b ec jsr recven ;do receive enable 2062 eaf4 a9 3c lda #ncomhi ;command frame hi command 2063 eaf6 8d 03 d3 sta pbctl ;store in PIA 2064 eaf9 a5 11 chktim: lda brkkey 2065 eafb d0 03 bne ntbrk1 2066 eafd 4c a0 ed jmp broke ;jump if break key pressed 2067 ; 2068 eb00 ad 17 03 ntbrk1: lda timflg ;no, 2069 eb03 f0 05 beq tout ;if timeout, go set error status 2070 eb05 a5 39 lda recvdn 2071 eb07 f0 f0 beq chktim ;done ? 2072 eb09 60 goback: rts 2073 eb0a a9 8a tout: lda #timout ;yes, 2074 eb0c 85 30 sta status ;set timeout status 2075 ; 2076 ; 2077 ; 2078 ; 2079 ; 2080 ; 2081 eb0e 60 rretrn: rts ;return 2082 ; 2083 ; 2084 ; 2085 ; 2086 ; 2087 ; 2088 ; 2089 ; serial input ready interrupt service routine 2090 ; 2091 eb0f 98 isrsir: tya 2092 eb10 48 pha ;save Y reg on stack 2093 ; 2094 ; 2095 ; 2096 eb11 ad 0f d2 lda skstat 2097 eb14 8d 0a d2 sta skres ;reset status register 2098 ; ******** this may not be the place to do it ********* 2099 ; 2100 eb17 30 04 bmi ntfram ;branch if no framing error 2101 ; 2102 eb19 a0 8c ldy #frmerr 2103 eb1b 84 30 sty status ;set frame errorr status 2104 ; 2105 eb1d 29 20 ntfram: and #$20 2106 eb1f d0 04 bne ntovrn ;branch if no overrun error 2107 ; 2108 eb21 a0 8e ldy #ovrrun 2109 eb23 84 30 sty status ;set overrun error status 2110 ; 2111 eb25 a5 38 ntovrn: lda bufrfl 2112 eb27 f0 13 beq notyet ;branch if buffer was not yet filled \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 49 2113 ; 2114 eb29 ad 0d d2 lda serin ;this input byte is the checksum 2115 eb2c c5 31 cmp chksum 2116 eb2e f0 04 beq sretrn ;branch if checksums match 2117 ; 2118 eb30 a0 8f ldy #chkerr 2119 eb32 84 30 sty status ;set checksum error status 2120 ; 2121 eb34 a9 ff sretrn: lda #$ff ;set receive done flag 2122 eb36 85 39 sta recvdn 2123 ; 2124 eb38 68 susual: pla 2125 eb39 a8 tay ;restore Y reg 2126 eb3a 68 pla ;return from interrupt 2127 eb3b 40 rti 2128 ; 2129 ; 2130 ; 2131 eb3c ad 0d d2 notyet: lda serin 2132 eb3f a0 00 ldy #0 2133 eb41 91 32 sta (bufrlo),y ;store input register into buffer 2134 ; 2135 eb43 18 clc ;add it to checksum 2136 eb44 65 31 adc chksum 2137 eb46 69 00 adc #0 2138 eb48 85 31 sta chksum 2139 ; 2140 eb4a e6 32 inc bufrlo ;increment buffer pointer 2141 eb4c d0 02 bne ntwrp1 2142 eb4e e6 33 inc bufrhi 2143 ; 2144 eb50 a5 32 ntwrp1: lda bufrlo 2145 eb52 c5 34 cmp bfenlo 2146 eb54 a5 33 lda bufrhi 2147 eb56 e5 35 sbc bfenhi 2148 eb58 90 de bcc susual ;branch if new buffer address is in buffer l 2149 ; 2150 eb5a a5 3c lda nocksm 2151 eb5c f0 06 beq goon ;branch if a checksum will follow data 2152 ; 2153 eb5e a9 00 lda #0 2154 eb60 85 3c sta nocksm ;clear no checksum flag 2155 ; 2156 eb62 f0 d0 beq sretrn ;go return and set receive done flag 2157 ; 2158 ; 2159 eb64 a9 ff goon: lda #$ff 2160 eb66 85 38 sta bufrfl ;set buffer full flag 2161 ; 2162 eb68 d0 ce bne susual ;go return 2163 ; 2164 ; 2165 ; 2166 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 50 2167 ; 2168 ; 2169 ; 2170 ; 2171 ; load buffer pointer subroutine 2172 ; 2173 ; load buffer pointer with DCB buffer information 2174 ; 2175 eb6a 18 ldpntr: clc 2176 eb6b ad 04 03 lda dbuflo 2177 eb6e 85 32 sta bufrlo 2178 eb70 6d 08 03 adc dbytlo 2179 eb73 85 34 sta bfenlo ;also set buffer end + 1 address 2180 ; 2181 eb75 ad 05 03 lda dbufhi 2182 eb78 85 33 sta bufrhi 2183 eb7a 6d 09 03 adc dbythi 2184 eb7d 85 35 sta bfenhi 2185 ; 2186 eb7f 60 rts ;return 2187 ; 2188 ; 2189 ; 2190 ; 2191 ; 2192 ; 2193 ; 2194 ; 2195 ; cassette handling code 2196 ; 2197 eb80 ad 03 03 casent: lda dstats 2198 eb83 10 2e bpl casred ;branch if input from cassette 2199 ; 2200 ; write a record 2201 ; 2202 eb85 a9 cc lda #b600lo ;set baud rate to 600 2203 eb87 8d 04 d2 sta audf3 2204 eb8a a9 05 lda #b600hi 2205 eb8c 8d 06 d2 sta audf4 2206 ; 2207 eb8f 20 f2 eb jsr senden ;turn on POKEY mark tone 2208 ; 2209 eb92 a0 0f ldy #wsirg ;load short write inter record gap time 2210 eb94 ad 0b 03 lda daux2 2211 eb97 30 02 bmi srtir0 ;branch if short gap is desired 2212 ; 2213 eb99 a0 b4 ldy #wirglo ;set write IRG time 2214 eb9b a2 00 srtir0: ldx #wirghi 2215 eb9d 20 b9 ed jsr setvbx 2216 ; 2217 eba0 a9 34 lda #motrgo 2218 eba2 8d 02 d3 sta pactl ;turn on motor 2219 ; 2220 eba5 ad 17 03 timit: lda timflg ;loop until done \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 51 2221 eba8 d0 fb bne timit 2222 ; 2223 ebaa 20 6a eb jsr ldpntr ;load buffer pointer with DCB information 2224 ; 2225 ebad 20 6b ea jsr send ;send a buffer 2226 ; 2227 ebb0 4c df eb jmp cretrn ;go return 2228 ; 2229 ; 2230 ; 2231 ; receive a record 2232 ; 2233 ebb3 a9 ff casred: lda #$ff 2234 ebb5 8d 0f 03 sta casflg ;set set cassette flag 2235 ; 2236 ebb8 a0 0a ldy #rsirg ;load short read inter record gap time 2237 ebba ad 0b 03 lda daux2 2238 ebbd 30 02 bmi srtir1 ;branch if short gap is desired 2239 ; 2240 ebbf a0 78 ldy #rirglo ;set time out for read IRG 2241 ebc1 a2 00 srtir1: ldx #rirghi 2242 ebc3 20 b9 ed jsr setvbx 2243 ; 2244 ebc6 a9 34 lda #motrgo 2245 ebc8 8d 02 d3 sta pactl ;turn on motor 2246 ; 2247 ebcb ad 17 03 timit1: lda timflg ;loop until done 2248 ebce d0 fb bne timit1 2249 ; 2250 ebd0 20 6a eb jsr ldpntr ;load buffer pointer with DCB information 2251 ; 2252 ebd3 20 75 ec jsr sttmot ;set device time out in Y,X 2253 ebd6 20 b9 ed jsr setvbx 2254 ; 2255 ebd9 20 10 ed jsr begin ;set initial baud rate 2256 ; 2257 ebdc 20 e0 ea jsr receiv ;go receive a block 2258 ; 2259 ebdf ad 0b 03 cretrn: lda daux2 2260 ebe2 30 05 bmi srtir2 ;branch if doing short inter record gaps 2261 ; don't turn off cassette motor 2262 ebe4 a9 3c lda #motrst 2263 ebe6 8d 02 d3 sta pactl ;turn off motor 2264 ; 2265 ebe9 4c 0d ea srtir2: jmp return ;go return 2266 ; 2267 ; 2268 ; 2269 ; 2270 ; 2271 ebec a9 00 jtimer: lda #$00 2272 00eb jtadrh = jtimer/256 ;hi byte of jump timer routine addr 2273 00ec jtadrl = (-256)*jtadrh+jtimer 2274 ebee 8d 17 03 sta timflg ;set time out flag \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 52 2275 ebf1 60 rts 2276 ; 2277 ; 2278 ; 2279 ; 2280 ; 2281 ;; 2282 ; send enable subroutine 2283 ; 2284 ebf2 a9 07 senden: lda #$07 ;mask off previous serial bus control bits 2285 ebf4 2d 32 02 and sskctl 2286 ebf7 09 20 ora #$20 ;set transmit mode 2287 ; 2288 ebf9 ac 00 03 ldy ddevic 2289 ebfc c0 60 cpy #caset 2290 ebfe d0 0c bne notcas ;branch if not cassette 2291 ; 2292 ec00 09 08 ora #$08 ;set the fsk output bit 2293 ; 2294 ec02 a0 07 ldy #lotone ;set fsk tone frequencies 2295 ec04 8c 02 d2 sty audf2 2296 ec07 a0 05 ldy #hitone 2297 ec09 8c 00 d2 sty audf1 2298 ; 2299 ec0c 8d 32 02 notcas: sta sskctl ;store new value to system mask 2300 ec0f 8d 0f d2 sta skctl ;store to actual register 2301 ; 2302 ec12 a9 c7 lda #$c7 ;mask off previous serial bus interrupt bits 2303 ec14 25 10 and pokmsk 2304 ec16 09 10 ora #$10 ;enable output data needed interrupt 2305 ; 2306 ; 2307 ec18 4c 31 ec jmp contin ;go continue in receive enable subroutine 2308 ; 2309 ; 2310 ; 2311 ; 2312 ; 2313 ; 2314 ; 2315 ; 2316 ; 2317 ; 2318 ; receive enable subroutine 2319 ; 2320 ec1b a9 07 recven: lda #$07 ;mask off previous serial bus control bits 2321 ec1d 2d 32 02 and sskctl 2322 ec20 09 10 ora #$10 ;set receive mode asynch. 2323 ec22 8d 32 02 sta sskctl ;store new value to system mask 2324 ec25 8d 0f d2 sta skctl ;store to actual register 2325 ; 2326 ec28 8d 0a d2 sta skres ;reset serial port/keyboard status register 2327 ; 2328 ec2b a9 c7 lda #$c7 ;mask off previous serial bus interrupt bits \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 53 2329 ec2d 25 10 and pokmsk 2330 ec2f 09 20 ora #$20 ;enable receive interrupt 2331 ec31 85 10 contin: sta pokmsk ;store new value to system mask 2332 ec33 8d 0e d2 sta irqen ;store to actual register 2333 ; 2334 ; 2335 ec36 a9 28 lda #$28 ;clock ch.3 with 1.79 mhz 2336 ec38 8d 08 d2 sta audctl ;clock ch.4 with ch. 3 2337 ; 2338 ec3b a2 06 ldx #6 ;set pure tones, no volume 2339 ec3d a9 a8 lda #$a8 2340 ec3f a4 41 ldy soundr ;test quiet I/O flag 2341 ec41 d0 02 bne noise1 ;ne is normal (noisy) 2342 ec43 a9 a0 lda #$a0 2343 ec45 9d 01 d2 noise1: sta audc1,x 2344 ec48 ca dex 2345 ec49 ca dex 2346 ec4a 10 f9 bpl noise1 2347 ; 2348 ec4c a9 a0 lda #$a0 2349 ec4e 8d 05 d2 sta audc3 ;turn off sound on channel 3 2350 ec51 ac 00 03 ldy ddevic 2351 ec54 c0 60 cpy #caset 2352 ec56 f0 06 beq cas31 ;branch if cassette is desired 2353 ec58 8d 01 d2 sta audc1 ;otherwise turn off channels 1 and 2 2354 ec5b 8d 03 d2 sta audc2 2355 ; 2356 ; 2357 ec5e 60 cas31: rts ;return 2358 ; 2359 ; 2360 ; 2361 ; 2362 ; 2363 ; 2364 ; 2365 ; 2366 ; 2367 ; 2368 ; disable send and disable receive subroutines 2369 ; 2370 ec5f ea sendds: nop 2371 ec60 a9 c7 recvds: lda #$c7 ;mask off serial bus interrupts 2372 ec62 25 10 and pokmsk 2373 ec64 85 10 sta pokmsk ;store new value to system mask 2374 ec66 8d 0e d2 sta irqen ;store to actual register 2375 ; 2376 ec69 a2 06 ldx #6 2377 ec6b a9 00 lda #0 2378 ec6d 9d 01 d2 zerit: sta audc1,x 2379 ec70 ca dex 2380 ec71 ca dex 2381 ec72 10 f9 bpl zerit ;turn off audio volume 2382 ; \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 54 2383 ec74 60 rts ;return 2384 ; 2385 ; 2386 ; 2387 ; 2388 ; 2389 ; 2390 ; 2391 ; 2392 ; 2393 ; 2394 ; set ddevice time out values in Y,X subroutine 2395 ; 2396 ec75 ad 06 03 sttmot: lda dtimlo ;get device time out in 1 second incr 2397 ec78 6a ror a ;put 6 hi bits in X, lo 2 bits in Y 2398 ec79 6a ror a 2399 ec7a a8 tay ;temp save 2400 ec7b 29 3f and #$3f ;mask off 2 hi bits 2401 ec7d aa tax ;this is hi byte of time out 2402 ; 2403 ec7e 98 tya ;restore 2404 ec7f 6a ror a 2405 ec80 29 c0 and #$c0 ;mask off all but 2 hi bits 2406 ec82 a8 tay ;this is lo byte of time out 2407 ; 2408 ec83 60 rts 2409 ; 2410 ; 2411 ; 2412 ; 2413 ; 2414 ; 2415 ; 2416 ; 2417 ; 2418 ; 2419 ec84 0f eb inttbl: .word isrsir ;serial input ready 2420 ec86 90 ea .word isrodn ;output data needed 2421 ec88 cf ea .word isrtd ;transmission done 2422 ; 2423 00eb sirhi = isrsir/256 ;serial input ready isr address 2424 000f sirlo = (-256)*sirhi+isrsir 2425 00ea odnhi = isrodn/256 ;output data needed isr address 2426 0090 odnlo = (-256)*odnhi+isrodn 2427 00ea tdhi = isrtd/256 ;transmission done isr address 2428 00cf tdlo = (-256)*tdhi+isrtd 2429 ; 2430 ; 2431 ; 2432 ; 2433 ; send a data frame to an intelligent peripheral subroutine 2434 ; 2435 ; 2436 ec8a a2 01 sendin: ldx #$01 \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 55 2437 ec8c a0 ff delay0: ldy #$ff 2438 ec8e 88 delay1: dey 2439 ec8f d0 fd bne delay1 2440 ec91 ca dex 2441 ec92 d0 f8 bne delay0 2442 ; 2443 ec94 20 6b ea jsr send ;go send the data frame 2444 ; 2445 ec97 a0 02 ldy #ctimlo ;set ack tine out 2446 ec99 a2 00 ldx #ctimhi 2447 ec9b 20 b9 ed waiter: jsr setvbx 2448 ; 2449 ec9e 20 1a ea jsr wait ;wait for ack 2450 ; 2451 eca1 98 tya ;if Y=0, a time out or nack occured 2452 ; 2453 eca2 60 rts ;return 2454 ; 2455 ; 2456 ; 2457 ; 2458 ; 2459 ; 2460 ; 2461 ; 2462 ; 2463 ; 2464 ; 2465 ; compute value for POKEY freq regs for the baud rate as 2466 ; measured by an interval of the 'vcount' timer. 2467 ; 2468 eca3 8d 10 03 comput: sta timer2 2469 eca6 8c 11 03 sty timer2+1 ;save final timer value 2470 eca9 20 04 ed jsr adjust ;adjust vcount value 2471 ecac 8d 10 03 sta timer2 ;save adjusted value 2472 ecaf ad 0c 03 lda timer1 2473 ecb2 20 04 ed jsr adjust ;adjust 2474 ecb5 8d 0c 03 sta timer1 ;save adjusted timer1 value 2475 ecb8 ad 10 03 lda timer2 2476 ecbb 38 sec 2477 ecbc ed 0c 03 sbc timer1 2478 ecbf 8d 12 03 sta temp1 ;find vcount difference 2479 ecc2 ad 11 03 lda timer2+1 2480 ecc5 38 sec 2481 ecc6 ed 0d 03 sbc timer1+1 2482 ecc9 a8 tay ;find vblank count difference 2483 .if PALFLG 2484 lda #-$9c 2485 hitimr: clc 2486 adc #$9c 2487 .endif 2488 .if PALFLG-1 2489 ecca a9 7d lda #-$83 2490 eccc 18 hitimr: clc \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 56 2491 eccd 69 83 adc #$83 ;accumulate multiplication 2492 .endif 2493 eccf 88 dey 2494 ecd0 10 fa bpl hitimr ;done? 2495 ecd2 18 clc 2496 ecd3 6d 12 03 adc temp1 ;total vcount difference 2497 ecd6 a8 findx: tay ;save accum 2498 ecd7 4a lsr a 2499 ecd8 4a lsr a 2500 ecd9 4a lsr a 2501 ecda 0a asl a 2502 ecdb 38 sec 2503 ecdc e9 16 sbc #22 ;adjust table index 2504 ecde aa tax ;divide interval by 4 to get table index 2505 ecdf 98 tya ;restore accum 2506 ece0 29 07 and #7 2507 ece2 a8 tay ;pull off 3 lo bits of interval 2508 ece3 a9 f5 lda #-11 2509 ece5 18 dointp: clc 2510 ece6 69 0b adc #11 ;accumulate interpolation constant 2511 ece8 88 dey 2512 ece9 10 fa bpl dointp ;interpolation constant computation done? 2513 ; 2514 eceb a0 00 enintp: ldy #0 2515 eced 8c 0e 03 sty addcor ;clear addition correction flag 2516 ecf0 38 sec 2517 ecf1 e9 07 sbc #7 ;adjust interpolation constant 2518 ecf3 10 03 bpl plus 2519 ecf5 ce 0e 03 dec addcor 2520 ecf8 18 plus: clc 2521 ecf9 7d d0 ed adc poktab,x ;add constant to lo byte table value 2522 ecfc a8 tay ;lo byte POKEY freq value 2523 ecfd ad 0e 03 lda addcor 2524 ed00 7d d1 ed adc poktab+1,x ;add carry to hi byte table value 2525 ; hi byte POKEY freq value 2526 ed03 60 rts 2527 ; 2528 ; 2529 ; 2530 ; routine to adjust vcount value 2531 ; 2532 ed04 c9 7c adjust: cmp #$7c 2533 ed06 30 04 bmi adj1 ;larger than '7c' ? 2534 ed08 38 sec ;yes, 2535 ed09 e9 7c sbc #$7c 2536 ed0b 60 rts 2537 ed0c 18 adj1: clc 2538 .if PALFLG 2539 adc #$20 2540 .endif 2541 .if PALFLG-1 2542 ed0d 69 07 adc #$7 2543 .endif 2544 ed0f 60 rts \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 57 2545 ; 2546 ; 2547 ; 2548 ; 2549 ; 2550 ; 2551 ; 2552 ; initial baud rate measurement -- used to set the 2553 ; baud rate at the start of a record. 2554 ; 2555 ; it is assumed that the first two bytes of every 2556 ; record are 'aa' hex. 2557 ; 2558 ed10 a5 11 begin: lda brkkey 2559 ed12 d0 03 bne ntbrk2 2560 ed14 4c a0 ed jmp broke ;jump if break key pressed 2561 ; 2562 ed17 78 ntbrk2: sei 2563 ; 2564 ed18 ad 17 03 lda timflg 2565 ed1b d0 02 bne oktim1 ;branch if not timed out 2566 ed1d f0 25 beq tout1 ;branch if time out 2567 ; 2568 ed1f ad 0f d2 oktim1: lda skstat 2569 ed22 29 10 and #$10 ;read serial port 2570 ed24 d0 ea bne begin ;start bit? 2571 ed26 8d 16 03 sta savio ;save ser. data in 2572 ed29 ae 0b d4 ldx vcount ;read vertical line counter 2573 ed2c a4 14 ldy rtclok+2 ;read lo byte of vblank clock 2574 ed2e 8e 0c 03 stx timer1 2575 ed31 8c 0d 03 sty timer1+1 ;save initial timer value 2576 ; 2577 ed34 a2 01 ldx #1 ;set mode flag 2578 ed36 8e 15 03 stx temp3 2579 ed39 a0 0a ldy #10 ;set bit counter for 10 bits 2580 ed3b a5 11 count: lda brkkey 2581 ed3d f0 61 beq broke ;branch if break key pressed 2582 ; 2583 ed3f ad 17 03 lda timflg 2584 ed42 d0 04 bne oktimr ;branch if not timed out 2585 ed44 58 tout1: cli 2586 ed45 4c 0a eb jmp tout ;branch if time out 2587 ; 2588 ed48 ad 0f d2 oktimr: lda skstat 2589 ed4b 29 10 and #$10 ;read serial port 2590 ed4d cd 16 03 cmp savio ;data in changed yet? 2591 ed50 f0 e9 beq count 2592 ed52 8d 16 03 sta savio ;yes,save ser. data in 2593 ed55 88 dey ;decr. bit counter 2594 ed56 d0 e3 bne count ;done? 2595 ; 2596 ed58 ce 15 03 dec temp3 ;yes, 2597 ed5b 30 12 bmi goread ;done with both modes? 2598 ed5d ad 0b d4 lda vcount \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 58 2599 ed60 a4 14 ldy rtclok+2 ;read timer lo & hi bytes 2600 ed62 20 a3 ec jsr comput ;no, compute baud rate 2601 ed65 8c ee 02 sty cbaudl 2602 ed68 8d ef 02 sta cbaudh ;set baud rate into RAM cells 2603 ed6b a0 09 ldy #9 ;set bit counter for 9 bits 2604 ed6d d0 cc bne count 2605 ; 2606 ed6f ad ee 02 goread: lda cbaudl 2607 ed72 8d 04 d2 sta audf3 2608 ed75 ad ef 02 lda cbaudh 2609 ed78 8d 06 d2 sta audf4 ;set POKEY freq regs for baud rate 2610 ed7b a9 00 lda #0 2611 ed7d 8d 0f d2 sta skstat 2612 ed80 ad 32 02 lda sskctl 2613 ed83 8d 0f d2 sta skstat ;init. POKEY serial port 2614 ed86 a9 55 lda #$55 2615 ed88 91 32 sta (bufrlo),y ;store '$55' as first rcv. buffer 2616 ed8a c8 iny 2617 ed8b 91 32 sta (bufrlo),y 2618 ed8d a9 aa lda #$aa 2619 ed8f 85 31 sta chksum ;store checksum for 2 bytes of '$aa' 2620 ed91 18 clc 2621 ed92 a5 32 lda bufrlo 2622 ed94 69 02 adc #2 2623 ed96 85 32 sta bufrlo 2624 ed98 a5 33 lda bufrhi 2625 ed9a 69 00 adc #0 2626 ed9c 85 33 sta bufrhi ;incr. buffer pointer by 1 2627 ed9e 58 cli 2628 ed9f 60 rts 2629 ; 2630 ; 2631 ; 2632 eda0 20 5f ec broke: jsr sendds ;break key was pressed, so prepare 2633 eda3 a9 3c lda #motrst ;to return 2634 eda5 8d 02 d3 sta pactl ;turn off motor 2635 eda8 8d 03 d3 sta pbctl ;raise not command line 2636 ; 2637 edab a9 80 lda #brkabt 2638 edad 85 30 sta status ;store break abort status code 2639 ; 2640 edaf ae 18 03 ldx stackp 2641 edb2 9a txs ;restore stack pointer 2642 ; 2643 edb3 c6 11 dec brkkey ;set break key flag to nonzero 2644 edb5 58 cli ;allow IRQ's 2645 ; 2646 edb6 4c 0d ea jmp return ;go return 2647 ; 2648 ; 2649 ; 2650 ; 2651 ; 2652 edb9 a9 ec setvbx: lda #jtadrl ;store time out routine address \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 59 2653 edbb 8d 26 02 sta cdtma1 2654 edbe a9 eb lda #jtadrh 2655 edc0 8d 27 02 sta cdtma1+1 2656 ; 2657 edc3 a9 01 lda #1 ;set for timer 1 2658 ; 2659 edc5 78 sei ;the setvbl routine needs this to cut short 2660 edc6 20 5c e4 jsr setvbv ;any vblanks that occur 2661 edc9 a9 01 lda #1 ;set for timer 1 2662 edcb 8d 17 03 sta timflg ;set flag to not timed out 2663 edce 58 cli 2664 edcf 60 rts 2665 ; 2666 ; 2667 ; 2668 ; 2669 ; 2670 ; 2671 ; 2672 ; 'vcount' interval timer measurement -- to -- POKEY freq reg value 2673 ; conversion table 2674 ; 2675 ; 2676 ; the values stored in the table are 'audf+7'. 2677 ; 2678 ; the following formulas were used to determine the table values: 2679 ; 2680 ; f out= f in/(2*(audf+m)) , where f in=1.78979 mhz. & m=7 2681 ; 2682 ; from this was derived the formula used to compute the 2683 ; table values based on a measurenent of the period by 2684 ; an interval of the 'vcount' timer. 2685 ; 2686 ; audf+7=(11.365167)*t out, where t out=# of counts 2687 ; (127 usec.resolution) of 'vcount' for 1 2688 ; character time (10 bit times). 2689 ; 2690 ; 2691 ; 2692 ; 2693 ; audf+7 baud rate vcount interval 2694 ; ------ ----------- ---------------- 2695 ; .word $27c ;1407 56 2696 ; .word $2d7 ;1231 64 2697 ; .word $332 ;1094 72 2698 ; .word $38d ;985 80 2699 edd0 e8 03 poktab: .word $3e8 ;895 88 2700 edd2 43 04 .word $443 ;820 96 2701 edd4 9e 04 .word $49e ;757 104 2702 edd6 f9 04 .word $4f9 ;703 112 2703 edd8 54 05 .word $554 ;656 120 2704 edda af 05 .word $5af ;615 128 2705 eddc 0a 06 .word $60a ;579 136 2706 edde 65 06 .word $665 ;547 144 \newpage err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 60 2707 ede0 c0 06 .word $6c0 ;518 152 2708 ede2 1a 07 .word $71a ;492 160 2709 ede4 75 07 .word $775 ;469 168 2710 ede6 d0 07 .word $7d0 ;447 176 2711 ; .word $82b ;428 184 2712 ; .word $886 ;410 192 2713 ; .word $8e1 ;394 200 2714 ; .word $93c ;379 208 2715 ; .word $997 ;365 216 2716 ; .word $9f2 ;352 224 2717 ; .word $a4d ;339 232 2718 ; .word $aa8 ;328 240 2719 ; .word $b03 ;318 248 2720 ; 2721 ; 2722 ; 2723 ; 2724 ;*********************************************************************** 2725 ede8 crntp3 =* 2726 *=$14 2727 0014 02 siospr: .byte dskorg-crntp3 ;^gsiol is too long \newfile err line addr b1 b2 b3 b4 SIO ( serial bus input/output controller ) page 61 2728 2729 .title 'disk ***** diskp.src ***** 3/9/79 ***** 4:00:00 P.M.' 2730 ; 2731 ; 2732 ; 2733 ; 2734 ; 2735 ; 2736 0002 statvh = dvstat/256 2737 00ea statvl = (-256)*statvh+dvstat ;status pointer 2738 ; 2739 ; 2740 ; 2741 ; 2742 ; constant equates 2743 ; 2744 0031 diskid = $31 ;serial bus disk i.d. 2745 0050 putsec = $50 ;disk put sector DCB command 2746 ; read = $52 ;disk get sector DCB command 2747 ; write = $57 ;disk put sector with read check DCB command 2748 0053 statc = $53 ;disk status DCB command 2749 0021 fomat = $21 ;disk format DCB command !!!!! ***** 2750 0000 nodat = 0 ;SIO command for "no data" operation 2751 0040 getdat = $40 ;SIO command for "data from device" 2752 0080 putdat = $80 ;SIO command for "data to device" 2753 ; 2754 ; 2755 ; vectors 2756 ; 2757 *=$e450 2758 ; 2759 e450 4c ea ed jmp dinit ;disk init. vector 2760 e453 4c f0 ed jmp dskif ;disk interface entry point 2761 ; 2762 ; 2763 ; 2764 ; 2765 ; 2766 ; 2767 ; constants 2768 ; 2769 *=dskorg 2770 ; 2771 ; 2772 ; 2773 ; 2774 ; 2775 ; 2776 ; 2777 ; 2778 ; 2779 ;*********************************************************************** 2780 ; disk interface routine starts here 2781 ;*********************************************************************** \newpage err line addr b1 b2 b3 b4 disk ***** diskp.src ***** 3/9/79 ***** 4:00:00 page 62 2782 ; 2783 ; 2784 ; 2785 ; 2786 ; disk interface initialization routine 2787 ; 2788 edea a9 a0 dinit: lda #160 2789 edec 8d 46 02 sta dsktim ;set initial disk timeout to 160 sec 2790 edef 60 rts 2791 ; 2792 ; 2793 ; 2794 ; disk interface entry point 2795 ; 2796 edf0 a9 31 dskif: lda #diskid 2797 edf2 8d 00 03 sta ddevic ;set serial bus i.d in DCB 2798 edf5 ad 46 02 lda dsktim 2799 edf8 ae 02 03 ldx dcomnd 2800 edfb e0 21 cpx #fomat ;is command a format command? 2801 edfd f0 02 beq putdto 2802 edff a9 07 lda #7 ;no, set timeout to 7 secs. 2803 ee01 8d 06 03 putdto: sta dtimlo ;put disk timeout in DCB 2804 ee04 a2 40 ldx #getdat ;set "get data" command for SIO 2805 ee06 a0 80 ldy #$80 ;set byte count to 128 2806 ee08 ad 02 03 lda dcomnd ;read command in DCB 2807 ee0b c9 57 cmp #write ;is command a "put sector" command? 2808 ee0d d0 02 bne ckstc 2809 ee0f a2 80 ldx #putdat ;yes, set "put data" command for SIO 2810 ee11 c9 53 ckstc: cmp #statc ;is command a status command? 2811 ee13 d0 0c bne putcnt 2812 ee15 a9 ea lda #statvl 2813 ee17 8d 04 03 sta dbuflo 2814 ee1a a9 02 lda #statvh 2815 ee1c 8d 05 03 sta dbufhi ;set buffer addr to global status buffer 2816 ee1f a0 04 ldy #4 ;yes, set byte count to 4 2817 ee21 8e 03 03 putcnt: stx dstats ;put status command for SIO in DCB 2818 ee24 8c 08 03 sty dbytlo 2819 ee27 a9 00 lda #0 2820 ee29 8d 09 03 sta dbythi ;put byte count in DCB 2821 ee2c 20 59 e4 jsr siov ;call serial I/O. 2822 ee2f 10 01 bpl goodst ;no error 2823 ee31 60 rts ;no, go back 2824 ee32 ad 02 03 goodst: lda dcomnd ;read the command 2825 ee35 c9 53 cmp #statc ;was it a status command? 2826 ee37 d0 0a bne putbc 2827 ee39 20 6d ee jsr putadr ;put buffer addr in temp reg. 2828 ee3c a0 02 ldy #2 2829 ee3e b1 15 lda (bufadr),y ;read disk timeout value byte of status 2830 ee40 8d 46 02 sta dsktim ;put it in disk timeout reg. 2831 ee43 ad 02 03 putbc: lda dcomnd 2832 ee46 c9 21 cmp #fomat ;was command a format command? 2833 ee48 d0 1f bne enddif 2834 ee4a 20 6d ee fmtd: jsr putadr ;yes, put buffer addr into temp reg 2835 ee4d a0 fe ldy #$fe ;set buffer pointer \newpage err line addr b1 b2 b3 b4 disk ***** diskp.src ***** 3/9/79 ***** 4:00:00 page 63 2836 ee4f c8 twice: iny 2837 ee50 c8 iny ;incr buffer pointer by 2 2838 ee51 b1 15 rdbad: lda (bufadr),y ;read lo byte bad sector data 2839 ee53 c9 ff cmp #$ff 2840 ee55 d0 f8 bne twice ;is it "ff" ? 2841 ee57 c8 iny ;yes, 2842 ee58 b1 15 lda (bufadr),y ;read hi byte bad sector data 2843 ee5a c8 iny 2844 ee5b c9 ff cmp #$ff 2845 ee5d d0 f2 bne rdbad ;is it "ff" ? 2846 ee5f 88 dey 2847 ee60 88 dey ;yes, 2848 ee61 8c 08 03 sty dbytlo ;put bad sector byte count into DCB 2849 ee64 a9 00 lda #0 2850 ee66 8d 09 03 sta dbythi 2851 ee69 ac 03 03 enddif: ldy dstats 2852 ee6c 60 rts 2853 ; 2854 ; 2855 ; 2856 ; 2857 ; S U B R O U T I N E S 2858 ; 2859 ; 2860 ; put buffer addr from DCB into temp reg 2861 ; 2862 ee6d ad 04 03 putadr: lda dbuflo 2863 ee70 85 15 sta bufadr 2864 ee72 ad 05 03 lda dbufhi 2865 ee75 85 16 sta bufadr+1 ;put buffer addr in temp reg 2866 ee77 60 rts 2867 ;**************************************************************** 2868 ; 2869 ; 2870 ; spare byte or module too long flag 2871 ; 2872 ee78 crntp4 = * 2873 ; 2874 *=$14 2875 0014 00 dskspr: .byte prnorg-crntp4 ;^gdiskp too long 2876 ; \newfile err line addr b1 b2 b3 b4 disk ***** diskp.src ***** 3/9/79 ***** 4:00:00 page 64 2877 .page 2878 .title 'printer ***** printp.src ***** 3/9/79 ***** 4:00:00 P 2879 ; 2880 ; 2881 ; 2882 ; 2883 ; 2884 ; 2885 ; 2886 ; 2887 ; 2888 ; 2889 ; 2890 ; device number or code equates 2891 ; 2892 0002 opnout = $2 ;IOCB open for output command 2893 0028 nbufsz = 40 ;print normal buffer size 2894 0014 dbufsz = 20 ;print double bufffer size 2895 001d sbufsz = 29 ;print sideways buffer size 2896 0040 pdevn = $40 ;printer device number 2897 ; statc = $53 ;DCB status command code 2898 0057 writec = $57 ;DCB write command 2899 0020 space = $20 ;ascii space char. 2900 004e n = $4e ;ascii "N" char. 2901 0044 d = $44 ;ascii "D" char. 2902 0053 s = $53 ;ascii "S" char. 2903 ; 2904 ; 2905 ; printer handler entry points 2906 ; 2907 ; 2908 ; 2909 ; 2910 *=$e430 2911 ; 2912 e430 9e ee .word phopen-1 ;printer handler open 2913 e432 db ee .word phclos-1 ;ph close 2914 e434 9d ee .word badst-1 ;ph read 2915 e436 a6 ee .word phwrit-1 ;ph write 2916 e438 80 ee .word phstat-1 ;ph status 2917 e43a 9d ee .word badst-1 ;ph special 2918 e43c 4c 78 ee jmp phinit ;ph init. 2919 e43f 00 .byte 0 ;ROM filler 2920 ; 2921 ; 2922 ; 2923 ; 2924 ; 2925 *=prnorg 2926 ; 2927 ; 2928 ; 2929 ; 2930 ; printer handler initialization routine \newpage err line addr b1 b2 b3 b4 printer ***** printp.src ***** 3/9/79 ***** 4:00 page 65 2931 ; 2932 ee78 a9 1e phinit: lda #30 2933 ee7a 85 1c sta ptimot ;set up initial printer timeout of 30 sec. 2934 ee7c 60 rts 2935 ; 2936 ; 2937 ; printer handler constants 2938 ; 2939 ee7d ea 02 phstlo: .word dvstat ;status buffer pointer 2940 ee7f c0 03 phchlo: .word prnbuf ;char. buffer pointer 2941 ; 2942 ; 2943 ; 2944 ; ************************ 2945 ; printer handler routines 2946 ; ************************ 2947 ; 2948 ; 2949 ; 2950 ; 2951 ; 2952 ; printer handler status routine 2953 ; 2954 ee81 a9 04 phstat: lda #4 2955 ee83 85 1e sta pbufsz ;set buffer size to 4 bytes 2956 ee85 ae 7d ee ldx phstlo 2957 ee88 ac 7e ee ldy phstlo+1 ;set pointer to status buffer 2958 ee8b a9 53 lda #statc ;set command to "status" 2959 ee8d 8d 02 03 sta dcomnd ;set status command 2960 ee90 8d 0a 03 sta daux1 2961 ee93 20 e6 ee jsr setdcb ;go setup DCB 2962 ee96 20 59 e4 jsr siov ;send status command 2963 ee99 30 03 bmi badst ;go if error 2964 ee9b 20 14 ef jsr phput ;yes,put status into global buffer. 2965 ee9e 60 badst: rts 2966 ; 2967 ; 2968 ; 2969 ; 2970 ; printer handler open routine 2971 ; 2972 ee9f 20 81 ee phopen: jsr phstat ;do status command to SIO 2973 eea2 a9 00 lda #0 2974 eea4 85 1d sta pbpnt ;clear print buffer pointer 2975 eea6 60 rts 2976 ; 2977 ; 2978 ; 2979 ; 2980 ; printer handler write routine 2981 ; 2982 eea7 85 1f phwrit: sta ptemp ;save accum 2983 eea9 20 1a ef jsr prmode ;go determine print mode 2984 eeac a6 1d ldx pbpnt \newpage err line addr b1 b2 b3 b4 printer ***** printp.src ***** 3/9/79 ***** 4:00 page 66 2985 eeae a5 1f lda ptemp ;get char. sent by CIO 2986 eeb0 9d c0 03 sta prnbuf,x ;put char. in print buffer 2987 eeb3 e8 inx ;incr. buffer pointer 2988 eeb4 e4 1e cpx pbufsz ;buffer pointer=buffer size? 2989 eeb6 f0 13 beq bufful 2990 eeb8 86 1d stx pbpnt ;save buffer pointer 2991 eeba c9 9b cmp #CR ;is char. = EOL ? 2992 eebc f0 03 beq blfill ;if yes, go do blank fill. 2993 eebe a0 01 ldy #succes ;put good status in Y reg for CIO. 2994 eec0 60 rts 2995 eec1 a9 20 blfill: lda #space ;put blank in accum. 2996 eec3 9d c0 03 fillbf: sta prnbuf,x ;store it in print buffer. 2997 eec6 e8 inx 2998 eec7 e4 1e cpx pbufsz 2999 eec9 d0 f8 bne fillbf ;buffer blank filled? 3000 eecb a9 00 bufful: lda #0 3001 eecd 85 1d sta pbpnt ;clear print buffer pointer 3002 eecf ae 7f ee ldx phchlo 3003 eed2 ac 80 ee ldy phchlo+1 ;set pointer to print buffer 3004 eed5 20 e6 ee jsr setdcb ;go setup DCB 3005 eed8 20 59 e4 jsr siov ;send print command 3006 eedb 60 rts ;yes. 3007 ; 3008 ; 3009 ; 3010 ; 3011 ; printer handler close routine 3012 ; 3013 eedc 20 1a ef phclos: jsr prmode ;go determine print mode 3014 eedf a6 1d ldx pbpnt 3015 eee1 d0 de bne blfill 3016 eee3 a0 01 ldy #succes 3017 eee5 60 rts 3018 ; 3019 ; 3020 ; 3021 ; 3022 ; 3023 ; 3024 ; 3025 ; 3026 ; S U B R O U T I N E S 3027 ; 3028 ; 3029 ; 3030 ; 3031 ; 3032 ; set up DCB to call SIO 3033 ; 3034 eee6 8e 04 03 setdcb: stx dbuflo 3035 eee9 8c 05 03 sty dbufhi ;set buffer pointer 3036 eeec a9 40 lda #pdevn 3037 eeee 8d 00 03 sta ddevic ;set printer bus i.d. for DCB 3038 eef1 a9 01 lda #1 \newpage err line addr b1 b2 b3 b4 printer ***** printp.src ***** 3/9/79 ***** 4:00 page 67 3039 eef3 8d 01 03 sta dunit ;set unit number to 1 3040 eef6 a9 80 lda #$80 ;device will expect data 3041 eef8 ae 02 03 ldx dcomnd 3042 eefb e0 53 cpx #statc ;status command? 3043 eefd d0 02 bne psioc 3044 eeff a9 40 lda #$40 ;expect data from device 3045 ef01 8d 03 03 psioc: sta dstats ;set SIO mode command. 3046 ef04 a5 1e lda pbufsz 3047 ef06 8d 08 03 sta dbytlo ;set lo byte count 3048 ef09 a9 00 lda #0 3049 ef0b 8d 09 03 sta dbythi ;set hi byte count 3050 ef0e a5 1c lda ptimot 3051 ef10 8d 06 03 sta dtimlo ;set device timeout count 3052 ef13 60 rts 3053 ; 3054 ; 3055 ; 3056 ; 3057 ; get device timeout from status & save it 3058 ; 3059 ef14 ad ec 02 phput: lda dvstat+2 3060 ef17 85 1c sta ptimot ;save device timeout 3061 ef19 60 rts 3062 ; 3063 ; 3064 ; 3065 ; 3066 ; determine print mode & setup print buffer size, DCB print 3067 ; command, & DCB aux1 for print mode 3068 ; 3069 ef1a a0 57 prmode: ldy #writec ;put write command in Y reg 3070 ef1c a5 2b lda icax2z ;read print mode 3071 ef1e c9 4e cmode: cmp #n 3072 ef20 d0 04 bne cdubl ;print normal ? 3073 ef22 a2 28 ldx #nbufsz ;yes, set normal char. buffer size 3074 ef24 d0 0e bne setbsz 3075 ef26 c9 44 cdubl: cmp #d 3076 ef28 d0 04 bne cside ;print double? 3077 ef2a a2 14 ldx #dbufsz ;yes, set double char. buffer size 3078 ef2c d0 06 bne setbsz 3079 ef2e c9 53 cside: cmp #s ;print sideways ? 3080 ef30 d0 0b bne goerr ;if not, go to error routine 3081 ef32 a2 1d ldx #sbufsz ;yes, set sideways buffer size 3082 ef34 86 1e setbsz: stx pbufsz ;store print buffer size 3083 ef36 8c 02 03 sty dcomnd ;store DCB command 3084 ef39 8d 0a 03 sta daux1 ;store DCB aux1 print mode 3085 ef3c 60 rts 3086 ef3d a9 4e goerr: lda #n ;set default print mode to normal 3087 ef3f d0 dd bne cmode 3088 ;************************************************************* 3089 ; 3090 ; 3091 ; spare byte or module too long flag 3092 ; \newpage err line addr b1 b2 b3 b4 printer ***** printp.src ***** 3/9/79 ***** 4:00 page 68 3093 ef41 crntp5 = * 3094 ; 3095 *=$14 3096 ; 3097 0014 00 prnspr: .byte casorg-crntp5 ;^gprintp too long 3098 ; \newfile err line addr b1 b2 b3 b4 printer ***** printp.src ***** 3/9/79 ***** 4:00 page 69 3099 .page 3100 .title 'casset handler 3/12 (dk1:cascv)' 3101 0003 cbufh = casbuf/256 3102 00fd cbufl = (-256)*cbufh+casbuf 3103 0040 srsta = $40 ;SIO read status 3104 0080 swsta = $80 ;SIO write status 3105 ;motrgo = $34 3106 ;motrst = $3c 3107 ; 3108 ; 3109 00fc dta = $fc ;data record type byte 3110 00fa dt1 = $fa ;last data record 3111 00fe EOT = $fe ;end of tape 3112 00fb hdr = $fb ;header 3113 0002 tone1 = 2 ;change to record mode tone 3114 0001 tone2 = 1 ;press play tone 3115 ; 3116 ; 3117 ; 3118 *=casetv 3119 e440 4b ef 2a f0 .word openc-1,closec-1,gbyte-1,pbyte-1,statu-1,special-1 3120 e444 d5 ef 0f f0 3121 e448 27 f0 4a ef 3122 e44c 4c 41 ef jmp init 3123 e44f 00 .byte 0 ;ROM filler byte 3124 ; 3125 ; 3126 ; 3127 ; used in monitp for cassette boot 3128 ; 3129 *=rblokv 3130 e47a 4c e9 ef jmp rblok 3131 ; 3132 *=csopiv 3133 e47d 4c 5d ef jmp opinp 3134 ; 3135 ; 3136 *=casorg 3137 ; 3138 ; 3139 ; init routine 3140 ; 3141 ef41 a9 cc init: lda #$cc 3142 ef43 8d ee 02 sta cbaudl 3143 ef46 a9 05 lda #$05 3144 ef48 8d ef 02 sta cbaudh ;set casset baud rate to 600 3145 special: ;thats all folks 3146 ef4b 60 rts \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 70 3147 .page 3148 ; 3149 ; open function - with no timing adjust 3150 ; 3151 ef4c a5 2b openc: lda icax2z ;get ax2 3152 ef4e 85 3e sta ftype ;save it for future reference 3153 ef50 a5 2a lda icax1z 3154 ef52 29 0c and #$0c ;in and out bits 3155 ef54 c9 04 cmp #$04 3156 ef56 f0 05 beq opinp 3157 ef58 c9 08 cmp #$08 ;see if open for output 3158 ef5a f0 39 beq opout 3159 ef5c 60 rts ;if already open, return leaving status=$84 3160 ef5d a9 00 opinp: lda #0 3161 ef5f 8d 89 02 sta wmode ;set read mode 3162 ef62 85 3f sta feof ;no EOF yet 3163 ef64 a9 01 sfh: lda #tone2 ;tone for press play 3164 ef66 20 58 f0 jsr beep ;go beep 3165 ef69 30 24 bmi opnrtn ;if error during beep 3166 ef6b a9 34 lda #motrgo 3167 ef6d 8d 02 d3 sta pactl ;turn motor on 3168 .if PALFLG 3169 ldy #$e0 3170 ldx #1 3171 .endif 3172 .if PALFLG-1 3173 ef70 a0 40 ldy #$40 ;5-31-79 9 sec read leader 3174 ef72 a2 02 ldx #2 3175 .endif 3176 ef74 a9 03 lda #3 3177 ef76 8d 2a 02 sta cdtmf3 3178 ef79 20 5c e4 jsr setvbv ;set up vblank timer 3179 ef7c ad 2a 02 waittm: lda cdtmf3 3180 ef7f d0 fb bne waittm ;wait for motor to come up to speed 3181 ef81 a9 80 lda #$80 ;next byte=no bytes in buffer 3182 ef83 85 3d sta bptr 3183 ef85 8d 8a 02 sta blim 3184 ef88 4c d3 ef jmp opok ;open ok 3185 ; 3186 ; open for output 3187 ; 3188 ef8b a0 80 pbrk: ldy #brkabt ;break key abort status 3189 ef8d c6 11 dec brkkey ;reset break key 3190 ef8f a9 00 opnrtn: lda #0 ;clear write mode flag 3191 ef91 8d 89 02 sta wmode 3192 ef94 60 rts ;and exit. 3193 ; 3194 ef95 a9 80 opout: lda #$80 3195 ef97 8d 89 02 sta wmode ;set write mode 3196 ef9a a9 02 lda #tone1 ;tell user to turn on record mode 3197 ef9c 20 58 f0 jsr beep 3198 ef9f 30 ee bmi opnrtn ;if error during beep 3199 efa1 a9 cc lda #$cc ;set baud rate 3200 efa3 8d 04 d2 sta audf3 ;which seems to be nessecary \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 71 3201 efa6 a9 05 lda #$05 ;for some obscure reason 3202 efa8 8d 06 d2 sta audf4 3203 efab a9 60 lda #$60 3204 efad 8d 00 03 sta ddevic 3205 efb0 20 68 e4 jsr sendev ;tell POKEY to write marks 3206 efb3 a9 34 lda #motrgo ;write 5 sec blank tape 3207 efb5 8d 02 d3 sta pactl 3208 efb8 a9 03 lda #3 3209 .if PALFLG 3210 ldx #$3 3211 ldy #$c0 3212 .endif 3213 .if PALFLG-1 3214 efba a2 04 ldx #4 ;5/30/79 20 sec leader 3215 efbc a0 80 ldy #$80 3216 .endif 3217 efbe 20 5c e4 jsr setvbv 3218 efc1 a9 ff lda #$ff 3219 efc3 8d 2a 02 sta cdtmf3 3220 efc6 a5 11 wdlr: lda brkkey 3221 efc8 f0 c1 beq pbrk ;if break during write leader 3222 efca ad 2a 02 lda cdtmf3 3223 efcd d0 f7 bne wdlr 3224 efcf a9 00 lda #0 ;init buffer pointer 3225 efd1 85 3d sta bptr 3226 efd3 a0 01 opok: ldy #succes 3227 efd5 60 rts \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 72 3228 .page 3229 ; 3230 ; get byte 3231 ; 3232 efd6 a5 3f gbyte: lda feof ;if at EOF already 3233 efd8 30 33 bmi iseof ;return EOF status 3234 efda a6 3d ldx bptr ;buffer pointer 3235 efdc ec 8a 02 cpx blim ;if end of buffer 3236 efdf f0 08 beq rblok ;read another block 3237 efe1 bd 00 04 lda casbuf+3,x ;get next byte 3238 efe4 e6 3d inc bptr ;bump pointer 3239 efe6 a0 01 ldy #succes ;ok status 3240 efe8 60 gbx: rts 3241 efe9 a9 52 rblok: lda #'R ;read opcode 3242 efeb 20 95 f0 jsr siosb ;SIO on sys buf 3243 efee 98 tya 3244 efef 30 f7 bmi gbx ;if SIO errors, return 3245 eff1 a9 00 lda #0 3246 eff3 85 3d sta bptr ;reset pointer 3247 eff5 a2 80 ldx #$80 ;default # bytes 3248 eff7 ad ff 03 lda casbuf+2 3249 effa c9 fe cmp #EOT 3250 effc f0 0d beq ateof ;if header, go read again 3251 effe c9 fa cmp #dt1 ;if last data rec 3252 f000 d0 03 bne nlr 3253 f002 ae 7f 04 ldx casbuf+130 ;last data record, get # bytes 3254 f005 8e 8a 02 nlr: stx blim 3255 f008 4c d6 ef jmp gbyte ;get next byte 3256 f00b c6 3f ateof: dec feof ;set feof 3257 f00d a0 88 iseof: ldy #eoferr ;endfile status 3258 f00f 60 rts \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 73 3259 .page 3260 ; 3261 ; put byte to buffer 3262 ; 3263 f010 a6 3d pbyte: ldx bptr ;buffer pointer 3264 f012 9d 00 04 sta casbuf+3,x ;store char away 3265 f015 e6 3d inc bptr ;bump pointer 3266 f017 a0 01 ldy #succes ;ok status 3267 f019 e0 7f cpx #127 ;if buffer full 3268 f01b f0 01 beq *+3 3269 f01d 60 rts 3270 ; write out the buffer 3271 f01e a9 fc lda #dta ;record type = data 3272 f020 20 d2 f0 jsr wsiosb ;do write on system buffer 3273 f023 a9 00 lda #0 3274 f025 85 3d sta bptr ;reset buffer pointer 3275 f027 60 rts ;exit. \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 74 3276 .page 3277 ; 3278 ; status - return status info thru dvstat 3279 ; 3280 f028 a0 01 statu: ldy #succes 3281 f02a 60 rts \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 75 3282 .page 3283 ; 3284 ; close 3285 ; 3286 f02b ad 89 02 closec: lda wmode ;see if writing 3287 f02e 30 08 bmi clwrt ;go close for write 3288 ; close for read - flag closed 3289 f030 a0 01 ldy #succes ;successfull 3290 f032 a9 3c fcax: lda #motrst ;stop the motor in case was short IRG mode 3291 f034 8d 02 d3 sta pactl 3292 f037 60 rts 3293 f038 a6 3d clwrt: ldx bptr ;buffer pointer 3294 f03a f0 0a beq wtlr ;if no data bytes in buffer, no dt1 rec 3295 f03c 8e 7f 04 stx casbuf+130 ;write to last record 3296 f03f a9 fa lda #dt1 ;rec type 3297 f041 20 d2 f0 jsr wsiosb ;write out user buffer 3298 f044 30 ec bmi fcax ;go if error 3299 f046 a2 7f wtlr: ldx #127 ;zero buffer 3300 f048 a9 00 lda #0 3301 f04a 9d 00 04 ztbuf: sta casbuf+3,x 3302 f04d ca dex 3303 f04e 10 fa bpl ztbuf 3304 f050 a9 fe lda #EOT ;write EOT record 3305 f052 20 d2 f0 jsr wsiosb 3306 f055 4c 32 f0 jmp fcax ;flag closed and exit \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 76 3307 .page 3308 ; 3309 ; subroutines 3310 ; 3311 ; beep - generate tone on keyboard speaker 3312 ; on entry A= freq 3313 ; 3314 f058 85 40 beep: sta freq 3315 f05a a5 14 beep1: lda rtclok+2 ;current clock 3316 f05c 18 clc 3317 .if PALFLG 3318 adc #25 3319 .endif 3320 .if PALFLG-1 3321 f05d 69 1e adc #30 ;1 sec tone 3322 .endif 3323 f05f aa tax 3324 f060 a9 ff wfl: lda #$ff 3325 f062 8d 1f d0 sta consol ;turn on speaker 3326 f065 a9 00 lda #0 3327 f067 a0 f0 ldy #$f0 3328 f069 88 dey 3329 f06a d0 fd bne *-1 3330 f06c 8d 1f d0 sta consol ;turn off speaker 3331 f06f a0 f0 ldy #$f0 3332 f071 88 dey 3333 f072 d0 fd bne *-1 3334 f074 e4 14 cpx rtclok+2 ;see if 1 sec is up yet 3335 f076 d0 e8 bne wfl 3336 f078 c6 40 dec freq ;count beeps 3337 f07a f0 0b beq wfak ;if all done go wait for key 3338 f07c 8a txa 3339 f07d 18 clc 3340 .if PALFLG 3341 adc #8 3342 .endif 3343 .if PALFLG-1 3344 f07e 69 0a adc #10 3345 .endif 3346 f080 aa tax 3347 f081 e4 14 cpx rtclok+2 3348 f083 d0 fc bne *-2 3349 f085 f0 d3 beq beep1 ;uncond go beep agin 3350 f087 20 8c f0 wfak: jsr wfak1 ;use simulated "jmp (kgetch)" 3351 f08a 98 tya 3352 f08b 60 rts 3353 f08c ad 25 e4 wfak1: lda keybdv+5 3354 f08f 48 pha 3355 f090 ad 24 e4 lda keybdv+4 ;simulate "jmp (kgetch)" 3356 f093 48 pha 3357 f094 60 rts 3358 ; 3359 ; siosb - call SIO on system buffer 3360 ; \newpage err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 77 3361 f095 8d 02 03 siosb: sta dcomnd ;save command 3362 f098 a9 00 lda #0 3363 f09a 8d 09 03 sta dbythi ;set buffer length 3364 f09d a9 83 lda #131 3365 f09f 8d 08 03 sta dbytlo 3366 f0a2 a9 03 lda #cbufh 3367 f0a4 8d 05 03 sta dbufhi ;set buffer address 3368 f0a7 a9 fd lda #cbufl 3369 f0a9 8d 04 03 sta dbuflo 3370 f0ac a9 60 csio: lda #$60 ;casset pseudo device 3371 f0ae 8d 00 03 sta ddevic 3372 f0b1 a9 00 lda #0 3373 f0b3 8d 01 03 sta dunit 3374 f0b6 a9 23 lda #35 ;device timeout (5/30/79) 3375 f0b8 8d 06 03 sta dtimlo 3376 f0bb ad 02 03 lda dcomnd ;get command back 3377 f0be a0 40 ldy #srsta ;SIO read status command 3378 f0c0 c9 52 cmp #'R 3379 f0c2 f0 02 beq *+4 3380 f0c4 a0 80 ldy #swsta ;SIO write status command 3381 f0c6 8c 03 03 sty dstats ;set status for SIO 3382 f0c9 a5 3e lda ftype 3383 f0cb 8d 0b 03 sta daux2 ;indicate if short IRG mode 3384 f0ce 20 59 e4 jsr siov ;go call SIO 3385 f0d1 60 rts 3386 ; 3387 ; wsiosb write SIO system buffer 3388 ; 3389 f0d2 8d ff 03 wsiosb: sta casbuf+2 ;store type byte 3390 f0d5 a9 55 lda #$55 3391 f0d7 8d fd 03 sta casbuf+0 3392 f0da 8d fe 03 sta casbuf+1 3393 f0dd a9 57 lda #'W ;write 3394 f0df 20 95 f0 jsr siosb ;call SIO on system buffer 3395 f0e2 60 rts and ;return 3396 f0e3 crntp6 =* 3397 *=$14 3398 0014 00 casspr: .byte monorg-crntp6 ;^gcascv is too long \newfile err line addr b1 b2 b3 b4 casset handler 3/12 (dk1:cascv) page 78 3399 3400 .title 'monitor ***** monitp.src ***** 3/9/79 ***** 4:00:00 P 3401 ; 3402 ; 3403 ; 3404 ; constant equates 3405 ; 3406 0009 puttxt = $9 ;"put text record" CIO command code 3407 0007 getcar = $7 ;"get character" CIO command code 3408 000b putcar = $b ;"put character" CIO command code 3409 0000 inimll = $00 ;initial mem lo low byte 3410 0007 inimlh = $07 ;initial mem lo high byte 3411 ; good = $1 ;good status code 3412 ; write = $57 ;write command 3413 ; read = $52 ;read command 3414 ; statc = $53 ;status command 3415 0000 sex = $0 ;screen editor IOCB index 3416 007d CLS = $7D ;clear screen code 3417 0092 ctrlc = $92 ;keyboard code for 'control c' 3418 0088 EOF = $88 ;cassette end of file code 3419 0000 lirg = $0 ;long IRG type code 3420 ; 3421 0004 buffh = (casbuf+3)/256 3422 0000 buffl = (-256)*buffh+casbuf+3 ;buffer pointer 3423 ; 3424 ; 3425 ; 3426 ; the following equates are in the cartridge address space. 3427 ; 3428 ; 3429 ; "B" cartridge addr's are 8000-9fff (36k config. only) 3430 ; "A" cart. addr's are a000-bfff (36k config. only) 3431 ; 3432 ; "A" cart. addr's are b000-bfff (48k config. only) 3433 ; 3434 *=$bffa 3435 bffa cartcs: .res 2 ;cartridge cold start address. 3436 bffc cart: .res 1 ;cartridge available flag byte. 3437 bffd cartfg: .res 1 ;cartridge flag byte. bit0=flag1, 3438 bffe cartad: .res 2 ;2-byte cartridge start vector 3439 ; 3440 ; 3441 ; cartridge flag action definitions 3442 ; 3443 ; 3444 ; bit action if set 3445 ; 3446 ; 7 special -- don't power-up, just run cartridge 3447 ; 6-3 none 3448 ; 2 run cartridge 3449 ; 1 none 3450 ; 0 boot DOS 3451 ; 3452 ; \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 79 3453 ; ***** 3454 ; note 3455 ; ***** 3456 ; 3457 ; 1.if bit2 is 0, goto blackboard mode. 3458 ; 2.if bit0 set, the disk will be booted before any 3459 ; other action. 3460 ; 3461 ; 3462 ; 3463 ; 3464 ; 3465 ; 3466 ; 3467 ; 3468 ; 3469 ; power-up vector 3470 ; 3471 ;**************************** 3472 ; *=$fffc 3473 ; 3474 ; pvect .word pwrup power-up vector 3475 ;************************* 3476 ; 3477 ; 3478 ; 3479 ; 3480 ; 3481 ; entry point vector 3482 ; 3483 *=blkbdv 3484 ; 3485 e471 4c 23 f2 jmp signon ;black board vector 3486 ; 3487 *=warmsv 3488 ; 3489 e474 4c 1b f1 jmp reset ;warm start vector 3490 ; 3491 *=coldsv 3492 ; 3493 e477 4c 25 f1 jmp pwrup ;cold start vector (9000 for RAM vector writ 3494 ; 3495 *=$9000 3496 9000 20 0c 90 jsr $900c 3497 9003 4c 25 f1 jmp pwrup ;(to handle RAM vector writing) 3498 9006 20 0c 90 jsr $900c 3499 9009 4c 1b f1 jmp reset 3500 ; 3501 ; 3502 ; 3503 *=monorg 3504 ; 3505 ; 3506 ; \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 80 3507 ; 3508 ; handler table entries 3509 ; 3510 f0e3 50 tblent: .byte 'P' 3511 f0e4 30 e4 .word printv 3512 f0e6 43 .byte 'C' 3513 f0e7 40 e4 .word casetv 3514 f0e9 45 .byte 'E' 3515 f0ea 00 e4 .word editrv 3516 f0ec 53 .byte 'S' 3517 f0ed 10 e4 .word screnv 3518 f0ef 4b .byte 'K' 3519 f0f0 20 e4 .word keybdv 3520 ; 3521 ; 3522 ;tbllen = ident-tblent-1 handler table length. "moved to line 8 3523 ; 3524 ; ***** print messages ***** 3525 ; 3526 ; 3527 f0f2 7d 41 54 41 ident: .byte CLS,'ATARI COMPUTER - MEMO PAD',CR 3528 f0f6 52 49 20 43 3529 f0fa 4f 4d 50 55 3530 f0fe 54 45 52 20 3531 f102 2d 20 4d 45 3532 f106 4d 4f 20 50 3533 f10a 41 44 9b 3534 ; 3535 00f0 identh = ident/256 3536 00f2 identl = (-256)*identh+ident ;system i.d. msg pointer 3537 ; 3538 000e tbllen = ident-tblent-1 ;handler table length 3539 f10d 42 4f 4f 54 derr5: .byte 'BOOT ERROR',CR 3540 f111 20 45 52 52 3541 f115 4f 52 9b 3542 ; 3543 00f1 derrh = derr5/256 3544 000d derrl = (-256)*derrh+derr5 ;disk error msg pointer 3545 ; 3546 ; 3547 ; 3548 ; 3549 ; device/filename specifications 3550 ; 3551 f118 45 3a 9b opnedt: .byte 'E:',CR ;"open screen editor" device spec. 3552 ; 3553 00f2 opnh = opnedt/256 3554 0018 opnl =(-256)*opnh+opnedt ;screen editor open pointer 3555 f11b 3556 ; 3557 ; 3558 ; 3559 ; 3560 ;***************************************************************** \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 81 3561 ; reset button routine starts here 3562 ;***************************************************************** 3563 ; 3564 f11b 78 reset: sei ;disable IRQ interrupts 3565 f11c ad 44 02 lda coldst ;were we in middle of coldstart? 3566 f11f d0 04 bne pwrup ;yes, go try it again 3567 f121 a9 ff lda #$ff 3568 f123 d0 03 bne pwrup1 ;set warm start flag 3569 ; 3570 ; 3571 ; 3572 ;*************************************************************** 3573 ; power up routines start here 3574 ;*************************************************************** 3575 ; 3576 f125 78 pwrup: sei ;disable IRQ interrupts 3577 f126 a9 00 lda #0 ;clear warmstart flag 3578 f128 85 08 pwrup1: sta warmst 3579 f12a d8 cld ;clear decimal flag. 3580 f12b a2 ff ldx #$ff 3581 f12d 9a txs ;set stack pointer 3582 f12e 20 3f f2 jsr specl ;cartridge special case? 3583 f131 20 77 f2 jsr hardi ;do hardware initialization 3584 f134 a5 08 lda warmst ;is it warmstart? 3585 f136 d0 28 bne zosram ;yes, only zero OS RAM 3586 ; 3587 f138 a9 00 zerorm: lda #0 3588 f13a a0 08 ldy #warmst 3589 f13c 85 04 sta ramlo 3590 f13e 85 05 sta ramlo+1 ;initialize RAM pointer 3591 f140 91 04 clrram: sta (ramlo),y ;clear memory loc. 3592 f142 c8 iny 3593 f143 c0 00 cpy #0 ;at end of page? 3594 f145 d0 f9 bne clrram 3595 f147 e6 05 inc ramlo+1 ;yes, incr page pointer 3596 f149 a6 05 ldx ramlo+1 3597 f14b e4 06 cpx tramsz ;at end of mem? 3598 f14d d0 f1 bne clrram ;no. 3599 ; 3600 ; initialize dosvec to point to signon (blackboard) 3601 f14f ad 72 e4 lda blkbdv+1 3602 f152 85 0a sta dosvec ;use blackboard vector 3603 f154 ad 73 e4 lda blkbdv+2 ;for dosvec 3604 f157 85 0b sta dosvec+1 3605 f159 a9 ff lda #$ff 3606 f15b 8d 44 02 sta coldst ;set to show in middle of coldstart 3607 f15e d0 13 bne estscm ;go around zosram 3608 ; 3609 ; clear OS RAM (for warmstart) 3610 f160 a2 00 zosram: ldx #0 3611 f162 8a txa 3612 f163 9d 00 02 zosrm2: sta $200,x ;clear pages 2 and 3 3613 f166 9d 00 03 sta $300,x 3614 f169 ca dex \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 82 3615 f16a d0 f7 bne zosrm2 3616 f16c a2 10 ldx #intzbs 3617 f16e 95 00 zosrm3: sta 0,x ;clear zero page locations intzbs-7f 3618 f170 e8 inx 3619 f171 10 fb bpl zosrm3 3620 ; 3621 ; establish screen margins 3622 f173 a9 02 estscm: lda #ledge 3623 f175 85 52 sta lmargn 3624 f177 a9 27 lda #redge 3625 f179 85 53 sta rmargn 3626 ; 3627 ; 3628 ; move vector table from ROM to RAM 3629 f17b a2 25 opsys: ldx #$25 3630 f17d bd 80 e4 movvec: lda vctabl,x ;ROM table 3631 f180 9d 00 02 sta intabs,x ;to RAM 3632 f183 ca dex 3633 f184 10 f7 bpl movvec 3634 f186 20 8a f2 jsr osram ;do O.S. RAM setup 3635 f189 58 cli ;enable IRQ interrupts 3636 ; 3637 ; 3638 ; link handlers 3639 ; 3640 f18a a2 0e ldx #tbllen 3641 f18c bd e3 f0 nxtent: lda tblent,x ;read handler table entry 3642 f18f 9d 1a 03 sta hatabs,x ;put in table 3643 f192 ca dex 3644 f193 10 f7 bpl nxtent ;done with all entries? 3645 ; 3646 ; 3647 ; 3648 ; 3649 ; 3650 ; interrogate cartridge addr. space to see which cartridges there are 3651 ; 3652 f195 a2 00 ldx #0 3653 f197 86 07 stx tstdat ;clear "B" cart. flag 3654 f199 86 06 stx tramsz ;clear "A" cart. flag 3655 f19b ae e4 02 ldx ramsiz 3656 f19e e0 90 cpx #$90 ;RAM in "B" cart. slot? 3657 f1a0 b0 0a bcs endbck 3658 f1a2 ad fc 9f lda cart-$2000 ;no, 3659 f1a5 d0 05 bne endbck ;cart. plugged into "B" slot? 3660 f1a7 e6 07 inc tstdat ;yes, set "B" cart. flag 3661 f1a9 20 3c f2 jsr cbini ;initialize cartridge "B" 3662 ; 3663 f1ac ae e4 02 endbck: ldx ramsiz 3664 f1af e0 b0 cpx #$b0 ;RAM in "A" cart. slot? 3665 f1b1 b0 0a bcs endack 3666 f1b3 ae fc bf ldx cart ;no, 3667 f1b6 d0 05 bne endack ;cart. plugged into "A" slot? 3668 f1b8 e6 06 inc tramsz ;yes, set "A", cart. flag \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 83 3669 f1ba 20 39 f2 jsr caini ;initialize cartridge "A" 3670 ; 3671 ; 3672 ; open screen editor 3673 ; 3674 f1bd a9 03 endack: lda #3 3675 f1bf a2 00 ldx #sex 3676 f1c1 9d 42 03 sta iccom,x ;open I/O command 3677 f1c4 a9 18 lda #opnl 3678 f1c6 9d 44 03 sta icbal,x 3679 f1c9 a9 f1 lda #opnh 3680 f1cb 9d 45 03 sta icbah,x ;set buffer pointer to open screen editor 3681 f1ce a9 0c lda #$c 3682 f1d0 9d 4a 03 sta icax1,x ;set up open for input/output 3683 f1d3 20 56 e4 jsr ciov ;go to cio 3684 ; 3685 f1d6 10 03 bpl scrnok ;br if no error 3686 f1d8 4c 25 f1 jmp pwrup ;retry pwrup if error (should never happen!) 3687 f1db e8 scrnok: inx ;screen ok, so wait for vblank to 3688 f1dc d0 fd bne scrnok ;bring up the display 3689 f1de c8 iny 3690 f1df 10 fa bpl scrnok 3691 ; 3692 ; 3693 ; do cassette boot 3694 f1e1 20 b2 f3 jsr csboot ;check, boot, and init 3695 ; 3696 ; check to see if either cartridge wants disk boot 3697 f1e4 a5 06 lda tramsz ;check both cartridges 3698 f1e6 05 07 ora tstdat ; 3699 f1e8 f0 12 beq nocart ;neither cartridge lives 3700 f1ea a5 06 lda tramsz ;"A" cart? 3701 f1ec f0 03 beq noa1 ;no 3702 f1ee ad fd bf lda cartfg ;get cartridge mode flag 3703 f1f1 a6 07 noa1: ldx tstdat ;"B" cart? 3704 f1f3 f0 03 beq nob1 ;no 3705 f1f5 0d fd 9f ora cartfg-$2000 ;add other flag 3706 f1f8 29 01 nob1: and #1 ;does either cart want boot? 3707 f1fa f0 03 beq noboot ;no 3708 ; 3709 ; do disk boot 3710 f1fc 20 cf f2 nocart: jsr boot ;check, boot, and init 3711 ; 3712 ; go to one of the cartridges if they so desire 3713 f1ff a9 00 noboot: lda #0 3714 f201 8d 44 02 sta coldst ;reset to show done with coldstart 3715 f204 a5 06 lda tramsz ;"A" cart? 3716 f206 f0 0a beq noa2 ;no 3717 f208 ad fd bf lda cartfg ;get cartridge mode flag 3718 f20b 29 04 and #4 ;does it want to run? 3719 f20d f0 03 beq noa2 ;no 3720 f20f 6c fa bf jmp (cartcs) ;run "A" cartridge 3721 f212 a5 07 noa2: lda tstdat ;"B" cart? 3722 f214 f0 0a beq nocar2 ;no \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 84 3723 f216 ad fd 9f lda cartfg-$2000 ;get "B" mode flag 3724 f219 29 04 and #4 ;does it want to run? 3725 f21b f0 df beq nocart ;no 3726 f21d 6c fa 9f jmp (cartcs-$2000) ;run "B" cartridge 3727 ; 3728 ; no cartridges, or neither wants to run, 3729 ; so go to dosvec (DOS, cassette, or blackboard) 3730 f220 6c 0a 00 nocar2: jmp (dosvec) 3731 ; 3732 ; print sign-on nessage 3733 f223 a2 f2 signon: ldx #identl 3734 f225 a0 f0 ldy #identh 3735 f227 20 85 f3 jsr putlin ;go put sign-on msg on screen 3736 ; 3737 ; 3738 ; 3739 ; blackboard routine 3740 f22a 20 30 f2 blackb: jsr blkb2 ;"jsr egetch" 3741 f22d 4c 2a f2 jmp blackb ;forever 3742 f230 ad 05 e4 blkb2: lda editrv+5 ;high byte 3743 f233 48 pha 3744 f234 ad 04 e4 lda editrv+4 ;low byte 3745 f237 48 pha 3746 f238 60 rts ;simulates "jmp (editrv)" 3747 ; 3748 ; 3749 ; cartridge initialization indirect jumps 3750 f239 6c fe bf caini: jmp (cartad) 3751 f23c 6c fe 9f cbini: jmp (cartad-$2000) \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 85 3752 .page 3753 ; 3754 ; 3755 ; 3756 ; 3757 ; 3758 ; 3759 ; S U B R O U T I N E S 3760 ; 3761 ; 3762 ; 3763 ; 3764 ; 3765 ; 3766 ; 3767 ; 3768 ; 3769 ; 3770 ; 3771 ; 3772 ; 3773 ; 3774 ; 3775 ; 3776 ; 3777 ; 3778 ; check for how much RAM & special cartridge case. 3779 ; if special cartridge case, don't go back -- go to cart. 3780 ; 3781 f23f ad fc bf specl: lda cart ;check for RAM or cart 3782 f242 d0 13 bne enspe2 ;go if nothing or maybe RAM 3783 f244 ee fc bf inc cart ;now do RAM check 3784 f247 ad fc bf lda cart ;is it ROM? 3785 f24a d0 08 bne enspec ;no 3786 f24c ad fd bf lda cartfg ;yes, 3787 f24f 10 03 bpl enspec ;bit set? 3788 f251 6c fe bf jmp (cartad) ;yes, go run cartridge 3789 ; 3790 ; check for amount of RAM 3791 ; 3792 ; 3793 f254 ce fc bf enspec: dec cart ;restore RAM if needed 3794 f257 a0 00 enspe2: ldy #0 3795 f259 84 05 sty ramlo+1 3796 f25b a9 10 lda #$10 3797 f25d 85 06 sta tramsz ;set RAM pointer to 4K. 3798 f25f b1 05 howmch: lda (ramlo+1),y ;read RAM location 3799 f261 49 ff eor #$ff ;invert it. 3800 f263 91 05 sta (ramlo+1),y ;write inverted data. 3801 f265 d1 05 cmp (ramlo+1),y ;read RAM again 3802 f267 d0 0d bne endram 3803 f269 49 ff eor #$ff ;convert it back 3804 f26b 91 05 sta (ramlo+1),y ;restore original RAM data 3805 f26d a5 06 lda tramsz \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 86 3806 f26f 18 clc 3807 f270 69 10 adc #$10 3808 f272 85 06 sta tramsz ;incr. RAM pointer by 4K. 3809 f274 d0 e9 bne howmch ;go find how much RAM. 3810 f276 60 endram: rts 3811 ; 3812 ; 3813 ; 3814 ; 3815 ; hardware initialization 3816 ; 3817 ; 3818 f277 a9 00 hardi: lda #0 3819 f279 aa tax 3820 f27a 9d 00 d0 clrchp: sta $d000,x 3821 f27d 9d 00 d4 sta $d400,x 3822 f280 9d 00 d2 sta $d200,x 3823 f283 9d 00 d3 sta $d300,x 3824 f286 e8 inx 3825 f287 d0 f1 bne clrchp 3826 f289 60 rts 3827 ; 3828 ; 3829 ; O.S. RAM setup 3830 ; 3831 f28a c6 11 osram: dec brkkey ;turn off break key flag 3832 f28c a9 54 lda #.low.brkky2 3833 f28e 8d 36 02 sta brkky 3834 f291 a9 e7 lda #.high.brkky2 3835 f293 8d 37 02 sta brkky+1 3836 f296 a5 06 lda tramsz ;read RAM size in temp. reg. 3837 f298 8d e4 02 sta ramsiz ;save it in RAM size. 3838 f29b 8d e6 02 sta memtop+1 ; init. memtop addr hi byte 3839 f29e a9 00 lda #0 3840 f2a0 8d e5 02 sta memtop ;init. memtop addr lo byte 3841 f2a3 a9 00 lda #inimll 3842 f2a5 8d e7 02 sta memlo 3843 f2a8 a9 07 lda #inimlh 3844 f2aa 8d e8 02 sta memlo+1 ;initialize memlo addr vector 3845 f2ad 20 0c e4 jsr editrv+$c ;editor init. 3846 f2b0 20 1c e4 jsr screnv+$c ;screen init. 3847 f2b3 20 2c e4 jsr keybdv+$c ;keyboard init. 3848 f2b6 20 3c e4 jsr printv+$c ;printer handler init 3849 f2b9 20 4c e4 jsr casetv+$c ;cassette handler init 3850 f2bc 20 6e e4 jsr cioinv ;CIO init. 3851 f2bf 20 65 e4 jsr sioinv ;SIO init. 3852 f2c2 20 6b e4 jsr intinv ;interrupt handler init. 3853 f2c5 ad 1f d0 lda consol 3854 f2c8 29 01 and #$1 3855 f2ca d0 02 bne nokey ;game start key depressed? 3856 f2cc e6 4a inc ckey ;yes, set key flag. 3857 f2ce 60 nokey: rts 3858 ; 3859 ; \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 87 3860 ; do boot of disk 3861 ; 3862 f2cf a5 08 boot: lda warmst 3863 f2d1 f0 0a beq nowarm ;warm start? 3864 f2d3 a5 09 lda boot? ;yes, 3865 f2d5 29 01 and #1 3866 f2d7 f0 03 beq noinit ;valid boot? 3867 f2d9 20 7e f3 jsr dini ;yes, re-init. DOS software 3868 f2dc 60 noinit: rts 3869 f2dd a9 01 nowarm: lda #1 3870 f2df 8d 01 03 sta dunit ;assign disk drive no. 3871 f2e2 a9 53 lda #statc 3872 f2e4 8d 02 03 sta dcomnd ;set up status command 3873 f2e7 20 53 e4 jsr dskinv ;go do disk status 3874 f2ea 10 01 bpl doboot ;is status from SIO good? 3875 f2ec 60 rts ;no, go back with bad boot status 3876 ; 3877 f2ed a9 00 doboot: lda #0 3878 f2ef 8d 0b 03 sta daux2 3879 f2f2 a9 01 lda #1 3880 f2f4 8d 0a 03 sta daux1 ;set sector # to 1. 3881 f2f7 a9 00 lda #buffl 3882 f2f9 8d 04 03 sta dbuflo 3883 f2fc a9 04 lda #buffh 3884 f2fe 8d 05 03 sta dbufhi ;set up buffer addr 3885 f301 20 9d f3 sect1: jsr getsec ;get sector 3886 f304 10 08 bpl allsec ;status o.k. ? 3887 f306 20 81 f3 baddsk: jsr dskrde ;no, go print disk read error 3888 f309 a5 4b lda cassbt 3889 f30b f0 e0 beq doboot ;cassette boot? 3890 f30d 60 rts ;yes, quit 3891 f30e a2 03 allsec: ldx #3 3892 f310 bd 00 04 rdbyte: lda casbuf+3,x ;read a buffer byte 3893 f313 9d 40 02 sta dflags,x ;store it 3894 f316 ca dex 3895 f317 10 f7 bpl rdbyte ;done with 4 byte transfer ? 3896 f319 ad 42 02 lda bootad ;yes, 3897 f31c 85 04 sta ramlo 3898 f31e ad 43 02 lda bootad+1 3899 f321 85 05 sta ramlo+1 ;put boot addr into z. page RAM 3900 f323 ad 04 04 lda casbuf+7 3901 f326 85 0c sta dosini ;establish DOS init address 3902 f328 ad 05 04 lda casbuf+8 3903 f32b 85 0d sta dosini+1 3904 f32d a0 7f mvbuff: ldy #$7f ;yes, set byte count 3905 f32f b9 00 04 mvnxb: lda casbuf+3,y 3906 f332 91 04 sta (ramlo),y ;move a byte from sector buffer to boot addr 3907 f334 88 dey 3908 f335 10 f8 bpl mvnxb ;done ? 3909 f337 18 clc ;yes, 3910 f338 a5 04 lda ramlo 3911 f33a 69 80 adc #$80 3912 f33c 85 04 sta ramlo 3913 f33e a5 05 lda ramlo+1 \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 88 3914 f340 69 00 adc #0 3915 f342 85 05 sta ramlo+1 ;incr boot loader buffer pointer. 3916 f344 ce 41 02 dec dbsect ;decr # of sectors. 3917 f347 f0 11 beq enboot ;more sectors ? 3918 f349 ee 0a 03 inc daux1 ;yes, incr sector # 3919 f34c 20 9d f3 sectx: jsr getsec ;go get sector. 3920 f34f 10 dc bpl mvbuff ;status o.k. ? 3921 f351 20 81 f3 jsr dskrde ;no, go print disk read error 3922 f354 a5 4b lda cassbt 3923 f356 d0 ae bne baddsk ;if cassette, quit. 3924 f358 f0 f2 beq sectx ;if disk, try sector again. 3925 f35a a5 4b enboot: lda cassbt 3926 f35c f0 03 beq xboot ;cassette boot ? 3927 f35e 20 9d f3 jsr getsec ;yes, get EOF record, but don't use it. 3928 f361 20 6c f3 xboot: jsr bload ;go execute boot loader 3929 f364 b0 a0 bcs baddsk ;if bad boot, do it over again 3930 f366 20 7e f3 jsr dini ;go init. software 3931 f369 e6 09 inc boot? ;show boot success 3932 f36b 60 rts 3933 f36c 18 bload: clc 3934 f36d ad 42 02 lda bootad 3935 f370 69 06 adc #6 3936 f372 85 04 sta ramlo 3937 f374 ad 43 02 lda bootad+1 3938 f377 69 00 adc #0 3939 f379 85 05 sta ramlo+1 ;put start addr of bootloader into RAM 3940 f37b 6c 04 00 jmp (ramlo) 3941 f37e 6c 0c 00 dini: jmp (dosini) 3942 ; 3943 ; 3944 ; 3945 ; 3946 ; display disk read error msg 3947 ; 3948 f381 a2 0d dskrde: ldx #derrl 3949 f383 a0 f1 ldy #derrh 3950 ; 3951 ; 3952 ; 3953 ; put line on screen at present cursor position 3954 ; 3955 ; X-reg -- lo byte, begin addr of line 3956 ; Y-reg -- hi byte, begin addr of line 3957 ; 3958 f385 8a putlin: txa 3959 f386 a2 00 ldx #sex 3960 f388 9d 44 03 sta icbal,x 3961 f38b 98 tya 3962 f38c 9d 45 03 sta icbah,x ;set up addr of begin of line 3963 f38f a9 09 lda #puttxt 3964 f391 9d 42 03 sta iccom,x ;"put text record" command 3965 f394 a9 ff lda #$ff 3966 f396 9d 48 03 sta icbll,x ;set buffer length 3967 f399 20 56 e4 jsr ciov ;put line on screen \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 89 3968 f39c 60 rts 3969 ; 3970 ; 3971 ; 3972 ; 3973 ; get sector from disk 0 3974 ; 3975 f39d a5 4b getsec: lda cassbt 3976 f39f f0 03 beq diskm ;cassette boot ? 3977 f3a1 4c 7a e4 jmp rblokv ;yes, go to read block routine 3978 f3a4 a9 52 diskm: lda #read 3979 f3a6 8d 02 03 sta dcomnd ;set read sector command 3980 f3a9 a9 01 lda #1 3981 f3ab 8d 01 03 sta dunit ;set drive no. to drive 0 3982 f3ae 20 53 e4 jsr dskinv ;get sector 3983 f3b1 60 rts 3984 ; 3985 ; 3986 ; 3987 ; do check for cassette boot & if so, do boot 3988 ; 3989 f3b2 a5 08 csboot: lda warmst ;warmstart? 3990 f3b4 f0 0a beq csbot2 ;no 3991 f3b6 a5 09 lda boot? ;get boot flag 3992 f3b8 29 02 and #2 ;was cassette boot succesfull? 3993 f3ba f0 03 beq nocsb2 ;no 3994 f3bc 20 e1 f3 jsr cini ;yes, init cassette software 3995 f3bf 60 nocsb2: rts 3996 ; 3997 f3c0 a5 4a csbot2: lda ckey 3998 f3c2 f0 1c beq nocsbt ;"c" key flag set ? 3999 f3c4 a9 80 lda #$80 ;yes, 4000 f3c6 85 3e sta ftype ;set long IRG type 4001 f3c8 e6 4b inc cassbt ;set cassette boot flag 4002 f3ca 20 7d e4 jsr csopiv ;open cassette for input 4003 f3cd 20 01 f3 jsr sect1 ;do boot & init. 4004 f3d0 a9 00 lda #0 4005 f3d2 85 4b sta cassbt ;reset cassette boot flag 4006 f3d4 85 4a sta ckey ;clear key flag 4007 f3d6 06 09 asl boot? ;shift boot flag (now=2 if success) 4008 f3d8 a5 0c lda dosini 4009 f3da 85 02 sta casini ;move init address for cassette 4010 f3dc a5 0d lda dosini+1 4011 f3de 85 03 sta casini+1 4012 f3e0 60 nocsbt: rts 4013 ; 4014 f3e1 6c 02 00 cini: jmp (casini) ;init cassette 4015 ;*********************************************************************** 4016 ; 4017 ; 4018 ; spare byte or module too long flag 4019 ; 4020 f3e5 crntp7 =* 4021 ; \newpage err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 90 4022 *=$14 4023 0014 00 monspr: .byte kbdorg-crntp7 ;^gmonitp too long 4024 ; \newfile err line addr b1 b2 b3 b4 monitor ***** monitp.src ***** 3/9/79 ***** 4:00 page 91 4025 .page 4026 .title 'display handler -- 10-30-78 -- displc' 4027 ; 4028 ; handler dependent equates 4029 ; 4030 007d clrcod = $7d ;clear screen atasci code 4031 009f cntl1 = $9f ;POKEY key code for ^1 4032 ; 4033 0068 frmadr = savadr 4034 0066 toadr = mlttmp 4035 ; \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 92 4036 .page 4037 ; 4038 ; 4039 *=editrv 4040 ; 4041 ; screen editor handler entry point 4042 ; 4043 e400 fb f3 editor: .word eopen-1 4044 e402 33 f6 .word retur1-1 ;(close) 4045 e404 3d f6 .word egetch-1 4046 e406 a3 f6 .word eoutch-1 4047 e408 33 f6 .word retur1-1 ;(status) 4048 e40a 3c f6 .word nofunc-1 ;(special) 4049 e40c 4c e4 f3 jmp pwrona 4050 e40f 00 .byte 0 ;ROM filler byte 4051 ; 4052 *=screnv 4053 ; 4054 ; display handler entry point 4055 ; 4056 e410 f5 f3 displa: .word dopen-1 4057 e412 33 f6 .word retur1-1 ;(close) 4058 e414 92 f5 .word getch-1 4059 e416 b6 f5 .word outch-1 4060 e418 33 f6 .word retur1-1 ;(status) 4061 e41a fb fc .word draw-1 ;(special) 4062 e41c 4c e4 f3 jmp pwrona 4063 e41f 00 .byte 0 ;ROM filler byte 4064 ; 4065 *=keybdv 4066 ; 4067 ; 4068 ; keyboard handler entry point 4069 ; 4070 e420 33 f6 kbdhnd: .word retur1-1 4071 e422 33 f6 .word retur1-1 ;(close) 4072 e424 e1 f6 .word kgetch-1 4073 e426 3c f6 .word nofunc-1 ;(outch) 4074 e428 33 f6 .word retur1-1 ;(status) 4075 e42a 3c f6 .word nofunc-1 ;(special) 4076 e42c 4c e4 f3 jmp pwrona 4077 e42f 00 .byte 0 ;ROM filler byte 4078 ; 4079 ; 4080 ; interrupt vector table entry 4081 *=vctabl-intabs+vkeybd 4082 e488 be ff .word pirq5 ;keyboard IRQ interrupt vector \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 93 4083 4084 *=kbdorg 4085 ; 4086 f3e4 a9 ff pwrona: lda #$ff 4087 f3e6 8d fc 02 sta ch 4088 f3e9 ad e6 02 lda memtop+1 4089 f3ec 29 f0 and #$f0 ;insure 4K page boundary 4090 f3ee 85 6a sta ramtop 4091 f3f0 a9 40 lda #$40 ;default to upper case alpha at pwron 4092 f3f2 8d be 02 sta shflok 4093 f3f5 60 rts ;power on completed \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 94 4094 .page 4095 ; 4096 ; 4097 ; begin display handler open processing 4098 ; 4099 f3f6 a5 2b dopen: lda icax2z ;get aux 2 byte 4100 f3f8 29 0f and #$f 4101 f3fa d0 08 bne opncom ;if mode zero, clear icax1z 4102 f3fc a5 2a eopen: lda icax1z ;clear "clr inhibit" and "mxd mode" bits 4103 f3fe 29 0f and #$f 4104 f400 85 2a sta icax1z 4105 f402 a9 00 lda #0 4106 f404 85 57 opncom: sta dindex 4107 f406 a9 e0 lda #$e0 ;initialize global vblank RAM 4108 f408 8d f4 02 sta chbas 4109 f40b a9 02 lda #2 4110 f40d 8d f3 02 sta chact 4111 f410 8d 2f 02 sta sdmctl ;turn off DMA next vblank 4112 f413 a9 01 lda #succes 4113 f415 85 4c sta dstat ;clear status 4114 f417 a9 c0 lda #$c0 ;do irqen 4115 f419 05 10 ora pokmsk 4116 f41b 85 10 sta pokmsk 4117 f41d 8d 0e d2 sta irqen 4118 f420 a9 00 lda #0 4119 f422 8d 93 02 sta tindex ;text index must always be 0 4120 f425 85 64 sta adress 4121 f427 85 7b sta swpflg 4122 f429 8d f0 02 sta crsinh ;turn cursor on at open 4123 f42c a0 0e ldy #14 ;clear tab stops 4124 f42e a9 01 lda #1 ;init tab stops to every 8 characters 4125 f430 99 a3 02 clrtbs: sta tabmap,y 4126 f433 88 dey 4127 f434 10 fa bpl clrtbs 4128 f436 a2 04 ldx #4 ;load color registers 4129 f438 bd c1 fe dopen8: lda colrtb,x 4130 f43b 9d c4 02 sta color0,x 4131 f43e ca dex 4132 f43f 10 f7 bpl dopen8 4133 f441 a4 6a ldy ramtop ;do txtmsc=$2c40 (if memtop=3000) 4134 f443 88 dey 4135 f444 8c 95 02 sty txtmsc+1 4136 f447 a9 60 lda #$60 4137 f449 8d 94 02 sta txtmsc 4138 f44c a6 57 ldx dindex 4139 f44e bd 69 fe lda anconv,x ;convert it to ANTIC code 4140 f451 d0 04 bne dopena ;if zero, it is illegal 4141 f453 a9 91 opnerr: lda #badmod ;set error status 4142 f455 85 4c sta dstat 4143 f457 85 51 dopena: sta hold1 4144 f459 a5 6a lda ramtop ;set up an indirect pointer 4145 f45b 85 65 sta adress+1 4146 f45d bc 45 fe ldy alocat,x ;allocate n blocks of 40 bytes 4147 f460 a9 28 dopen1: lda #40 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 95 4148 f462 20 21 f9 jsr dbsub 4149 f465 88 dey 4150 f466 d0 f8 bne dopen1 4151 f468 ad 6f 02 lda gprior ;clear GTIA modes 4152 f46b 29 3f and #$3f 4153 f46d 85 67 sta opntmp+1 4154 f46f a8 tay 4155 f470 e0 08 cpx #8 ;test if 320x1 4156 f472 90 17 bcc not8 4157 f474 8a txa ;get 2 low bits 4158 f475 6a ror a 4159 f476 6a ror a 4160 f477 6a ror a 4161 f478 29 c0 and #$c0 ;now 2 top bits 4162 f47a 05 67 ora opntmp+1 4163 f47c a8 tay 4164 f47d a9 10 lda #16 ;subtract 16 more for page boundary 4165 f47f 20 21 f9 jsr dbsub 4166 f482 e0 0b cpx #11 ;test mode 11 4167 f484 d0 05 bne not8 ;if mode = 11 4168 f486 a9 06 lda #6 ;put GTIA lum value into background register 4169 f488 8d c8 02 sta color4 4170 f48b 8c 6f 02 not8: sty gprior ;store new priority 4171 f48e a5 64 lda adress ;save memory scan counter address 4172 f490 85 58 sta savmsc 4173 f492 a5 65 lda adress+1 4174 f494 85 59 sta savmsc+1 4175 f496 ad 0b d4 vbwait: lda vcount ;wait for next vblank before messing 4176 f499 c9 7a cmp #$7a ;with the display list 4177 f49b d0 f9 bne vbwait 4178 f49d 20 1f f9 jsr dbdec ;start putting display list right under RAM 4179 f4a0 bd 75 fe lda pagetb,x ;test if display list will be in trouble 4180 f4a3 f0 06 beq nomod ;of crossing a 256 byte page boundary 4181 f4a5 a9 ff lda #$ff ;if so, drop down a page 4182 f4a7 85 64 sta adress 4183 f4a9 c6 65 dec adress+1 4184 f4ab a5 64 nomod: lda adress ;save end of display list for later 4185 f4ad 85 68 sta savadr 4186 f4af a5 65 lda adress+1 4187 f4b1 85 69 sta savadr+1 4188 f4b3 20 13 f9 jsr dbddec ;(double byte double decrement) 4189 f4b6 a9 41 lda #$41 ;(ANTIC) wait for vblank and jmp to top 4190 f4b8 20 17 f9 jsr store 4191 f4bb 86 66 stx opntmp 4192 f4bd a9 18 lda #24 ;initialize botscr 4193 f4bf 8d bf 02 sta botscr 4194 f4c2 a5 57 lda dindex ;disallow mixed mode if mode.ge.9 4195 f4c4 c9 09 cmp #9 4196 f4c6 b0 2d bcs notmxd 4197 f4c8 a5 2a lda icax1z ;test mixed mode 4198 f4ca 29 10 and #$10 4199 f4cc f0 27 beq notmxd 4200 f4ce a9 04 lda #4 4201 f4d0 8d bf 02 sta botscr \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 96 4202 f4d3 a2 02 ldx #2 ;add 4 lines of text at bottom of screen 4203 f4d5 a9 02 dopen2: lda #2 4204 f4d7 20 17 f9 jsr store 4205 f4da ca dex 4206 f4db 10 f8 bpl dopen2 4207 f4dd a4 6a ldy ramtop ;reload msc for text 4208 f4df 88 dey 4209 f4e0 98 tya 4210 f4e1 20 17 f9 jsr store 4211 f4e4 a9 60 lda #$60 4212 f4e6 20 17 f9 jsr store 4213 f4e9 a9 42 lda #$42 4214 f4eb 20 17 f9 jsr store 4215 f4ee 18 clc 4216 f4ef a9 0c lda #mxdmde-numdle ;point X at mixed mode table 4217 f4f1 65 66 adc opntmp 4218 f4f3 85 66 sta opntmp 4219 f4f5 a4 66 notmxd: ldy opntmp 4220 f4f7 be 51 fe ldx numdle,y ;get number of display list entries 4221 f4fa a5 51 dopen3: lda hold1 ;store n dle's 4222 f4fc 20 17 f9 jsr store 4223 f4ff ca dex 4224 f500 d0 f8 bne dopen3 4225 f502 a5 57 lda dindex ;do the messy 320x1 problem 4226 f504 c9 08 cmp #8 4227 f506 90 1c bcc dopen5 4228 f508 a2 5d ldx #93 ;get remaining number of dle's 4229 f50a a5 6a lda ramtop ;reload memory scan counter 4230 f50c 38 sec 4231 f50d e9 10 sbc #$10 4232 f50f 20 17 f9 jsr store 4233 f512 a9 00 lda #0 4234 f514 20 17 f9 jsr store 4235 f517 a9 4f lda #$4f ;(ANTIC) reload msc code 4236 f519 20 17 f9 jsr store 4237 f51c a5 51 dopen4: lda hold1 ;do remaining dle's 4238 f51e 20 17 f9 jsr store 4239 f521 ca dex 4240 f522 d0 f8 bne dopen4 4241 f524 a5 59 dopen5: lda savmsc+1 ;polish off display list 4242 f526 20 17 f9 jsr store 4243 f529 a5 58 lda savmsc 4244 f52b 20 17 f9 jsr store 4245 f52e a5 51 lda hold1 4246 f530 09 40 ora #$40 4247 f532 20 17 f9 jsr store 4248 f535 a9 70 lda #$70 ;24 blank lines 4249 f537 20 17 f9 jsr store 4250 f53a a9 70 lda #$70 4251 f53c 20 17 f9 jsr store 4252 f53f a5 64 lda adress ;save display list address 4253 f541 8d 30 02 sta sdlstl 4254 f544 a5 65 lda adress+1 4255 f546 8d 31 02 sta sdlstl+1 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 97 4256 f549 a9 70 lda #$70 ;add last blank line entry 4257 f54b 20 17 f9 jsr store ;position adress=sdlstl-1 4258 f54e a5 64 lda adress ;store new memtop 4259 f550 8d e5 02 sta memtop 4260 f553 a5 65 lda adress+1 4261 f555 8d e6 02 sta memtop+1 4262 f558 a5 68 lda savadr 4263 f55a 85 64 sta adress 4264 f55c a5 69 lda savadr+1 4265 f55e 85 65 sta adress+1 4266 f560 ad 31 02 lda sdlstl+1 4267 f563 20 17 f9 jsr store 4268 f566 ad 30 02 lda sdlstl 4269 f569 20 17 f9 jsr store 4270 f56c a5 4c lda dstat ;if error ocurred on allocation, open the ed 4271 f56e 10 07 bpl dopen9 4272 f570 48 pha ;save status 4273 f571 20 fc f3 jsr eopen ;open the editor 4274 f574 68 pla ;restore status 4275 f575 a8 tay ;and return it to CIO 4276 f576 60 rts 4277 f577 a5 2a dopen9: lda icax1z ;test clear inhibit bit 4278 f579 29 20 and #$20 4279 f57b d0 0b bne dopen7 4280 f57d 20 b9 f7 jsr clrscr ;clear screen 4281 f580 8d 90 02 sta txtrow ;and home text cursor (ac is zero) 4282 f583 a5 52 lda lmargn 4283 f585 8d 91 02 sta txtcol 4284 f588 a9 22 dopen7: lda #$22 ;everything else is set up 4285 f58a 0d 2f 02 ora sdmctl ;so turn on dmactl 4286 f58d 8d 2f 02 sta sdmctl 4287 f590 4c 21 f6 jmp retur2 4288 ; 4289 ; 4290 f593 20 96 fa getch: jsr range ;getch does incrsr, getplt doesn't 4291 f596 20 a2 f5 jsr getplt 4292 f599 20 32 fb jsr inatac ;convert internal code to atascii 4293 f59c 20 d4 f9 jsr incrsb 4294 f59f 4c 34 f6 jmp retur1 4295 f5a2 20 47 f9 getplt: jsr convrt ;convert row/column to adress 4296 f5a5 b1 64 lda (adress),y 4297 f5a7 2d a0 02 and dmask 4298 f5aa 46 6f shiftd: lsr shfamt ;shift data down to low bits 4299 f5ac b0 03 bcs shift1 4300 f5ae 4a lsr a 4301 f5af 10 f9 bpl shiftd ;(unconditional) 4302 f5b1 8d fa 02 shift1: sta char 4303 f5b4 c9 00 cmp #0 ;restore flags also 4304 f5b6 60 rts 4305 ; 4306 ; 4307 ; 4308 f5b7 8d fb 02 outch: sta atachr 4309 f5ba 20 96 fa jsr range \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 98 4310 ; jsr offcrs 4311 f5bd ad fb 02 outcha: lda atachr ;test for clear screen 4312 f5c0 c9 7d cmp #clrcod 4313 f5c2 d0 06 bne outche 4314 f5c4 20 b9 f7 jsr clrscr 4315 f5c7 4c 21 f6 jmp retur2 4316 f5ca ad fb 02 outche: lda atachr ;test for carriage return 4317 f5cd c9 9b cmp #CR 4318 f5cf d0 06 bne outchb 4319 f5d1 20 30 fa jsr docrws ;do CR 4320 f5d4 4c 21 f6 jmp retur2 4321 f5d7 20 e0 f5 outchb: jsr outplt 4322 f5da 20 d8 f9 jsr incrsr 4323 f5dd 4c 21 f6 jmp retur2 4324 ; 4325 ; 4326 f5e0 ad ff 02 outplt: lda ssflag ;*****loop here if start/stop flag is non-0 4327 f5e3 d0 fb bne outplt 4328 f5e5 a2 02 ldx #2 4329 f5e7 b5 54 crloop: lda rowcrs,x ;save cursor location for draw line to draw 4330 f5e9 95 5a sta oldrow,x 4331 f5eb ca dex 4332 f5ec 10 f9 bpl crloop 4333 f5ee ad fb 02 lda atachr ;convert atascii(atachr) to internal(char) 4334 f5f1 a8 tay ;save atachr 4335 f5f2 2a rol a 4336 f5f3 2a rol a 4337 f5f4 2a rol a 4338 f5f5 2a rol a 4339 f5f6 29 03 and #3 4340 f5f8 aa tax ;X has index into ataint 4341 f5f9 98 tya ;restore atachr 4342 f5fa 29 9f and #$9f ;strip off column address 4343 f5fc 1d f6 fe ora ataint,x ;or in new column address 4344 f5ff 8d fa 02 outch2: sta char 4345 f602 20 47 f9 jsr convrt 4346 f605 ad fa 02 lda char 4347 f608 46 6f shiftu: lsr shfamt ;shift up to proper position 4348 f60a b0 04 bcs shift2 4349 f60c 0a asl a 4350 f60d 4c 08 f6 jmp shiftu 4351 f610 2d a0 02 shift2: and dmask 4352 f613 85 50 sta tmpchr ;save shifted data 4353 f615 ad a0 02 lda dmask ;invert mask 4354 f618 49 ff eor #$ff 4355 f61a 31 64 and (adress),y ;mask off old data 4356 f61c 05 50 ora tmpchr ;or in new data 4357 f61e 91 64 sta (adress),y 4358 f620 60 rts 4359 ; 4360 ; 4361 f621 20 a2 f5 retur2: jsr getplt ;do cursor on the way out 4362 f624 85 5d sta oldchr 4363 f626 a6 57 ldx dindex ;graphics have invisible cursor \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 99 4364 f628 d0 0a bne retur1 4365 f62a ae f0 02 ldx crsinh ;test cursor inhibit 4366 f62d d0 05 bne retur1 4367 f62f 49 80 eor #$80 ;toggle MSB 4368 f631 20 ff f5 jsr outch2 ;display it 4369 f634 a4 4c retur1: ldy dstat ;return to CIO with status in Y 4370 f636 a9 01 lda #succes 4371 f638 85 4c sta dstat ;set status= successful completion 4372 f63a ad fb 02 lda atachr ;put atachr in ac for return to CIO 4373 f63d 60 nofunc: rts ;(non-existent function return point) 4374 ; 4375 ; 4376 ; 4377 ; end of display handler 4378 ; \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 100 4379 .page 4380 ; 4381 ; 4382 ; 4383 ; 4384 f63e 20 b3 fc egetch: jsr swap 4385 f641 20 88 fa jsr erange 4386 f644 a5 6b lda bufcnt ;anything in the buffer? 4387 f646 d0 34 bne egetc3 ;yes 4388 f648 a5 54 lda rowcrs ;no, so save buffer start address 4389 f64a 85 6c sta bufstr 4390 f64c a5 55 lda colcrs 4391 f64e 85 6d sta bufstr+1 4392 f650 20 e2 f6 egetc1: jsr kgetch ;let's fill our buffer 4393 f653 84 4c sty dstat save keyboard status 4394 f655 ad fb 02 lda atachr ;test for CR 4395 f658 c9 9b cmp #CR 4396 f65a f0 12 beq egetc2 4397 f65c 20 ad f6 jsr doss ;no, so print it 4398 f65f 20 b3 fc jsr swap ;jsr doss did swap so swap back 4399 f662 a5 63 lda logcol ;beep if nearing logical col 120 4400 f664 c9 71 cmp #113 4401 f666 d0 03 bne egetc6 4402 f668 20 0a f9 jsr bell 4403 f66b 4c 50 f6 egetc6: jmp egetc1 4404 f66e 20 e4 fa egetc2: jsr offcrs ;get buffer count 4405 f671 20 00 fc jsr dobufc 4406 f674 a5 6c lda bufstr ;return a character 4407 f676 85 54 sta rowcrs 4408 f678 a5 6d lda bufstr+1 4409 f67a 85 55 sta colcrs 4410 f67c a5 6b egetc3: lda bufcnt 4411 f67e f0 11 beq egetc5 4412 f680 c6 6b egetc7: dec bufcnt ;and return till bufcnt=0 4413 f682 f0 0d beq egetc5 4414 f684 a5 4c lda dstat ;if err, loop on egetc7 until bufr is emptie 4415 f686 30 f8 bmi egetc7 4416 f688 20 93 f5 jsr getch 4417 f68b 8d fb 02 sta atachr 4418 f68e 4c b3 fc jmp swap ;and return without turning cursor back on 4419 f691 20 30 fa egetc5: jsr docrws ;do real carriage return 4420 f694 a9 9b lda #CR ;and return EOL 4421 f696 8d fb 02 sta atachr 4422 f699 20 21 f6 jsr retur2 ;turn on cursor then swap 4423 f69c 84 4c sty dstat ;save keyboard status 4424 f69e 4c b3 fc jmp swap ;and return through retur1 4425 ; 4426 f6a1 6c 64 00 jsrind: jmp (adress) ;jsr to this causes jsr indirect 4427 ; 4428 f6a4 8d fb 02 eoutch: sta atachr ;save atascii value 4429 f6a7 20 b3 fc jsr swap 4430 f6aa 20 88 fa jsr erange 4431 f6ad 20 e4 fa doss: jsr offcrs ;turn off cursor 4432 f6b0 20 8d fc jsr tstctl ;test for control characters (Z=1 if ctl) \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 101 4433 f6b3 f0 09 beq eoutc5 4434 f6b5 0e a2 02 eoutc6: asl escflg ;escflg only works once 4435 f6b8 20 ca f5 jsr outche 4436 f6bb 4c b3 fc eretn: jmp swap ;and return through retur1 4437 f6be ad fe 02 eoutc5: lda dspflg ;do dspflg and escflg 4438 f6c1 0d a2 02 ora escflg 4439 f6c4 d0 ef bne eoutc6 ;if non-0 display rather than execute it 4440 f6c6 0e a2 02 asl escflg 4441 f6c9 e8 inx ;process control characters 4442 f6ca bd c6 fe lda cntrls,x ;get displacement into routine 4443 f6cd 85 64 sta adress 4444 f6cf bd c7 fe lda cntrls+1,x ;get high byte 4445 f6d2 85 65 sta adress+1 4446 f6d4 20 a1 f6 jsr jsrind ;do computed jsr 4447 f6d7 20 21 f6 jsr retur2 ;do cursor 4448 f6da 4c b3 fc jmp swap ;all done so return through retur1 4449 ; 4450 ; 4451 ; 4452 ; 4453 ; end screen editor. 4454 ; 4455 ; 4456 ; begin keyboard handler 4457 ; 4458 ; 4459 ; 4460 ; 4461 f6dd a9 ff kgetc2: lda #$ff 4462 f6df 8d fc 02 sta ch 4463 f6e2 a5 2a kgetch: lda icax1z ;test LSB of aux1 for special editor read mo 4464 f6e4 4a lsr a 4465 f6e5 b0 62 bcs getout 4466 f6e7 a9 80 lda #brkabt 4467 f6e9 a6 11 ldx brkkey ;test break 4468 f6eb f0 58 beq k7 ;if break, put brkabt in dstat and CR in ata 4469 f6ed ad fc 02 lda ch 4470 f6f0 c9 ff cmp #$ff 4471 f6f2 f0 ee beq kgetch 4472 f6f4 85 7c sta holdch ;save ch for shift lock proc 4473 f6f6 a2 ff ldx #$ff ;"clear" ch 4474 f6f8 8e fc 02 stx ch 4475 f6fb 20 d8 fc jsr click ;do keyboard audio feedback (A is ok) 4476 f6fe aa kgetc3: tax ;do asccon 4477 f6ff e0 c0 cpx #$c0 ;test for ctl & shift together 4478 f701 90 02 bcc ascc01 4479 f703 a2 03 ldx #3 ;bad code 4480 f705 bd fe fe ascc01: lda atasci,x 4481 f708 8d fb 02 sta atachr ;done 4482 f70b c9 80 cmp #$80 ;do nulls 4483 f70d f0 ce beq kgetc2 4484 f70f c9 81 cmp #$81 ;check atari key 4485 f711 d0 0b bne kgetc1 4486 f713 ad b6 02 lda invflg \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 102 4487 f716 49 80 eor #$80 4488 f718 8d b6 02 sta invflg 4489 f71b 4c dd f6 jmp kgetc2 ;dont return a value 4490 f71e c9 82 kgetc1: cmp #$82 ;caps/lower 4491 f720 d0 07 bne k1 4492 f722 a9 00 lda #0 ;clear shflok 4493 f724 8d be 02 sta shflok 4494 f727 f0 b4 beq kgetc2 4495 f729 c9 83 k1: cmp #$83 ;shift caps/lower 4496 f72b d0 07 bne k2 4497 f72d a9 40 lda #$40 4498 f72f 8d be 02 sta shflok ;shift bit 4499 f732 d0 a9 bne kgetc2 4500 f734 c9 84 k2: cmp #$84 ;cntl caps/lower 4501 f736 d0 07 bne k3 4502 f738 a9 80 lda #$80 ;cntl bit 4503 f73a 8d be 02 sta shflok 4504 f73d d0 9e bne kgetc2 4505 f73f c9 85 k3: cmp #$85 ;do EOF 4506 f741 d0 0a bne k6 4507 f743 a9 88 lda #eoferr 4508 f745 85 4c k7: sta dstat 4509 f747 85 11 sta brkkey ;restore break 4510 f749 a9 9b getout: lda #CR ;put CR in atachr 4511 f74b d0 26 bne k8 ;(unconditional) 4512 f74d a5 7c k6: lda holdch ;process shift locks 4513 f74f c9 40 cmp #$40 ;regular shift and control take precedence 4514 f751 b0 15 bcs k5 ;over lock 4515 f753 ad fb 02 lda atachr ;test for alpha 4516 f756 c9 61 cmp #$61 ;lower case a 4517 f758 90 0e bcc k5 ;not alpha if lt 4518 f75a c9 7b cmp #$7b ;lower case z+1 4519 f75c b0 0a bcs k5 ;not alpha if ge 4520 f75e ad be 02 lda shflok ;do shift/control lock 4521 f761 f0 05 beq k5 ;if no lock, dont re-do it 4522 f763 05 7c ora holdch 4523 f765 4c fe f6 jmp kgetc3 ;do retry 4524 f768 20 8d fc k5: jsr tstctl ;dont invert MSB of control characters 4525 f76b f0 09 beq k4 4526 f76d ad fb 02 lda atachr 4527 f770 4d b6 02 eor invflg 4528 f773 8d fb 02 k8: sta atachr 4529 f776 4c 34 f6 k4: jmp retur1 all done 4530 ; 4531 ; \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 103 4532 .page 4533 ; 4534 ; 4535 ; control character processors 4536 ; 4537 f779 a9 80 escape: lda #$80 ;set escape flag 4538 f77b 8d a2 02 sta escflg 4539 f77e 60 rts 4540 f77f c6 54 crsrup: dec rowcrs 4541 f781 10 06 bpl comret 4542 f783 ae bf 02 ldx botscr ;wraparound 4543 f786 ca dex 4544 f787 86 54 updncm: stx rowcrs 4545 f789 4c 5c fc comret: jmp strbeg ;colvert row and col to logcol and return 4546 f78c e6 54 crsrdn: inc rowcrs 4547 f78e a5 54 lda rowcrs 4548 f790 cd bf 02 cmp botscr 4549 f793 90 f4 bcc comret 4550 f795 a2 00 ldx #0 4551 f797 f0 ee beq updncm ;(unconditional) 4552 f799 c6 55 crsrlf: dec colcrs 4553 f79b a5 55 lda colcrs 4554 f79d 30 04 bmi crsrl1 ;(if lmargn=0, this eliminates problem case) 4555 f79f c5 52 cmp lmargn 4556 f7a1 b0 04 bcs comre1 4557 f7a3 a5 53 crsrl1: lda rmargn 4558 f7a5 85 55 lfrtcm: sta colcrs 4559 f7a7 4c dd fb comre1: jmp dolcol ;colvert row and col to logcol and return 4560 f7aa e6 55 crsrrt: inc colcrs 4561 f7ac a5 55 lda colcrs 4562 f7ae c5 53 cmp rmargn 4563 f7b0 90 f5 bcc comre1 4564 f7b2 f0 f3 beq comre1 ;(cause ble) 4565 f7b4 a5 52 lda lmargn 4566 f7b6 4c a5 f7 jmp lfrtcm ;unconditional to common store 4567 f7b9 20 f3 fc clrscr: jsr putmsc 4568 f7bc a0 00 ldy #0 4569 f7be 98 tya ;put 0 in the ac 4570 f7bf 91 64 clrsc2: sta (adress),y ;(ac is zero) 4571 f7c1 c8 iny 4572 f7c2 d0 fb bne clrsc2 4573 f7c4 e6 65 inc adress+1 4574 f7c6 a6 65 ldx adress+1 4575 f7c8 e4 6a cpx ramtop 4576 f7ca 90 f3 bcc clrsc2 4577 f7cc a9 ff lda #$ff ;clean up logical line bit map 4578 f7ce 99 b2 02 clrsc3: sta logmap,y ;(Y is zero after clrsc2 loop) 4579 f7d1 c8 iny 4580 f7d2 c0 04 cpy #4 4581 f7d4 90 f8 bcc clrsc3 4582 f7d6 20 e4 fc home: jsr colcr ;place colcrs at left edge 4583 f7d9 85 63 sta logcol 4584 f7db 85 6d sta bufstr+1 4585 f7dd a9 00 lda #0 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 104 4586 f7df 85 54 sta rowcrs 4587 f7e1 85 56 sta colcrs+1 4588 f7e3 85 6c sta bufstr 4589 f7e5 60 rts 4590 ; 4591 f7e6 a5 63 bs: lda logcol ;backspace 4592 f7e8 c5 52 cmp lmargn 4593 f7ea f0 21 beq bs1 4594 f7ec a5 55 bsa: lda colcrs ;left edge? 4595 f7ee c5 52 cmp lmargn 4596 f7f0 d0 03 bne bs3 ;no 4597 f7f2 20 73 fc jsr deltim ;yes, see if line should be deleted 4598 f7f5 20 99 f7 bs3: jsr crsrlf 4599 f7f8 a5 55 lda colcrs 4600 f7fa c5 53 cmp rmargn 4601 f7fc d0 07 bne bs2 4602 f7fe a5 54 lda rowcrs 4603 f800 f0 03 beq bs2 4604 f802 20 7f f7 jsr crsrup 4605 f805 a9 20 bs2: lda #$20 ;make backspace destructive 4606 f807 8d fb 02 sta atachr 4607 f80a 20 e0 f5 jsr outplt 4608 f80d 4c dd fb bs1: jmp dolcol ;and return 4609 f810 20 aa f7 tab: jsr crsrrt ;begin search 4610 f813 a5 55 lda colcrs ;test for new line 4611 f815 c5 52 cmp lmargn 4612 f817 d0 0a bne tab1 ;no 4613 f819 20 34 fa jsr docr ;do carriage return 4614 f81c 20 20 fb jsr logget ;check if end of logical line 4615 f81f 90 02 bcc tab1 ;no, continue 4616 f821 b0 07 bcs tab2 ;(unconditional) 4617 f823 a5 63 tab1: lda logcol ;check for tab stop 4618 f825 20 25 fb jsr bitget 4619 f828 90 e6 bcc tab ;no, so keep looking 4620 f82a 4c dd fb tab2: jmp dolcol ;colvert row and col to logcol and return 4621 f82d a5 63 settab: lda logcol 4622 f82f 4c 06 fb jmp bitset ;set bit in map and return 4623 f832 a5 63 clrtab: lda logcol 4624 f834 4c 12 fb jmp bitclr ;clear " " " " " 4625 f837 20 9d fc inschr: jsr phacrs 4626 f83a 20 a2 f5 jsr getplt ;get character under cursor 4627 f83d 85 7d sta insdat 4628 f83f a9 00 lda #0 4629 f841 8d bb 02 sta scrflg 4630 f844 20 ff f5 insch4: jsr outch2 ;store data 4631 f847 a5 63 lda logcol ;save logcol: if after incrsa logcol is 4632 f849 48 pha ;< than it is now, end loop 4633 f84a 20 dc f9 jsr incrsa ;special incrsr entry point 4634 f84d 68 pla 4635 f84e c5 63 cmp logcol 4636 f850 b0 0c bcs insch3 ;quit 4637 f852 a5 7d insch1: lda insdat ;keep going 4638 f854 48 pha 4639 f855 20 a2 f5 jsr getplt \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 105 4640 f858 85 7d sta insdat 4641 f85a 68 pla 4642 f85b 4c 44 f8 jmp insch4 4643 f85e 20 a8 fc insch3: jsr placrs 4644 f861 ce bb 02 insch6: dec scrflg 4645 f864 30 04 bmi insch5 ;if scroll occurred 4646 f866 c6 54 dec rowcrs ;move cursor up 4647 f868 d0 f7 bne insch6 ;(uncond) continue until scrflg is minus 4648 f86a 4c dd fb insch5: jmp dolcol ;colvert row and col to logcol and return 4649 ; 4650 ; 4651 f86d 20 9d fc delchr: jsr phacrs 4652 f870 20 47 f9 delch1: jsr convrt ;get data to the right of the cursor 4653 f873 a5 64 lda adress 4654 f875 85 68 sta savadr ;save adress to know where to put data 4655 f877 a5 65 lda adress+1 4656 f879 85 69 sta savadr+1 4657 f87b a5 63 lda logcol 4658 f87d 48 pha 4659 f87e 20 d4 f9 jsr incrsb ;put cursor over next character 4660 f881 68 pla 4661 f882 c5 63 cmp logcol ;test new logcol against old logcol 4662 f884 b0 10 bcs delch2 ;if old.ge.new then quit 4663 f886 a5 54 lda rowcrs ;is row off screen? 4664 f888 cd bf 02 cmp botscr 4665 f88b b0 09 bcs delch2 ;yes, so quit 4666 f88d 20 a2 f5 jsr getplt ;get data under cursor 4667 f890 a0 00 ldy #0 4668 f892 91 68 sta (savadr),y ;put it in previous position 4669 f894 f0 da beq delch1 ;and loop (unconditional) 4670 f896 a0 00 delch2: ldy #0 4671 f898 98 tya 4672 f899 91 68 sta (savadr),y ;clear the last position 4673 f89b 20 68 fc jsr deltia ;try to delete a line 4674 f89e 20 a8 fc jsr placrs 4675 f8a1 4c dd fb jmp dolcol ;and return 4676 f8a4 38 inslin: sec ;normal inslin puts "1" into bit map 4677 f8a5 20 7b fb inslia: jsr extend ;entry point for C=0 4678 f8a8 a5 52 lda lmargn ;do carriage return (no LF) 4679 f8aa 85 55 sta colcrs 4680 f8ac 20 47 f9 jsr convrt ;get address 4681 f8af a5 64 lda adress ;set up to=40+from (from = cursor) 4682 f8b1 85 68 sta frmadr 4683 f8b3 18 clc 4684 f8b4 69 28 adc #40 4685 f8b6 85 66 sta toadr 4686 f8b8 a5 65 lda adress+1 4687 f8ba 85 69 sta frmadr+1 4688 f8bc 69 00 adc #0 4689 f8be 85 67 sta toadr+1 4690 f8c0 a6 54 ldx rowcrs ;set up loop counter 4691 f8c2 e0 17 cpx #23 4692 f8c4 f0 08 beq insli2 4693 f8c6 20 4e fb insli1: jsr movlin \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 106 4694 f8c9 e8 inx 4695 f8ca e0 17 cpx #23 4696 f8cc d0 f8 bne insli1 4697 f8ce 20 9b fb insli2: jsr clrlin ;clear current line 4698 f8d1 4c dd fb jmp dolcol ;colvert row and col to logcol and return 4699 f8d4 20 dd fb dellin: jsr dolcol ;get beginning of log line (hold1) 4700 f8d7 a4 51 dellia: ldy hold1 ;squeeze bit map 4701 f8d9 84 54 sty rowcrs ;put cursor there 4702 f8db a4 54 dellib: ldy rowcrs 4703 f8dd 98 delli1: tya 4704 f8de 38 sec 4705 f8df 20 23 fb jsr lo2get ;get next bit 4706 f8e2 08 php 4707 f8e3 98 tya 4708 f8e4 18 clc 4709 f8e5 69 78 adc #120 4710 f8e7 28 plp 4711 f8e8 20 04 fb jsr bitput ;write it over present bit 4712 f8eb c8 iny 4713 f8ec c0 18 cpy #24 4714 f8ee d0 ed bne delli1 ;loop 4715 f8f0 ad b4 02 lda logmap+2 ;set LSB 4716 f8f3 09 01 ora #1 4717 f8f5 8d b4 02 sta logmap+2 4718 f8f8 a5 52 delli2: lda lmargn ;delete line of data using part of scroll 4719 f8fa 85 55 sta colcrs ;CR no LF 4720 f8fc 20 47 f9 jsr convrt 4721 f8ff 20 b7 fb jsr scrol1 4722 f902 20 20 fb jsr logget ;test next line for continuation 4723 ; is it a new log line? 4724 f905 90 d4 bcc dellib ;no so delete another 4725 f907 4c dd fb jmp dolcol ;yes so dolcol and return 4726 f90a a0 20 bell: ldy #$20 4727 f90c 20 d8 fc bell1: jsr click 4728 f90f 88 dey 4729 f910 10 fa bpl bell1 4730 f912 60 rts \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 107 4731 .page 4732 ; 4733 ; 4734 ; routines 4735 ; 4736 ; 4737 ; double byte decrement of indirect pointer 4738 ; including db subtract and db double decrement 4739 ; 4740 f913 a9 02 dbddec: lda #2 4741 f915 d0 0a bne dbsub ;(unconditional) 4742 ; 4743 ; store data indirect and decrement pointer 4744 ; (placed here to save jmp dbdec after store) 4745 f917 a4 4c store: ldy dstat ;return on error 4746 f919 30 2b bmi strok 4747 f91b a0 00 ldy #0 4748 f91d 91 64 store1: sta (adress),y 4749 ; jmp dbdec decrement and return 4750 ; 4751 f91f a9 01 dbdec: lda #1 4752 f921 8d 9e 02 dbsub: sta subtmp 4753 f924 a5 4c lda dstat ;return on error 4754 f926 30 1e bmi strok 4755 f928 a5 64 lda adress 4756 f92a 38 sec 4757 f92b ed 9e 02 sbc subtmp 4758 f92e 85 64 sta adress 4759 f930 b0 02 bcs dbsub1 4760 f932 c6 65 dec adress+1 4761 f934 a5 0f dbsub1: lda appmhi+1 ;make sure nothing ever overwrites appmhi 4762 f936 c5 65 cmp adress+1 4763 f938 90 0c bcc strok ;ok 4764 f93a d0 06 bne strerr ;error 4765 f93c a5 0e lda appmhi 4766 f93e c5 64 cmp adress 4767 f940 90 04 bcc strok 4768 f942 a9 93 strerr: lda #scrmem ;show mem too small for screen error 4769 f944 85 4c sta dstat 4770 f946 60 strok: rts 4771 ; 4772 ; 4773 ; 4774 ; convert row/column cursor into real address (from savmsc on up) 4775 ; 4776 f947 a5 54 convrt: lda rowcrs ;save cursor 4777 f949 48 pha 4778 f94a a5 55 lda colcrs 4779 f94c 48 pha 4780 f94d a5 56 lda colcrs+1 4781 f94f 48 pha 4782 f950 20 f3 fc jsr putmsc 4783 f953 a5 54 lda rowcrs ;put 10*rowcrs into mlttmp 4784 f955 85 66 sta mlttmp \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 108 4785 f957 a9 00 lda #0 4786 f959 85 67 sta mlttmp+1 4787 f95b a5 66 lda mlttmp ;quick x8 4788 f95d 0a asl a 4789 f95e 26 67 rol mlttmp+1 4790 f960 85 51 sta hold1 ;(save 2x value) 4791 f962 a4 67 ldy mlttmp+1 ;"" 4792 f964 8c 9f 02 sty hold2 ;"" 4793 f967 0a asl a 4794 f968 26 67 rol mlttmp+1 4795 f96a 0a asl a 4796 f96b 26 67 rol mlttmp+1 4797 f96d 18 clc ;add in 2x 4798 f96e 65 51 adc hold1 4799 f970 85 66 sta mlttmp 4800 f972 a5 67 lda mlttmp+1 4801 f974 6d 9f 02 adc hold2 4802 f977 85 67 sta mlttmp+1 4803 f979 a6 57 ldx dindex ;now shift mlttmp left dhline times to finis 4804 f97b bc 81 fe ldy dhline,x ;multiply 4805 f97e 88 convr1: dey ;loop n times 4806 f97f 30 07 bmi convr2 4807 f981 06 66 asl mlttmp 4808 f983 26 67 rol mlttmp+1 4809 f985 4c 7e f9 jmp convr1 4810 f988 bc a5 fe convr2: ldy div2tb,x ;now divide hcrsr to account for partial byt 4811 f98b a5 55 lda colcrs 4812 f98d a2 07 ldx #7 ;* tricky * 4813 f98f 88 convr3: dey 4814 f990 30 0a bmi convr4 4815 f992 ca dex 4816 f993 46 56 lsr colcrs+1 4817 f995 6a ror a 4818 f996 6e a1 02 ror tmplbt ;save low bits for mask 4819 f999 4c 8f f9 jmp convr3 4820 f99c c8 convr4: iny ;so Y is zero upon return from this routine 4821 f99d 18 clc 4822 f99e 65 66 adc mlttmp ;add shifted colcrs to mlttmp 4823 f9a0 85 66 sta mlttmp 4824 f9a2 90 02 bcc convr5 4825 f9a4 e6 67 inc mlttmp+1 4826 f9a6 38 convr5: sec ;* tricky * 4827 f9a7 6e a1 02 convr6: ror tmplbt ;slide a "1" up against low bits (continue t 4828 f9aa 18 clc 4829 f9ab ca dex ;and finish shift so low bits are 4830 f9ac 10 f9 bpl convr6 ;right justified. 4831 f9ae ae a1 02 ldx tmplbt ;tmplbt is now the index into dmasktb 4832 f9b1 a5 66 lda mlttmp ;prepare for return 4833 f9b3 18 clc 4834 f9b4 65 64 adc adress 4835 f9b6 85 64 sta adress 4836 f9b8 85 5e sta oldadr ;remember this address for cursor 4837 f9ba a5 67 lda mlttmp+1 4838 f9bc 65 65 adc adress+1 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 109 4839 f9be 85 65 sta adress+1 4840 f9c0 85 5f sta oldadr+1 4841 f9c2 bd b1 fe lda dmaskt,x 4842 f9c5 8d a0 02 sta dmask 4843 f9c8 85 6f sta shfamt 4844 f9ca 68 pla 4845 f9cb 85 56 sta colcrs+1 4846 f9cd 68 pla 4847 f9ce 85 55 sta colcrs 4848 f9d0 68 pla 4849 f9d1 85 54 sta rowcrs 4850 f9d3 60 rts 4851 ; 4852 ; 4853 ; increment cursor and detect both end of line and end of screen 4854 ; 4855 f9d4 a9 00 incrsb: lda #0 ;non-extend entry point 4856 f9d6 f0 02 beq incrsc 4857 f9d8 a9 9b incrsr: lda #$9b ;special case eliminator 4858 f9da 85 7d incrsc: sta insdat 4859 f9dc e6 63 incrsa: inc logcol ;(inschr entry point) 4860 f9de e6 55 inc colcrs 4861 f9e0 d0 02 bne incrs2 ;do high byte 4862 f9e2 e6 56 inc colcrs+1 4863 f9e4 a5 55 incrs2: lda colcrs ;test end of line 4864 f9e6 a6 57 ldx dindex 4865 f9e8 dd 8d fe cmp column,x ;test tabled value for all screen modes 4866 f9eb f0 0b beq inc2a ;do CR if equal 4867 f9ed e0 00 cpx #0 ;mode 0? 4868 f9ef d0 06 bne incrs3 ;if not, just return 4869 f9f1 c5 53 cmp rmargn ;test against rmargn 4870 f9f3 f0 02 beq incrs3 ;equal is ok 4871 f9f5 b0 01 bcs inc2a ;if greater than, do CR 4872 f9f7 60 incrs3: rts 4873 f9f8 e0 08 inc2a: cpx #8 ;check mode 4874 f9fa 90 04 bcc docr1 ;not 320x1 so do it 4875 f9fc a5 56 lda colcrs+1 ;test msd 4876 f9fe f0 f7 beq incrs3 ;only at 64 so don't do it 4877 fa00 a5 57 docr1: lda dindex ;don't mess with logmap if no mode zero 4878 fa02 d0 30 bne docr 4879 fa04 a5 63 lda logcol ;test line overrun 4880 fa06 c9 51 cmp #81 4881 fa08 90 0a bcc docr1b ;if less than 81 it is definitely not line 3 4882 fa0a a5 7d lda insdat 4883 fa0c f0 26 beq docr ;only do log line overflow if insdat <>0 4884 fa0e 20 30 fa jsr docrws ;log line overflow is special case 4885 fa11 4c 77 fa jmp incrs1 ;return 4886 fa14 20 34 fa docr1b: jsr docr ;get it over with 4887 fa17 a5 54 lda rowcrs 4888 fa19 18 clc ;test logical line bit map 4889 fa1a 69 78 adc #120 4890 fa1c 20 25 fb jsr bitget 4891 fa1f 90 08 bcc docr1a ;don't extend if overrun is into middle of l 4892 fa21 a5 7d lda insdat ;don't extend if insdat is zero \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 110 4893 fa23 f0 04 beq docr1a ;(inschr special case) 4894 fa25 18 clc ;insert "0" into bit map 4895 fa26 20 a5 f8 jsr inslia 4896 fa29 4c dd fb docr1a: jmp dolcol ;convert row and col to logcol and return 4897 fa2c a9 00 noscrl: lda #0 ;docr without scroll 4898 fa2e f0 02 beq noscr1 ;(unconditional) 4899 fa30 a9 9b docrws: lda #$9b ;docr with scrolling (normal mode) 4900 fa32 85 7d noscr1: sta insdat 4901 fa34 20 e4 fc docr: jsr colcr ;place colcrs at left edge 4902 fa37 a9 00 lda #0 4903 fa39 85 56 sta colcrs+1 4904 fa3b e6 54 inc rowcrs 4905 fa3d a6 57 docr2: ldx dindex 4906 fa3f a0 18 ldy #24 ;set up scroll loop counter 4907 fa41 24 7b bit swpflg 4908 fa43 10 05 bpl docr2a ;branch if normal 4909 fa45 a0 04 ldy #4 4910 fa47 98 tya 4911 fa48 d0 03 bne docr2b ;(unconditional) 4912 fa4a bd 99 fe docr2a: lda norows,x ;get no of rows 4913 fa4d c5 54 docr2b: cmp rowcrs 4914 fa4f d0 26 bne incrs1 4915 fa51 8c 9d 02 sty hold3 4916 fa54 8a txa ;don't scroll if mode <> 0 4917 fa55 d0 20 bne incrs1 4918 fa57 a5 7d lda insdat ;or if insdat = 0 4919 fa59 f0 1c beq incrs1 4920 ; lda insdat if insdat <> $9b then roll in a 0 4921 fa5b c9 9b cmp #$9b ;to extend bottom logical line 4922 fa5d 38 sec 4923 fa5e f0 01 beq docr4b 4924 fa60 18 clc 4925 fa61 20 ac fb docr4b: jsr scroll ;loop back to here if >1 scrolls 4926 fa64 ee bb 02 inc scrflg 4927 fa67 c6 6c dec bufstr ;rows move up so bufstr should too 4928 fa69 ce 9d 02 dec hold3 4929 fa6c ad b2 02 lda logmap 4930 fa6f 38 sec ;for partial lines, roll in a "1" 4931 fa70 10 ef bpl docr4b ;again if partial logical line 4932 fa72 ad 9d 02 lda hold3 ;place cursor at new line near the bottom 4933 fa75 85 54 sta rowcrs 4934 fa77 4c dd fb incrs1: jmp dolcol ;colvert row and col to logcol and return 4935 ; 4936 ; 4937 ; subend: subtract endpt from rowac or colac. (X=0 or 2) 4938 ; 4939 fa7a 38 subend: sec 4940 fa7b b5 70 lda rowac,x 4941 fa7d e5 74 sbc endpt 4942 fa7f 95 70 sta rowac,x 4943 fa81 b5 71 lda rowac+1,x 4944 fa83 e5 75 sbc endpt+1 4945 fa85 95 71 sta rowac+1,x 4946 fa87 60 rts \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 111 4947 ; 4948 ; 4949 ; range: do cursor range test. if error, pop stack twice and jmp return 4950 ; (erange is editor entry point and test if editor is open. 4951 ; if it isnt it opens the editor and continues) 4952 ; 4953 fa88 ad bf 02 erange: lda botscr ;if botscr=4 4954 fa8b c9 04 cmp #4 4955 fa8d f0 07 beq range ;then it is in mixed mode and ok 4956 fa8f a5 57 lda dindex ;if mode = 0 4957 fa91 f0 03 beq range ;then it is in editor mode and ok 4958 fa93 20 fc f3 jsr eopen ;if not, open editor 4959 fa96 a9 27 range: lda #39 ;***** range check rmargn ***** set up ac 4960 fa98 c5 53 cmp rmargn ;***** range check rmargn ***** compare 4961 fa9a b0 02 bcs range3 ;***** range check rmargn ***** branch ge 4962 fa9c 85 53 sta rmargn ;***** range check rmargn ***** bad so store 4963 fa9e a6 57 range3: ldx dindex 4964 faa0 bd 99 fe lda norows,x ;check rows 4965 faa3 c5 54 cmp rowcrs 4966 faa5 90 2a bcc rngerr ;(error if table.ge.rowcrs) 4967 faa7 f0 28 beq rngerr 4968 faa9 e0 08 cpx #8 ;check for 320x1 4969 faab d0 0a bne range1 ;special case it 4970 faad a5 56 lda colcrs+1 4971 faaf f0 13 beq rngok ;if high byte is 0, col is ok 4972 fab1 c9 01 cmp #1 4973 fab3 d0 1c bne rngerr ;if >1, bad 4974 fab5 f0 04 beq range2 ;if 1, go check low byte 4975 fab7 a5 56 range1: lda colcrs+1 ;for others, non-zero high byte is bad 4976 fab9 d0 16 bne rngerr 4977 fabb bd 8d fe range2: lda column,x ;check low byte 4978 fabe c5 55 cmp colcrs 4979 fac0 90 0f bcc rngerr 4980 fac2 f0 0d beq rngerr 4981 fac4 a9 01 rngok: lda #succes ;set status ok 4982 fac6 85 4c sta dstat 4983 fac8 a9 80 lda #brkabt ;prepare break abort status 4984 faca a6 11 ldx brkkey ;check break key flag 4985 facc 85 11 sta brkkey ;'clear' break 4986 face f0 06 beq rnger2 ;if break, quit immediately and return to ci 4987 fad0 60 rts 4988 fad1 20 d6 f7 rngerr: jsr home ;on range error, bring cursor back 4989 fad4 a9 8d lda #crsror ;show cursor overrange error 4990 fad6 85 4c rnger2: sta dstat 4991 fad8 68 rnger1: pla ;restore stack (this routine is always 1 lev 4992 fad9 68 pla ;away from return to CIO) 4993 fada a5 7b lda swpflg ;if swapped, swap back 4994 fadc 10 03 bpl retur3 4995 fade 20 b9 fc jsr swapa ;and dont do retur1 4996 fae1 4c 34 f6 retur3: jmp retur1 ;return to CIO 4997 ; 4998 ; 4999 ; 5000 ; offcrs: restore old data under cursor so it can be moved \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 112 5001 ; 5002 fae4 a0 00 offcrs: ldy #0 5003 fae6 a5 5d lda oldchr 5004 fae8 91 5e sta (oldadr),y 5005 faea 60 rts 5006 ; 5007 ; 5008 ; 5009 ; bitmap routines: 5010 ; 5011 ; bitcon: put mask in bitmsk and index in X 5012 ; bitput: put carry into bitmap 5013 ; bitrol: rol carry into bottom of bitmap (scroll) 5014 ; bitset: set proper bit 5015 ; bitclr: clear proper bit 5016 ; bitget: return carry set if bit is there 5017 ; logget: do bitget for logmap instead of tabmap 5018 ; 5019 faeb 48 bitcon: pha 5020 faec 29 07 and #7 5021 faee aa tax ;get mask 5022 faef bd b9 fe lda masktb,x 5023 faf2 85 6e sta bitmsk 5024 faf4 68 pla ;process index 5025 faf5 4a lsr a 5026 faf6 4a lsr a 5027 faf7 4a lsr a 5028 faf8 aa tax 5029 faf9 60 rts 5030 ; 5031 ; 5032 fafa 2e b4 02 bitrol: rol logmap+2 5033 fafd 2e b3 02 rol logmap+1 5034 fb00 2e b2 02 rol logmap 5035 fb03 60 rts 5036 ; 5037 ; 5038 fb04 90 0c bitput: bcc bitclr ;and return 5039 ; otherwise fall through to bitset and return 5040 fb06 20 eb fa bitset: jsr bitcon 5041 fb09 bd a3 02 lda tabmap,x 5042 fb0c 05 6e ora bitmsk 5043 fb0e 9d a3 02 sta tabmap,x 5044 fb11 60 rts 5045 ; 5046 fb12 20 eb fa bitclr: jsr bitcon 5047 fb15 a5 6e lda bitmsk 5048 fb17 49 ff eor #$ff 5049 fb19 3d a3 02 and tabmap,x 5050 fb1c 9d a3 02 sta tabmap,x 5051 fb1f 60 rts 5052 ; 5053 fb20 a5 54 logget: lda rowcrs 5054 fb22 18 lo1get: clc \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 113 5055 fb23 69 78 lo2get: adc #120 5056 fb25 20 eb fa bitget: jsr bitcon 5057 fb28 18 clc 5058 fb29 bd a3 02 lda tabmap,x 5059 fb2c 25 6e and bitmsk 5060 fb2e f0 01 beq bitge1 5061 fb30 38 sec 5062 fb31 60 bitge1: rts 5063 ; 5064 ; 5065 ; 5066 ; 5067 ; inatac: internal(char) to atascii(atachr) conversion 5068 ; 5069 fb32 ad fa 02 inatac: lda char 5070 fb35 a4 57 ldy dindex ;if graphics modes 5071 fb37 c0 03 cpy #3 5072 fb39 b0 0f bcs inata1 ;then don't change char 5073 fb3b 2a rol a 5074 fb3c 2a rol a 5075 fb3d 2a rol a 5076 fb3e 2a rol a 5077 fb3f 29 03 and #3 5078 fb41 aa tax 5079 fb42 ad fa 02 lda char 5080 fb45 29 9f and #$9f 5081 fb47 1d fa fe ora intata,x 5082 fb4a 8d fb 02 inata1: sta atachr 5083 fb4d 60 rts 5084 ; 5085 ; 5086 ; 5087 ; movlin: move 40 bytes at frmadr to toadr saving old toadr 5088 ; data in the linbuf. then make next frmadr 5089 ; be at linbuf for next transfer & toadr=toadr+40 5090 ; 5091 fb4e a9 02 movlin: lda #linbuf/256 ;set up adress=linbuf=$247 5092 fb50 85 65 sta adress+1 5093 fb52 a9 47 lda #linbuf.and.$ff 5094 fb54 85 64 sta adress 5095 fb56 a0 27 ldy #39 5096 fb58 b1 66 movli1: lda (toadr),y ;save to data 5097 fb5a 85 50 sta tmpchr 5098 fb5c b1 68 lda (frmadr),y ;store data 5099 fb5e 91 66 sta (toadr),y 5100 fb60 a5 50 lda tmpchr 5101 fb62 91 64 sta (adress),y 5102 fb64 88 dey 5103 fb65 10 f1 bpl movli1 5104 fb67 a5 65 lda adress+1 ;set up frmadr=last line 5105 fb69 85 69 sta frmadr+1 5106 fb6b a5 64 lda adress 5107 fb6d 85 68 sta frmadr 5108 fb6f 18 clc ;add 40 to toadr \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 114 5109 fb70 a5 66 lda toadr 5110 fb72 69 28 adc #40 5111 fb74 85 66 sta toadr 5112 fb76 90 02 bcc movli2 5113 fb78 e6 67 inc toadr+1 5114 fb7a 60 movli2: rts 5115 ; 5116 ; 5117 ; 5118 ; extend: extend bit map from rowcrs (extend logical line 5119 ; 5120 fb7b 08 extend: php ;save carry 5121 fb7c a0 17 ldy #23 5122 fb7e 98 exten1: tya 5123 fb7f 20 22 fb jsr lo1get 5124 fb82 08 php 5125 fb83 98 tya 5126 fb84 18 clc 5127 fb85 69 79 adc #121 5128 fb87 28 plp 5129 fb88 20 04 fb jsr bitput 5130 fb8b 88 exten3: dey 5131 fb8c 30 04 bmi exten4 5132 fb8e c4 54 cpy rowcrs 5133 fb90 b0 ec bcs exten1 5134 fb92 a5 54 exten4: lda rowcrs 5135 fb94 18 clc 5136 fb95 69 78 adc #120 5137 fb97 28 plp 5138 fb98 4c 04 fb jmp bitput ;store new line's bit and return 5139 ; 5140 ; 5141 ; 5142 ; clrlin: clear line cursor is on 5143 ; 5144 fb9b a5 52 clrlin: lda lmargn 5145 fb9d 85 55 sta colcrs 5146 fb9f 20 47 f9 jsr convrt 5147 fba2 a0 27 ldy #39 5148 fba4 a9 00 lda #0 5149 fba6 91 64 clrli1: sta (adress),y 5150 fba8 88 dey 5151 fba9 10 fb bpl clrli1 5152 fbab 60 rts 5153 ; 5154 ; 5155 ; 5156 ; 5157 ; scroll: scroll screen 5158 ; 5159 fbac 20 fa fa scroll: jsr bitrol ;roll in carry 5160 fbaf a5 58 lda savmsc ;set up working registers 5161 fbb1 85 64 sta adress 5162 fbb3 a5 59 lda savmsc+1 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 115 5163 fbb5 85 65 sta adress+1 5164 fbb7 a0 28 scrol1: ldy #40 ;loop 5165 fbb9 b1 64 lda (adress),y 5166 fbbb a6 6a ldx ramtop ;test for last line 5167 fbbd ca dex 5168 fbbe e4 65 cpx adress+1 5169 fbc0 d0 08 bne scrol2 5170 fbc2 a2 d7 ldx #$d7 5171 fbc4 e4 64 cpx adress 5172 fbc6 b0 02 bcs scrol2 5173 fbc8 a9 00 lda #0 ;yes so store zero data for this entire line 5174 fbca a0 00 scrol2: ldy #0 5175 fbcc 91 64 sta (adress),y 5176 fbce e6 64 inc adress 5177 fbd0 d0 e5 bne scrol1 5178 fbd2 e6 65 inc adress+1 5179 fbd4 a5 65 lda adress+1 5180 fbd6 c5 6a cmp ramtop 5181 fbd8 d0 dd bne scrol1 5182 fbda 4c dd fb jmp dolcol ;and return 5183 ; 5184 ; 5185 ; dolcol: do logical column from bitmap and colcrs 5186 ; 5187 fbdd a9 00 dolcol: lda #0 ;start with zero 5188 fbdf 85 63 sta logcol 5189 fbe1 a5 54 lda rowcrs 5190 fbe3 85 51 sta hold1 5191 fbe5 a5 51 dolco1: lda hold1 ;add in row component 5192 fbe7 20 22 fb jsr lo1get 5193 fbea b0 0c bcs dolco2 ;found beginning of line 5194 fbec a5 63 lda logcol ;add 40 and look back one 5195 fbee 18 clc 5196 fbef 69 28 adc #40 5197 fbf1 85 63 sta logcol 5198 fbf3 c6 51 dec hold1 ;up one line 5199 fbf5 4c e5 fb jmp dolco1 5200 fbf8 18 dolco2: clc ;add in colcrs 5201 fbf9 a5 63 lda logcol 5202 fbfb 65 55 adc colcrs 5203 fbfd 85 63 sta logcol 5204 fbff 60 rts 5205 ; 5206 ; 5207 ; 5208 ; dobufc: compute buffer count as the number of bytes from 5209 ; bufstr to end of logical line with trailing spaces removed 5210 ; 5211 fc00 20 9d fc dobufc: jsr phacrs 5212 fc03 a5 63 lda logcol 5213 fc05 48 pha 5214 fc06 a5 6c lda bufstr ;start 5215 fc08 85 54 sta rowcrs 5216 fc0a a5 6d lda bufstr+1 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 116 5217 fc0c 85 55 sta colcrs 5218 fc0e a9 01 lda #1 5219 fc10 85 6b sta bufcnt 5220 fc12 a2 17 dobuf1: ldx #23 ;normal 5221 fc14 a5 7b lda swpflg ;if swapped, row 3 is the last line on scree 5222 fc16 10 02 bpl dob1 5223 fc18 a2 03 ldx #3 5224 fc1a e4 54 dob1: cpx rowcrs ;test if crsr is at last screen position 5225 fc1c d0 0b bne dobu1a 5226 fc1e a5 55 lda colcrs 5227 fc20 c5 53 cmp rmargn 5228 fc22 d0 05 bne dobu1a 5229 fc24 e6 6b inc bufcnt ;yes, so fake incrsr to avoid scrolling 5230 fc26 4c 39 fc jmp dobuf2 5231 fc29 20 d4 f9 dobu1a: jsr incrsb 5232 fc2c e6 6b inc bufcnt 5233 fc2e a5 63 lda logcol 5234 fc30 c5 52 cmp lmargn 5235 fc32 d0 de bne dobuf1 ;not yet EOL 5236 fc34 c6 54 dec rowcrs ;back up one incrsr 5237 fc36 20 99 f7 jsr crsrlf 5238 fc39 20 a2 f5 dobuf2: jsr getplt ;test current column for non-zero data 5239 fc3c d0 17 bne dobuf4 ;quit if non-zero 5240 fc3e c6 6b dec bufcnt ;decrement counter 5241 fc40 a5 63 lda logcol ;beginning of logical line yet? 5242 fc42 c5 52 cmp lmargn 5243 fc44 f0 0f beq dobuf4 ;yes, so quit 5244 fc46 20 99 f7 jsr crsrlf ;back up cursor 5245 fc49 a5 55 lda colcrs ;if logcol=rmargn, go up 1 row 5246 fc4b c5 53 cmp rmargn 5247 fc4d d0 02 bne dobuf3 5248 fc4f c6 54 dec rowcrs 5249 fc51 a5 6b dobuf3: lda bufcnt 5250 fc53 d0 e4 bne dobuf2 ;loop unless bufcnt just went to zero 5251 fc55 68 dobuf4: pla 5252 fc56 85 63 sta logcol 5253 fc58 20 a8 fc jsr placrs 5254 fc5b 60 rts 5255 ; 5256 ; 5257 ; 5258 ; 5259 ; strbeg: move bufstr to beginning of logical line. 5260 ; 5261 fc5c 20 dd fb strbeg: jsr dolcol ;use dolcol to point hold1 at bol 5262 fc5f a5 51 lda hold1 5263 fc61 85 6c sta bufstr 5264 fc63 a5 52 lda lmargn 5265 fc65 85 6d sta bufstr+1 5266 fc67 60 rts 5267 ; 5268 ; 5269 ; 5270 ; \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 117 5271 ; 5272 ; deltim: time to delete a line if it is empty and an extension 5273 ; 5274 fc68 a5 63 deltia: lda logcol ;if logcol<>lmargn 5275 fc6a c5 52 cmp lmargn ;then dont move up one 5276 fc6c d0 02 bne deltib ;line before testing deltim 5277 fc6e c6 54 dec rowcrs 5278 fc70 20 dd fb deltib: jsr dolcol 5279 fc73 a5 63 deltim: lda logcol ;test for extension 5280 fc75 c5 52 cmp lmargn 5281 fc77 f0 13 beq delti3 ;no 5282 fc79 20 47 f9 jsr convrt 5283 fc7c a5 53 lda rmargn ;set up count 5284 fc7e 38 sec 5285 fc7f e5 52 sbc lmargn 5286 fc81 a8 tay 5287 fc82 b1 64 delti1: lda (adress),y 5288 fc84 d0 06 bne delti3 ;found a non-0 so quit and return 5289 fc86 88 dey 5290 fc87 10 f9 bpl delti1 5291 fc89 4c db f8 delti2: jmp dellib ;delete a line and return 5292 fc8c 60 delti3: rts 5293 ; 5294 ; 5295 ; 5296 ; tstctl: search cntrls table to see if atachr is a cntl char 5297 ; 5298 fc8d a2 2d tstctl: ldx #45 ;prepare to search table 5299 fc8f bd c6 fe tstct1: lda cntrls,x 5300 fc92 cd fb 02 cmp atachr 5301 fc95 f0 05 beq tstct2 5302 fc97 ca dex 5303 fc98 ca dex 5304 fc99 ca dex 5305 fc9a 10 f3 bpl tstct1 5306 fc9c 60 tstct2: rts 5307 ; 5308 ; 5309 ; 5310 ; push rowcrs,colcrs and colcrs+1 5311 ; 5312 fc9d a2 02 phacrs: ldx #2 5313 fc9f b5 54 phacr1: lda rowcrs,x 5314 fca1 9d b8 02 sta tmprow,x 5315 fca4 ca dex 5316 fca5 10 f8 bpl phacr1 5317 fca7 60 rts 5318 ; 5319 ; 5320 ; pull colcrs+1,colcrs and rowcrs 5321 ; 5322 fca8 a2 02 placrs: ldx #2 5323 fcaa bd b8 02 placr1: lda tmprow,x 5324 fcad 95 54 sta rowcrs,x \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 118 5325 fcaf ca dex 5326 fcb0 10 f8 bpl placr1 5327 fcb2 60 rts 5328 ; 5329 ; 5330 ; 5331 ; swap: if mixed mode, swap text cursors with regular cursors 5332 ; 5333 fcb3 20 b9 fc swap: jsr swapa ;this entry point does retur1 5334 fcb6 4c 34 f6 jmp retur1 5335 fcb9 ad bf 02 swapa: lda botscr 5336 fcbc c9 18 cmp #24 5337 fcbe f0 17 beq swap3 5338 fcc0 a2 0b ldx #11 5339 fcc2 b5 54 swap1: lda rowcrs,x 5340 fcc4 48 pha 5341 fcc5 bd 90 02 lda txtrow,x 5342 fcc8 95 54 sta rowcrs,x 5343 fcca 68 pla 5344 fccb 9d 90 02 sta txtrow,x 5345 fcce ca dex 5346 fccf 10 f1 bpl swap1 5347 fcd1 a5 7b lda swpflg 5348 fcd3 49 ff eor #$ff 5349 fcd5 85 7b sta swpflg 5350 fcd7 60 swap3: rts 5351 ; 5352 ; 5353 ; click: make click through keyboard speaker 5354 ; 5355 fcd8 a2 7f click: ldx #$7f 5356 fcda 8e 1f d0 click1: stx consol 5357 fcdd 8e 0a d4 stx wsync 5358 fce0 ca dex 5359 fce1 10 f7 bpl click1 5360 fce3 60 rts 5361 ; 5362 ; 5363 ; colcr: puts either 0 or lmargn into colcrs based on mode and swpflg 5364 ; 5365 fce4 a9 00 colcr: lda #0 5366 fce6 a6 7b ldx swpflg 5367 fce8 d0 04 bne colcr1 5368 fcea a6 57 ldx dindex 5369 fcec d0 02 bne colcr2 5370 fcee a5 52 colcr1: lda lmargn 5371 fcf0 85 55 colcr2: sta colcrs 5372 fcf2 60 rts 5373 ; 5374 ; 5375 ; putmsc: put savmsc into adress 5376 ; 5377 fcf3 a5 58 putmsc: lda savmsc ;set up address 5378 fcf5 85 64 sta adress \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 119 5379 fcf7 a5 59 lda savmsc+1 5380 fcf9 85 65 sta adress+1 5381 fcfb 60 rts 5382 ; \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 120 5383 .page 5384 ; 5385 ; 5386 ; draw -- draw a line from oldrow,oldcol to newrow,newcol 5387 ; (the Al Miller method from basketball) 5388 fcfc a2 00 draw: ldx #0 5389 fcfe a5 22 lda iccomz ;test command: $11=draw $12=fill 5390 fd00 c9 11 cmp #$11 5391 fd02 f0 08 beq drawa 5392 fd04 c9 12 cmp #$12 ;test fill 5393 fd06 f0 03 beq drawb ;yes 5394 fd08 a0 84 ldy #nvalid ;no, so return invalid command 5395 fd0a 60 rts 5396 fd0b e8 drawb: inx 5397 fd0c 8e b7 02 drawa: stx filflg 5398 fd0f a5 54 lda rowcrs ;put cursor into newrow,newcol 5399 fd11 85 60 sta newrow 5400 fd13 a5 55 lda colcrs 5401 fd15 85 61 sta newcol 5402 fd17 a5 56 lda colcrs+1 5403 fd19 85 62 sta newcol+1 5404 fd1b a9 01 lda #1 5405 fd1d 85 79 sta rowinc ;set up initial directions 5406 fd1f 85 7a sta colinc 5407 fd21 38 sec 5408 fd22 a5 60 lda newrow ;determine delta row 5409 fd24 e5 5a sbc oldrow 5410 fd26 85 76 sta deltar 5411 fd28 b0 0d bcs draw1 ;do direction and absolute value 5412 fd2a a9 ff lda #$ff ;borrow was attempted 5413 fd2c 85 79 sta rowinc ;set direction=down 5414 fd2e a5 76 lda deltar 5415 fd30 49 ff eor #$ff ;deltar = |deltar| 5416 fd32 18 clc 5417 fd33 69 01 adc #1 5418 fd35 85 76 sta deltar 5419 fd37 38 draw1: sec 5420 fd38 a5 61 lda newcol ;now delta column 5421 fd3a e5 5b sbc oldcol 5422 fd3c 85 77 sta deltac 5423 fd3e a5 62 lda newcol+1 ;two-byte quantity 5424 fd40 e5 5c sbc oldcol+1 5425 fd42 85 78 sta deltac+1 5426 fd44 b0 16 bcs draw2 ;direction and absolute value 5427 fd46 a9 ff lda #$ff ;borrow was attempted 5428 fd48 85 7a sta colinc ;set direction = left 5429 fd4a a5 77 lda deltac 5430 fd4c 49 ff eor #$ff ;deltac = |deltac| 5431 fd4e 85 77 sta deltac 5432 fd50 a5 78 lda deltac+1 5433 fd52 49 ff eor #$ff 5434 fd54 85 78 sta deltac+1 5435 fd56 e6 77 inc deltac ;add one for twos complement 5436 fd58 d0 02 bne draw2 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 121 5437 fd5a e6 78 inc deltac+1 5438 fd5c a2 02 draw2: ldx #2 ;zero RAM for draw loop 5439 fd5e a0 00 ldy #0 5440 fd60 84 73 sty colac+1 5441 fd62 98 draw3a: tya 5442 fd63 95 70 sta rowac,x 5443 fd65 b5 5a lda oldrow,x 5444 fd67 95 54 sta rowcrs,x 5445 fd69 ca dex 5446 fd6a 10 f6 bpl draw3a 5447 fd6c a5 77 lda deltac ;find larger one (row or col) 5448 ; sta countr (prepare countr and endpt) 5449 ; sta endpt 5450 fd6e e8 inx ;make X 0 5451 fd6f a8 tay 5452 fd70 a5 78 lda deltac+1 5453 fd72 85 7f sta countr+1 5454 fd74 85 75 sta endpt+1 5455 fd76 d0 0b bne draw3 ;automatically larger if msd>0 5456 fd78 a5 77 lda deltac 5457 fd7a c5 76 cmp deltar ;low col >low row? 5458 fd7c b0 05 bcs draw3 ;yes 5459 fd7e a5 76 lda deltar 5460 fd80 a2 02 ldx #2 5461 fd82 a8 tay 5462 fd83 98 draw3: tya ;put in initial conditions 5463 fd84 85 7e sta countr 5464 fd86 85 74 sta endpt 5465 fd88 48 pha ;save ac 5466 fd89 a5 75 lda endpt+1 ;put LSB of high byte 5467 fd8b 4a lsr a ;into carry 5468 fd8c 68 pla ;restore ac 5469 fd8d 6a ror a ;ror the 9 bit acumulator 5470 fd8e 95 70 sta rowac,x 5471 fd90 a5 7e draw4a: lda countr ;test zero 5472 fd92 05 7f ora countr+1 5473 fd94 d0 03 bne draw11 ;if counter is zero, leave draw 5474 fd96 4c 42 fe jmp draw10 5475 fd99 18 draw11: clc ;add row to rowac (plot loop) 5476 fd9a a5 70 lda rowac 5477 fd9c 65 76 adc deltar 5478 fd9e 85 70 sta rowac 5479 fda0 90 02 bcc draw5 5480 fda2 e6 71 inc rowac+1 5481 fda4 a5 71 draw5: lda rowac+1 ;compare row to endpoint 5482 fda6 c5 75 cmp endpt+1 ;if high byte of row is .lt. high 5483 fda8 90 14 bcc draw6 ;byte of endpt, blt to column 5484 fdaa d0 06 bne draw5a 5485 fdac a5 70 lda rowac 5486 fdae c5 74 cmp endpt ;low byte 5487 fdb0 90 0c bcc draw6 ;also blt 5488 fdb2 18 draw5a: clc ;ge so move point 5489 fdb3 a5 54 lda rowcrs 5490 fdb5 65 79 adc rowinc \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 122 5491 fdb7 85 54 sta rowcrs 5492 fdb9 a2 00 ldx #0 ;and subtract endpt from rowac 5493 fdbb 20 7a fa jsr subend 5494 fdbe 18 draw6: clc ;do same for column (double byte add) 5495 fdbf a5 72 lda colac ;add 5496 fdc1 65 77 adc deltac 5497 fdc3 85 72 sta colac 5498 fdc5 a5 73 lda colac+1 5499 fdc7 65 78 adc deltac+1 5500 fdc9 85 73 sta colac+1 5501 fdcb c5 75 cmp endpt+1 ;compare high byte 5502 fdcd 90 27 bcc draw8 5503 fdcf d0 06 bne draw6a 5504 fdd1 a5 72 lda colac ;compare low byte 5505 fdd3 c5 74 cmp endpt 5506 fdd5 90 1f bcc draw8 5507 fdd7 24 7a draw6a: bit colinc ;+ or - ? 5508 fdd9 10 10 bpl draw6b 5509 fddb c6 55 dec colcrs ;do double byte decrement 5510 fddd a5 55 lda colcrs 5511 fddf c9 ff cmp #$ff 5512 fde1 d0 0e bne draw7 5513 fde3 a5 56 lda colcrs+1 5514 fde5 f0 0a beq draw7 ;don't dec if zero 5515 fde7 c6 56 dec colcrs+1 5516 fde9 10 06 bpl draw7 ;(unconditional) 5517 fdeb e6 55 draw6b: inc colcrs ;do double byte increment 5518 fded d0 02 bne draw7 5519 fdef e6 56 inc colcrs+1 5520 fdf1 a2 02 draw7: ldx #2 ;and subtract endpt from colac 5521 fdf3 20 7a fa jsr subend 5522 fdf6 20 96 fa draw8: jsr range 5523 fdf9 20 e0 f5 jsr outplt ;plot point 5524 fdfc ad b7 02 lda filflg ;test right fill 5525 fdff f0 2f beq draw9 5526 fe01 20 9d fc jsr phacrs 5527 fe04 ad fb 02 lda atachr 5528 fe07 8d bc 02 sta hold4 5529 fe0a a5 54 draw8a: lda rowcrs ;save row in case of CR 5530 fe0c 48 pha 5531 fe0d 20 dc f9 jsr incrsa ;position cursor one past dot 5532 fe10 68 pla ;restore rowcrs 5533 fe11 85 54 sta rowcrs 5534 fe13 20 96 fa draw8c: jsr range 5535 fe16 20 a2 f5 jsr getplt ;get data 5536 fe19 d0 0c bne draw8b ;stop if non-zero data is encountered 5537 fe1b ad fd 02 lda fildat ;fill data 5538 fe1e 8d fb 02 sta atachr 5539 fe21 20 e0 f5 jsr outplt ;draw it 5540 fe24 4c 0a fe jmp draw8a ;loop 5541 fe27 ad bc 02 draw8b: lda hold4 5542 fe2a 8d fb 02 sta atachr 5543 fe2d 20 a8 fc jsr placrs 5544 fe30 38 draw9: sec ;do double byte subtract \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 123 5545 fe31 a5 7e lda countr 5546 fe33 e9 01 sbc #1 5547 fe35 85 7e sta countr 5548 fe37 a5 7f lda countr+1 5549 fe39 e9 00 sbc #0 5550 fe3b 85 7f sta countr+1 5551 fe3d 30 03 bmi draw10 5552 fe3f 4c 90 fd jmp draw4a 5553 fe42 4c 34 f6 draw10: jmp retur1 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 124 5554 .page 5555 ; 5556 ; 5557 ; tables 5558 ; 5559 ; 5560 ; memory allocation 5561 ; 5562 fe45 18 10 0a 0a alocat: .byte 24,16,10,10,16,28,52,100,196,196,196,196 5563 fe49 10 1c 34 64 5564 fe4d c4 c4 c4 c4 5565 ; 5566 ; 5567 ; number of display list entries 5568 ; 5569 fe51 17 17 0b 17 numdle: .byte 23,23,11,23,47,47,95,95,97,97,97,97 5570 fe55 2f 2f 5f 5f 5571 fe59 61 61 61 61 5572 fe5d 13 13 09 13 mxdmde: .byte 19,19,9,19,39,39,79,79,65,65,65,65 ;(ext of numdle) 5573 fe61 27 27 4f 4f 5574 fe65 41 41 41 41 5575 ; 5576 ; 5577 ; ANTIC code from internal mode conversion table 5578 ; 5579 ; internal ANTIC code description 5580 ; 0 2 40x2x8 characters 5581 ; 1 6 20x5x8 "" 5582 ; 2 7 20x5x16 "" 5583 ; 3 8 40x4x8 graphics 5584 ; 4 9 80x2x4 "" 5585 ; 5 a 80x4x4 "" 5586 ; 6 b 160x2x2 "" 5587 ; 7 d 160x4x2 "" 5588 ; 8 f 320x2x1 "" 5589 ; 9 same as 8 but GTIA 'lum' mode 5590 ; 10 same as 8 but GTIA 'col/lum register' mode 5591 ; 11 same as 8 but GTIA 'color' mode 5592 ; 5593 fe69 02 06 07 08 anconv: .byte 2,6,7,8,9,$a,$b,$d,$f,$f,$f,$f ;zeros for range test in 5594 fe6d 09 0a 0b 0d 5595 fe71 0f 0f 0f 0f 5596 ; 5597 ; 5598 ; page table tells which display lists are in danger of 5599 ; crossing a 256 byte page boundary 5600 ; 5601 fe75 00 00 00 00 pagetb: .byte 0,0,0,0,0,0,0,1,1,1,1,1 5602 fe79 00 00 00 01 5603 fe7d 01 01 01 01 5604 ; 5605 ; 5606 ; this is the number of left shifts needed to multiply 5607 ; colcrs by 10,20, or 40. (rowcrs*10)/(2**dhline) \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 125 5608 ; 5609 fe81 02 01 01 00 dhline: .byte 2,1,1,0,0,1,1,2,2,2,2,2 5610 fe85 00 01 01 02 5611 fe89 02 02 02 02 5612 ; 5613 ; 5614 ; column: number of columns 5615 ; 5616 fe8d 28 14 14 28 column: .byte 40,20,20,40,80,80,160,160,64,80,80,80 ;mode 8 is special 5617 fe91 50 50 a0 a0 5618 fe95 40 50 50 50 5619 ; 5620 ; 5621 ; 5622 ; norows: number of rows 5623 ; 5624 fe99 18 18 0c 18 norows: .byte 24,24,12,24,48,48,96,96,192,192,192,192 5625 fe9d 30 30 60 60 5626 fea1 c0 c0 c0 c0 5627 ; 5628 ; 5629 ; 5630 ; 5631 ; div2tb: how many right shifts for hcrsr for partial byte modes 5632 ; 5633 fea5 00 00 00 02 div2tb: .byte 0,0,0,2,3,2,3,2,3,1,1,1 5634 fea9 03 02 03 02 5635 fead 03 01 01 01 5636 ; 5637 ; 5638 ; dmaskt: display mask table 5639 ; 5640 feb1 00 ff f0 0f dmaskt: .byte $00,$ff,$f0,$0f 5641 feb5 c0 30 0c 03 .byte $c0,$30,$0c,$03 5642 ; 5643 ; masktb: bit mask. (also part of dmasktb! do not separate) 5644 ; 5645 feb9 80 40 20 10 masktb: .byte $80,$40,$20,$10,$08,$04,$02,$01 5646 febd 08 04 02 01 5647 ; 5648 ; 5649 ; 5650 ; 5651 fec1 28 ca 94 46 colrtb: .byte $28,$ca,$94,$46,$00 5652 fec5 00 5653 ; 5654 ; 5655 ; 5656 ; 5657 ; cntrls: control codes and their displacements into the 5658 ; control character processors 5659 ; 5660 fec6 1b cntrls: .byte $1b 5661 fec7 79 f7 .word escape \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 126 5662 fec9 1c .byte $1c 5663 feca 7f f7 .word crsrup 5664 fecc 1d .byte $1d 5665 fecd 8c f7 .word crsrdn 5666 fecf 1e .byte $1e 5667 fed0 99 f7 .word crsrlf 5668 fed2 1f .byte $1f 5669 fed3 aa f7 .word crsrrt 5670 fed5 7d .byte $7d 5671 fed6 b9 f7 .word clrscr 5672 fed8 7e .byte $7e 5673 fed9 e6 f7 .word bs 5674 fedb 7f .byte $7f 5675 fedc 10 f8 .word tab 5676 fede 9b .byte $9b 5677 fedf 30 fa .word docrws 5678 fee1 9c .byte $9c 5679 fee2 d4 f8 .word dellin 5680 fee4 9d .byte $9d 5681 fee5 a4 f8 .word inslin 5682 fee7 9e .byte $9e 5683 fee8 32 f8 .word clrtab 5684 feea 9f .byte $9f 5685 feeb 2d f8 .word settab 5686 feed fd .byte $fd 5687 feee 0a f9 .word bell 5688 fef0 fe .byte $fe 5689 fef1 6d f8 .word delchr 5690 fef3 ff .byte $ff 5691 fef4 37 f8 .word inschr 5692 ; 5693 ; 5694 ; 5695 ; 5696 ; 5697 ; ataint: atasci to internal table 5698 ; 5699 fef6 40 00 20 60 ataint: .byte $40,$00,$20,$60 5700 ; 5701 ; 5702 ; intata: internal to atasci table 5703 ; 5704 fefa 20 40 00 60 intata: .byte $20,$40,$00,$60 5705 ; 5706 ; 5707 ; atasci: atascii conversion table 5708 ; 5709 fefe 6c 6a 3b 80 atasci: .byte $6c,$6a,$3b,$80,$80,$6b,$2b,$2a ;lower case 5710 ff02 80 6b 2b 2a 5711 ff06 6f 80 70 75 .byte $6f,$80,$70,$75,$9b,$69,$2d,$3d 5712 ff0a 9b 69 2d 3d 5713 ff0e 5714 ff0e 76 80 63 80 .byte $76,$80,$63,$80,$80,$62,$78,$7a 5715 ff12 80 62 78 7a \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 127 5716 ff16 34 80 33 36 .byte $34,$80,$33,$36,$1b,$35,$32,$31 5717 ff1a 1b 35 32 31 5718 ff1e 5719 ff1e 2c 20 2e 6e .byte $2c,$20,$2e,$6e,$80,$6d,$2f,$81 5720 ff22 80 6d 2f 81 5721 ff26 72 80 65 79 .byte $72,$80,$65,$79,$7f,$74,$77,$71 5722 ff2a 7f 74 77 71 5723 ff2e 5724 ff2e 39 80 30 37 .byte $39,$80,$30,$37,$7e,$38,$3c,$3e 5725 ff32 7e 38 3c 3e 5726 ff36 66 68 64 80 .byte $66,$68,$64,$80,$82,$67,$73,$61 5727 ff3a 82 67 73 61 5728 ff3e 5729 ff3e 5730 ff3e 4c 4a 3a 80 .byte $4c,$4a,$3a,$80,$80,$4b,$5c,$5e ;upper case 5731 ff42 80 4b 5c 5e 5732 ff46 4f 80 50 55 .byte $4f,$80,$50,$55,$9b,$49,$5f,$7c 5733 ff4a 9b 49 5f 7c 5734 ff4e 5735 ff4e 56 80 43 80 .byte $56,$80,$43,$80,$80,$42,$58,$5a 5736 ff52 80 42 58 5a 5737 ff56 24 80 23 26 .byte $24,$80,$23,$26,$1b,$25,$22,$21 5738 ff5a 1b 25 22 21 5739 ff5e 5740 ff5e 5b 20 5d 4e .byte $5b,$20,$5d,$4e,$80,$4d,$3f,$81 5741 ff62 80 4d 3f 81 5742 ff66 52 80 45 59 .byte $52,$80,$45,$59,$9f,$54,$57,$51 5743 ff6a 9f 54 57 51 5744 ff6e 5745 ff6e 28 80 29 27 .byte $28,$80,$29,$27,$9c,$40,$7d,$9d 5746 ff72 9c 40 7d 9d 5747 ff76 46 48 44 80 .byte $46,$48,$44,$80,$83,$47,$53,$41 5748 ff7a 83 47 53 41 5749 ff7e 5750 ff7e 5751 ff7e 0c 0a 7b 80 .byte $0c,$0a,$7b,$80,$80,$0b,$1e,$1f ;control 5752 ff82 80 0b 1e 1f 5753 ff86 0f 80 10 15 .byte $0f,$80,$10,$15,$9b,$09,$1c,$1d 5754 ff8a 9b 09 1c 1d 5755 ff8e 5756 ff8e 16 80 03 80 .byte $16,$80,$03,$80,$80,$02,$18,$1a 5757 ff92 80 02 18 1a 5758 ff96 80 80 85 80 .byte $80,$80,$85,$80,$1b,$80,$fd,$80 5759 ff9a 1b 80 fd 80 5760 ff9e 5761 ff9e 00 20 60 0e .byte $00,$20,$60,$0e,$80,$0d,$80,$81 5762 ffa2 80 0d 80 81 5763 ffa6 12 80 05 19 .byte $12,$80,$05,$19,$9e,$14,$17,$11 5764 ffaa 9e 14 17 11 5765 ffae 5766 ffae 80 80 80 80 .byte $80,$80,$80,$80,$fe,$80,$7d,$ff 5767 ffb2 fe 80 7d ff 5768 ffb6 06 08 04 80 .byte $06,$08,$04,$80,$84,$07,$13,$01 5769 ffba 84 07 13 01 \newpage err line addr b1 b2 b3 b4 display handler -- 10-30-78 -- displc page 128 5770 ; 5771 ; 5772 ; 5773 ; 5774 ; 5775 ffbe ad 09 d2 pirq5: lda kbcode 5776 ffc1 cd f2 02 cmp ch1 ;test against last key pressed 5777 ffc4 d0 05 bne pirq3 ;if not, go process key 5778 ffc6 ad f1 02 lda keydel ;if key delay byte > 0 5779 ffc9 d0 20 bne pirq4 ;ignore key as bounce 5780 ffcb ad 09 d2 pirq3: lda kbcode ;restore ac 5781 ffce c9 9f cmp #cntl1 ;test control 1 (ssflag) 5782 ffd0 d0 0a bne pirq1 5783 ffd2 ad ff 02 lda ssflag 5784 ffd5 49 ff eor #$ff 5785 ffd7 8d ff 02 sta ssflag 5786 ffda b0 0f bcs pirq4 ;(unconditional) make ^1 invisible 5787 ffdc 8d fc 02 pirq1: sta ch 5788 ffdf 8d f2 02 sta ch1 5789 ffe2 a9 03 lda #3 5790 ffe4 8d f1 02 sta keydel ;initialize key delay for debounce 5791 ffe7 a9 00 lda #0 ;clear color shift byte 5792 ffe9 85 4d sta atract 5793 ffeb a9 30 pirq4: lda #$30 5794 ffed 8d 2b 02 sta srtimr 5795 fff0 68 pirq2: pla 5796 fff1 40 rti 5797 ; 5798 ; 5799 fff2 ff ff ff ff .byte $ff,$ff,$ff,$ff,$ff,$ff 5800 fff6 ff ff 5801 ; 5802 fff8 crntpc =* 5803 *=$14 5804 0014 00 kbdspr: .byte $fff8-crntpc ;^gdisplc is too long 5805 0015 .end assembly errors = 0