1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 ; PacAlpaca.asm 3 ; 4 ; ALPACA: A Multitasking operating system for Pac-Man Z80 arcade hardware 5 ; 6 ; Written by 7 ; Scott "Jerry" Lawrence 8 ; alpaca@umlautllama.com 9 ; 10 ; This source file is covered by the LGPL: 11 ; 12 ;; Alpaca - A Multitasking operating system for Z80 arcade hardware 13 ;; Copyright (C) 2003 Scott "Jerry" Lawrence 14 ;; alpaca@umlautllama.com 15 ;; 16 ;; This is free software; you can redistribute it and/or modify 17 ;; it under the terms of the GNU Lesser General Public License 18 ;; as published by the Free Software Foundation; either version 19 ;; 2 of the License, or (at your option) any later version. 20 ;; 21 ;; This software is distributed in the hope that it will be 22 ;; useful, but WITHOUT ANY WARRANTY; without even the implied 23 ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 24 ;; PURPOSE. See the GNU Lesser General Public License for 25 ;; more details. 26 ;; 27 ;; You should have received a copy of the GNU Lesser General 28 ;; Public License along with this library; if not, write to 29 ;; the Free Foundation, Inc., 59 Temple Place, Suite 330, 30 ;; Boston, MA 02111-1307 USA 31 ; 32 33 34 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 35 ; 36 ; This file is machine generated. Do not edit it by hand! 37 ; 38 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 39 40 41 .title alpaca 42 .module alpaca 43 44 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 45 ; some constants: 4FF0 46 stack = 0x4ff0 4000 47 vidram = 0x4000 4400 48 colram = 0x4400 4C00 49 ram = 0x4c00 5080 50 dsw0 = 0x5080 5040 51 in1 = 0x5040 5000 52 in0 = 0x5000 5000 53 specreg = 0x5000 00C0 54 speclen = 0x00C0 4FF0 55 sprtbase = 0x4ff0 0010 56 sprtlen = 0x0010 5000 57 p1_port = in0 0000 58 p1_up = 0 0001 59 p1_left = 1 0002 60 p1_right = 2 0003 61 p1_down = 3 5040 62 p2_port = in1 0000 63 p2_up = 0 0001 64 p2_left = 1 0002 65 p2_right = 2 0003 66 p2_down = 3 5040 67 start_port = in1 0005 68 start1 = 5 0006 69 start2 = 6 5000 70 coin_port = in0 0005 71 coin1 = 5 0006 72 coin2 = 6 0007 73 coin3 = 7 5000 74 rack_port = in0 0004 75 racktest = 4 5040 76 svc_port = in1 0004 77 service = 4 5040 78 cab_port = in1 0007 79 cabinet = 7 0004 80 sprtMult = 4 0001 81 sprtColor = 1 0000 82 sprtIndex = 0 0000 83 sprtXFlip = 0 0000 84 bitXFlip = 0 0001 85 valXFlip = 1 0000 86 sprtYFlip = 0 0001 87 bitYFlip = 1 0002 88 valYFlip = 2 4FF0 89 spritebase = 0x4ff0 0008 90 nsprites = 0x08 5060 91 spritecoords = 0x5060 5040 92 v1_acc = 0x5040 5045 93 v1_wave = 0x5045 5050 94 v1_freq = 0x5050 5055 95 v1_vol = 0x5055 5046 96 v2_acc = 0x5046 504A 97 v2_wave = 0x504a 5056 98 v2_freq = 0x5056 505A 99 v2_vol = 0x505a 504B 100 v3_acc = 0x504b 504F 101 v3_wave = 0x504f 505B 102 v3_freq = 0x505b 505F 103 v3_vol = 0x505f 5000 104 irqen = 0x5000 5001 105 sounden = 0x5001 5003 106 flipscreen = 0x5003 5007 107 coincount = 0x5007 50C0 108 watchdog = 0x50C0 109 110 ; constants for the task system 00C0 111 stacksize = 192 ; number of bytes per stack 0004 112 slotTicks = 4 ; number of ticks per slot to start with 113 114 115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 ; RAM allocation: 117 ; which task is in which slot (index into tasklist) 4C00 118 slotIdx = (ram + 0) ; 4 bytes, one per slot 4C00 119 slotIdx0 = (ram + 0) 4C01 120 slotIdx1 = (ram + 1) 4C02 121 slotIdx2 = (ram + 2) 4C03 122 slotIdx3 = (ram + 3) 00FF 123 slotOpen = 0xff 124 ; control information for each slot (to be handled by switcher) 4C04 125 slotCtrl = (ram + 4) ; 4 bytes, one per slot 4C04 126 slot0Ctrl = (ram + 4) 4C05 127 slot1Ctrl = (ram + 5) 4C06 128 slot2Ctrl = (ram + 6) 4C07 129 slot3Ctrl = (ram + 7) 0007 130 C_InUse = 7 0004 131 C_EXT0 = 4 0000 132 killSlot = 0 0001 133 execSlot = 1 0002 134 sleepSlot = 2 135 ; stack pointers for the four slots 4C08 136 slotSP = (ram + 8) ; 8 bytes, two per slot 4C08 137 slotSP0 = (ram + 8) 4C0A 138 slotSP1 = (ram + 10) 4C0C 139 slotSP2 = (ram + 12) 4C0E 140 slotSP3 = (ram + 14) 141 ; Base of ram for the currently active slot. 4C10 142 ramBase = (ram + 16) ; word 143 ; various flags about the task switcher system 4C12 144 taskFlag = (ram + 18) ; byte 0000 145 slot0use = 0 0001 146 slot1use = 1 0002 147 slot2use = 2 0003 148 slot3use = 3 0007 149 taskActive = 7 150 ; the currently active slot number 4C13 151 taskSlot = (ram + 19) ; byte 152 ; how many ticks does this slot have before it gets swapped out 4C14 153 slotTime = (ram + 20) ; byte 154 ; timer counter (word) 4C15 155 timer = (ram + 21) 156 ; random assistance register (byte) 4C17 157 randval = (ram + 23) 158 ; messages 58A0 159 msgbase = (ram + 0x0ca0) 58DF 160 msgmax = (msgbase + 0x003f) 161 ; semaphores 58E0 162 semabase = (ram + 0x0ce0) 58EF 163 semamax = (semabase + 0x0F) 164 ; stack regions for the four tasks 4CF0 165 stackbottom = (stack-(stacksize*4)) ; 192 bytes (bottom of stack 3) 4DB0 166 stack3 = (stack-(stacksize*3)) ; 192 bytes 4E70 167 stack2 = (stack-(stacksize*2)) ; 192 bytes 4F30 168 stack1 = (stack-(stacksize*1)) ; 192 bytes 4FF0 169 stack0 = (stack-(0)) ; top of space - sprite ram 170 171 172 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 173 ; area configuration 174 ; we want absolute dataspace, with this area called "CODE" 175 .area .CODE (ABS) 176 177 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 178 ; RST functions 179 180 ; RST 00 181 .org 0x000 0000 182 .reset00: ; RST 00 - Init 0000 C3 FC 00 183 jp .start 184 185 ; RST 08 186 .org 0x0008 0008 187 .reset08: ; RST 08 - Semaphore control 0008 C9 188 ret 189 190 ; RST 10 191 .org 0x0010 0010 192 .reset10: ; RST 10 - TBD 0010 C9 193 ret 194 195 ; RST 18 196 .org 0x0018 0018 197 .reset18: ; RST 18 - TBD 0018 C9 198 ret 199 200 ; RST 20 201 .org 0x0020 0020 202 .reset20: ; RST 20 - TBD 0020 C9 203 ret 204 205 ; RST 28 206 .org 0x0028 0028 207 .reset28: ; RST 28 - TBD 0028 C9 208 ret 209 210 ; RST 30 211 .org 0x0030 0030 212 .reset30: ; RST 30 - TBD 0030 C9 213 ret 214 215 ; RST 38 216 .org 0x0038 0038 217 .reset38: ; RST 38 - Vblank Interrupt Service Routine 0038 C3 68 00 218 jp .isr 219 220 ; NMI 221 .org 0x0066 0066 222 .nmi: ; NMI handler 0066 ED 45 223 retn 224 225 226 227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 228 ; interrupt service routine: 0068 229 .isr: 0068 F3 230 di ; disable interrupts (no re-entry!) 0069 F5 231 push af ; store aside some registers 006A AF 232 xor a ; a = 0 006B 32 00 50 233 ld (irqen), a ; disable external interrupt mechanism 006E C5 234 push bc 006F D5 235 push de 0070 E5 236 push hl 0071 DD E5 237 push ix 0073 FD E5 238 push iy 0075 32 C0 50 239 ld (watchdog), a ; kick the dog 0078 ED 4B 15 4C 240 ld bc, (timer) ; bc = timer 007C 03 241 inc bc ; bc++ 007D ED 43 15 4C 242 ld (timer), bc ; timer = bc 243 ;; task management stuff 244 ; check for disabled switching 0081 2A 12 4C 245 ld hl, (taskFlag) 0084 CB 7E 246 bit #taskActive, (hl) ; check to see if task switching is on 0086 28 64 247 jr Z, .doneTask ; jp over if switching is disabled 248 ; check to see if any of the control flags are set 249 ; loop throgh all slots 250 ; check for kill 251 ; check for sleep 252 ; check for start 253 ;; check to see if we need to task switch yet 0088 21 14 4C 254 ld hl, #slotTime ; hl = time address 008B 4E 255 ld c, (hl) ; c = current time for active slot 256 ; check the current value 008C AF 257 xor a ; a = 0 008D B9 258 cp c ; is C >=0? ( Carry set ) 008E DA E6 00 259 jp C, .noSwitch ; still greater than zero? 260 ;; change to next dormant task (or this one...) 0091 261 .tsNext: 0091 3A 13 4C 262 ld a, (taskSlot) ; a = current task slot (a is try) 0094 5F 263 ld e, a ; de = current slot 0095 264 .tsloop1: 0095 3C 265 inc a ; ++try 0096 E6 00 266 and a, #slotMask ; try &= 0x03 0098 21 04 4C 267 ld hl, #(slotCtrl) ; hl = slotCtrl base 009B 4F 268 ld c, a 009C 06 00 269 ld b, #0x00 ; bc = task number 009E 09 270 add hl, bc ; hl = control for this task 009F CB 7E 271 bit #C_InUse, (hl) ; check the flag 00A1 20 F2 272 jr NZ, .tsloop1 ; if not active, inc again 273 ; compare selected task with "current" 00A3 7B 274 ld a, e ; A = current (again) 00A4 B9 275 cp c ; compare A(curr) and C(try) 00A5 28 3A 276 jr Z, .overslot1 ; skip this next bit if we're there 00A7 277 .storeTheSP: 278 ; snag the SP into IX 00A7 DD 21 00 00 279 ld ix, #0x0000 ; zero ix 00AB DD 39 280 add ix, sp ; ix = SP 281 282 ; setup HL as ram location to store SP 00AD 21 08 4C 283 ld hl, #(slotSP) ; hl = base of slotSP array 00B0 16 00 284 ld d, #0x00 ; de = current slot 00B2 CB 03 285 rlc e ; = current slot * 2 286 ; bc still contains the try value 00B4 19 287 add hl, de ; hl = base of current slot SP 00B5 DD E5 288 push ix ; de 00B7 D1 289 pop de ; = SP 290 ; store the current SP 00B8 73 291 ld (hl), e ; (hl) = 00B9 23 292 inc hl 00BA 72 293 ld (hl), d ; = de (really SP) 00BB 294 .loadInTheSP: 295 ; swap in the new SP 00BB 16 00 296 ld d, #0 00BD 59 297 ld e, c ; de = new slot number 00BE CB 03 298 rlc e ; = new slot number * 2 00C0 21 08 4C 299 ld hl, #(slotSP) ; hl = base of slotSP array 00C3 19 300 add hl, de ; hl = base of new slot SP 301 ; snag it and shove it into place 00C4 5E 302 ld e, (hl) ; de = 00C5 23 303 inc hl 00C6 56 304 ld d, (hl) ; = new sp 00C7 62 305 ld h, d ; hl = 00C8 6B 306 ld l, e ; = sp 00C9 F9 307 ld sp, hl ; new SP! 00CA 308 .setupVars: 309 ; set up reference variables 00CA 79 310 ld a, c ; a = c 00CB 32 13 4C 311 ld (taskSlot), a ; taskSlot = new slot number 312 ; set up ramBase 00CE 21 00 00 313 ld hl, #(stackList) ; hl = base of stackList array 00D1 59 314 ld e, c ; e = new slot 00D2 1C 315 inc e ; e = new slot + 1 00D3 CB 03 316 rlc e ; e = (new slot + 1) * 2 00D5 16 00 317 ld d, #0 ; de = (new slot + 1) * 2 00D7 19 318 add hl, de ; = index of this slot + 1 word 00D8 4E 319 ld c, (hl) ; bc = 00D9 23 320 inc hl 00DA 46 321 ld b, (hl) ; = new ramBase item 00DB 21 10 4C 322 ld hl, #(ramBase) 00DE 71 323 ld (hl), c ; ramBase = 00DF 23 324 inc hl 00E0 70 325 ld (hl), b ; = correct value! 00E1 326 .overslot1: 00E1 21 14 4C 327 ld hl, #slotTime ; hl = time address 00E4 36 04 328 ld (hl), #slotTicks ; reset the ticks for this task 00E6 329 .noSwitch: 330 ; decrement the slot timer 00E6 21 14 4C 331 ld hl, #slotTime ; hl = time address 00E9 4E 332 ld c, (hl) ; c = current time for active slot 00EA 0D 333 dec c ; current time -- 00EB 71 334 ld (hl), c ; store the current time 00EC 335 .doneTask: 336 ; restore the registers 00EC FD E1 337 pop iy 00EE DD E1 338 pop ix 00F0 E1 339 pop hl 00F1 D1 340 pop de 00F2 C1 341 pop bc 00F3 3E 01 342 ld a, #0x01 ; a = 1 00F5 32 00 50 343 ld (irqen), a ; enable external interrupt mechanism 00F8 F1 344 pop af 00F9 FB 345 ei ; enable processor interrupts 00FA ED 4D 346 reti ; return from interrupt routine 347 348 349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 350 ; the core OS stuff: 351 ; initialization and splash screen 00FC 352 .start: 00FC F3 353 di ; disable processor interrupts 00FD 31 F0 4F 354 ld sp, #(stack) ; setup the initial stack pointer 0100 ED 56 355 im 1 ; setup interrupt mode 1 356 357 ;; clear the special registers 0102 3E 00 358 ld a, #0x00 ; a = 0x00 0104 21 00 50 359 ld hl, #(specreg) ; hl = start of special registers 0107 06 C0 360 ld b, #(speclen) ; b = 0xC0 bytes to zero 0109 CD ED 01 361 call memset256 ; 0x5000-0x50C0 will get 0x00 362 363 ;; clear sprite registers 010C 3E 00 364 ld a, #0x00 ; a = 0x00 010E 21 F0 4F 365 ld hl, #(sprtbase) ; hl = start of sprite registers 0111 06 10 366 ld b, #(sprtlen) ; b = 0x10 16 bytes 0113 CD ED 01 367 call memset256 ; 0x4ff0-0x4fff will get 0x00 368 369 ;; clear the screen ram 0116 CD FC 01 370 call cls ; clear the screen RAM 371 372 ;; clear user ram 0119 21 00 4C 373 ld hl, #(ram) ; hl = base of RAM 011C 3E 03 374 ld a, #0x03 ; a = 0 011E 06 02 375 ld b, #0x02 ; b = 2 blocks of 256 bytes to clear 0120 CD F2 01 376 call memsetN ; clear the blocks 377 378 ;; initialize tasks 379 ; clear flags 0123 AF 380 xor a ; a = 0 0124 32 12 4C 381 ld (taskFlag), a ; clear all task flags 382 ; clear the dormant stack pointers (set all four to 0x0000) 0127 AF 383 xor a ; a = 0 0128 06 08 384 ld b, #8 ; 8 bytes (4 one-word variables) 012A 21 08 4C 385 ld hl, #(slotSP) ; base of slot stack pointers 012D CD ED 01 386 call memset256 ; clear it 387 ; set all slots as open 0130 3E FF 388 ld a, #(slotOpen) ; a = openslot 0132 06 04 389 ld b, #4 ; 4 bytes 0134 21 00 4C 390 ld hl, #(slotIdx) ; base of slot index bytes 0137 CD ED 01 391 call memset256 392 ; clear control bytes 013A AF 393 xor a ; a = 0 013B 06 04 394 ld b, #4 ; 4 bytes 013D 21 04 4C 395 ld hl, #(slotCtrl) ; base of slot control bytes 0140 CD ED 01 396 call memset256 397 ; clear taskSlot 0143 AF 398 xor a ; a = 0 0144 32 13 4C 399 ld (taskSlot), a ; taskSlot = 0 400 ; enable the task switcher 0147 2A 12 4C 401 ld hl, (taskFlag) 014A CB FE 402 set #taskActive, (hl) ; set the flag 403 ;; setup pac interrupts 014C 3E FF 404 ld a, #0xff ; fill register 'a' with 0xff 014E D3 00 405 out (0x00), a ; send the 0xff to port 0x00 0150 3E 01 406 ld a, #0x01 ; fill register 'a' with 0x01 0152 32 00 50 407 ld (irqen), a ; enable the external interrupt mechanism. 0155 FB 408 ei 409 410 ; Splash screen! 0156 411 .splash: 0156 CD 0D 02 412 call guicls 413 414 ; draw out the llama! 0159 21 7D 04 415 ld hl, #(llama1) ; top half of llama 015C 01 09 0D 416 ld bc, #0x0d09 015F 3E 10 417 ld a, #(LlamaC) 0161 CD EA 02 418 call putstrB 0164 21 80 04 419 ld hl, #(llama2) ; bottom half of llama 0167 0C 420 inc c 0168 CD EA 02 421 call putstrB 422 423 ; draw out the copyright notice and version info 016B 21 83 04 424 ld hl, #(cprt1) 016E 01 0F 06 425 ld bc, #0x060f 0171 3E 00 426 ld a, #0x00 ; black text 0173 CD EA 02 427 call putstrB ; top black border 428 0176 01 11 06 429 ld bc, #0x0611 0179 CD EA 02 430 call putstrB ; bottom black border 431 017C 21 83 04 432 ld hl, #(cprt1) 017F 3E 14 433 ld a, #0x14 ; yellow text 0181 01 10 06 434 ld bc, #0x0610 0184 CD EA 02 435 call putstrB ; 'Alpaca OS...' 436 0187 21 94 04 437 ld hl, #(cprt2) 018A 3E 0B 438 ld a, #0x0b ; cyan text 018C 01 1E 04 439 ld bc, #0x041e 018F CD EA 02 440 call putstrB ; '(C) 2003... 441 0192 21 A9 04 442 ld hl, #(cprt3) 0195 01 00 02 443 ld bc, #0x0200 0198 CD 21 03 444 call putstrC ; email addy 445 446 ; the core task 019B 447 .coretask: 448 ; set up sprite 1 as the flying llama 019B DD 21 F0 4F 449 ld ix, #(sprtbase) 019F 3E 08 450 ld a, #(LlamaFS*sprtMult) 01A1 DD 77 00 451 ld sprtIndex(ix), a 01A4 3E 03 452 ld a, #(3) ; decent llama color 01A6 DD 77 01 453 ld sprtColor(ix), a 454 455 ;; set up sprite 2 and 3 01A9 DD 21 F0 4F 456 ld ix, #(sprtbase) 01AD 3E 04 457 ld a, #4 ;(hardcoded for now) 01AF DD 77 02 458 ld 2+sprtIndex(ix), a 01B2 DD 77 04 459 ld 4+sprtIndex(ix), a 01B5 3E 03 460 ld a, #(3) ;0x12 01B7 DD 77 03 461 ld 2+sprtColor(ix), a 01BA DD 77 05 462 ld 4+sprtColor(ix), a 463 01BD 464 foo: 465 ; do a lissajous on the screen with the first sprite (arrow cursor) 466 ;; X 01BD DD 21 60 50 467 ld ix, #(spritecoords) 01C1 ED 4B 15 4C 468 ld bc, (timer) 01C5 CB 01 469 rlc c ; *2 01C7 CB 01 470 rlc c ; *2 01C9 CD 46 02 471 call sine 01CC 0F 472 rrca 01CD E6 7F 473 and #0x7f 01CF C6 40 474 add #0x40 01D1 DD 77 00 475 ld sprtIndex(ix), a 476 ;; Y 01D4 ED 4B 15 4C 477 ld bc, (timer) 478 ;rlc c 01D8 CD 52 02 479 call cosine 01DB 0F 480 rrca 01DC E6 7F 481 and #0x7f 01DE C6 40 482 add #0x40 01E0 DD 77 01 483 ld sprtColor(ix), a 484 485 ; try to hug a screen refresh 01E3 01 01 00 486 ld bc, #1 01E6 CD 7A 03 487 call sleep 488 01E9 C3 BD 01 489 jp foo 01EC 76 490 halt 491 492 493 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 494 ; some helpful utility functions 495 496 ; memset256 497 ;; memset256 - set up to 256 bytes of ram to a certain value 498 ; in a value to poke 499 ; in b number of bytes to set 0x00 for 256 500 ; in hl base address of the memory location 501 ; out - 502 ; mod hl, bc 01ED 503 memset256: 01ED 77 504 ld (hl), a ; *hl = 0 01EE 23 505 inc hl ; hl++ 01EF 10 FC 506 djnz memset256 ; decrement b, jump to memset256 if b>0 01F1 C9 507 ret ; return 508 509 510 ; memsetN 511 ;; memsetN - set N blocks of ram to a certain value 512 ; in a value to poke 513 ; in b number of blocks to set 514 ; in hl base address of the memory location 515 ; out - 516 ; mod hl, bc 01F2 517 memsetN: 01F2 C5 518 push bc ; set aside bc 01F3 06 00 519 ld b, #0x00 ; b = 256 01F5 CD ED 01 520 call memset256 ; set 256 bytes 01F8 C1 521 pop bc ; restore the outer bc 01F9 10 F7 522 djnz memsetN ; if we're not done, set another chunk. 01FB C9 523 ret ; otherwise return 524 525 526 ; clear screen 527 ;; cls - clear the screen (color and video ram) 528 ; in - 529 ; out - 530 ; mod - 01FC 531 cls: 01FC E5 532 push hl ; set aside some registers 01FD F5 533 push af 01FE C5 534 push bc 535 01FF 21 00 40 536 ld hl, #(vidram) ; base of video ram 0202 3E 00 537 ld a, #0x00 ; clear the screen to 0x00 0204 06 08 538 ld b, #0x08 ; need to set 256 bytes 8 times. 539 0206 CD F2 01 540 call memsetN ; do it. 541 0209 C1 542 pop bc ; restore the registers 020A F1 543 pop af 020B E1 544 pop hl 020C C9 545 ret ; return 546 547 ; clear screen (gui tile version) 548 ;; guicls - clear the screen to the GUI background 549 ; in - 550 ; out - 551 ; mod - 020D 552 guicls: 020D E5 553 push hl ; set aside some registers 020E F5 554 push af 020F C5 555 push bc 556 557 ; fill the screen with the background color 0210 21 00 44 558 ld hl, #(colram) ; color ram 0213 3E 10 559 ld a, #(PwpC) ; color 0215 06 04 560 ld b, #0x04 ; 4 blocks 0217 CD F2 01 561 call memsetN 562 563 ; fill the screen with the background tile 021A 21 00 40 564 ld hl, #(vidram) ; character ram 021D 3E A2 565 ld a, #(PwpS) ; background tile 021F 06 04 566 ld b, #0x04 ; 4 blocks 0221 CD F2 01 567 call memsetN 568 0224 C1 569 pop bc ; restore the registers 0225 F1 570 pop af 0226 E1 571 pop hl 0227 C9 572 ret ; return 573 574 575 ; rand 576 ;; rand - get a random number 577 ; in - 578 ; out a random number 0..256 579 ; mod flags 0228 580 rand: 581 ; set aside registers 0228 E5 582 push hl 0229 C5 583 push bc 584 ; compute a random number 022A 2A 17 4C 585 ld hl, (randval) ; hl = last random number 022D E5 586 push hl 022E C1 587 pop bc ; bc = hl 022F CD 46 02 588 call sine ; a = sine (c) 0232 4F 589 ld c, a ; c = sine ( last value ) 0233 590 .r01: 0233 ED 5F 591 ld a, r ; a = R 0235 81 592 add a, c ; a += sine( last value ) 0236 4F 593 ld c, a ; c = sine( last value ) + R 0237 594 .r02: 0237 09 595 add hl, bc ; rnd += sin ( last value ) + R 0238 ED 4B 15 4C 596 ld bc, (timer) 023C 09 597 add hl, bc ; rnd += timer 023D 22 17 4C 598 ld (randval), hl ; hl = computed random (rnd) 0240 3A 17 4C 599 ld a, (randval) ; a = rnd 600 ; restore registers 0243 C1 601 pop bc 0244 E1 602 pop hl 603 ; return 0245 C9 604 ret 605 606 607 ; sine 608 ;; sine - get the sine of a 609 ; in c value to look up 610 ; out a sine value 0..256 611 ; mod - 0246 612 sine: 613 ; set aside registers 0246 E5 614 push hl 0247 C5 615 push bc 616 ; look up the value in the sine table 0248 21 CC 04 617 ld hl, #(.sinetab) ; hl = sinetable base 024B 06 00 618 ld b, #0x00 ; b = 0 024D 09 619 add hl, bc ; hl += bc 024E 7E 620 ld a, (hl) ; a = sine(c) 621 ; restore registers 024F C1 622 pop bc 0250 E1 623 pop hl 624 ; return 0251 C9 625 ret 626 627 ; cosine 628 ;; cosine - get the cosine of a 629 ; in c value to look up 630 ; out a cosine value 0..256 631 ; mod f 0252 632 cosine: 633 ; set aside registers 0252 C5 634 push bc 635 ; add 180 degrees, call sine 0253 3E 3F 636 ld a, #0x3f 0255 81 637 add a, c 0256 4F 638 ld c, a 0257 CD 46 02 639 call sine 640 ; restore registers 025A C1 641 pop bc 642 ; return 025B C9 643 ret 644 645 646 ; text justification 647 ;; textcenter - adjust the x ordinate 648 ; in hl pascal string 649 ; in b x ordinate 650 ; in c y ordinate BC -> 0xXXYY 651 ; out - 652 ; mod b adjusted for center 000E 653 hscrwide = 14 025C 654 textcenter: 655 ; set aside registers 025C F5 656 push af 657 ; halve the width 025D 46 658 ld b, (hl) ; b = length of text 025E D2 62 02 659 jp NC, .tcrr ; make sure carry is cleared 0261 3F 660 ccf 0262 661 .tcrr: 0262 CB 18 662 rr b ; b = half of text length 663 ; add on the center position 0264 3E 0E 664 ld a, #hscrwide ; a = screenwidth/2 0266 90 665 sub b ; a = screenwidth/2 - textlength/2 0267 47 666 ld b, a ; b = that result 667 ; restore registers 0268 F1 668 pop af 669 ; return 0269 C9 670 ret 671 672 ;; textright - adjust the x ordinate 673 ; in hl pascal string 674 ; in b x ordinate 675 ; in c y ordinate BC -> 0xXXYY 676 ; out - 677 ; mod b adjusted for right 026A 678 textright: 679 ; set aside registers 026A F5 680 push af 681 ; halve the width 026B 78 682 ld a, b ; a = start location 026C 46 683 ld b, (hl) ; b = length of text 026D 90 684 sub b ; a = start loc - length 026E 47 685 ld b, a ; b = new position 686 ; restore registers 026F F1 687 pop af 688 ; return 0270 C9 689 ret 690 691 692 ; xy2offs 693 ;; xy2offsB - get the vid/color buffer offset of the X Y coordinates 694 ; in b x ordinate 695 ; in c y ordinate BC -> 0xXXYY 696 ; out hl offset 697 ; mod - 0271 698 xy2offsB: 699 ; set aside registers 0271 F5 700 push af 0272 C5 701 push bc 0273 D5 702 push de 0274 DD E5 703 push ix 704 ; set aside Y for later in DE 0276 16 00 705 ld d, #0x00 ; d = 0 0278 59 706 ld e, c ; shove Y into E 707 ; get the base offset 0279 DD 21 CC 05 708 ld ix, #(.scroffs) ; ix = offset table base 709 ; add in X component 710 ;; XXXXJJJJJ This can probably be shortened if we 711 ;; drop the range check. 027D 78 712 ld a, b ; shove X into A 027E E6 1F 713 and a, #0x1f ; make sure X is reasonable 0280 CB 07 714 rlc a ; x *= 2 0282 4F 715 ld c, a ; c = offset * 2 0283 06 00 716 ld b, #0x00 ; b = 0 0285 DD 09 717 add ix, bc ; ix += bc 718 ; retrieve that value into HL 0287 DD 46 01 719 ld b, 1(ix) 028A DD 4E 00 720 ld c, 0(ix) 028D C5 721 push bc 028E E1 722 pop hl ; hl = scroffs[x] 723 ; add in Y component 028F 19 724 add hl, de ; hl += DE hl = scroffs[x]+y 725 ; restore registers 0290 DD E1 726 pop ix 0292 D1 727 pop de 0293 C1 728 pop bc 0294 F1 729 pop af 730 ; return 0295 C9 731 ret 732 733 ;; xy2offAC - get the vid/color buffer offset of the X Y coordinates 734 ; in b x ordinate 735 ; in c y ordinate BC -> 0xXXYY 736 ; out hl offset 737 ; mod - 0296 738 xy2offsAC: 739 ; set aside registers 0296 C5 740 push bc 0297 D5 741 push de 0298 DD E5 742 push ix 743 ; generate the X component into DE 029A 16 00 744 ld d, #0x00 ; d = 0 029C 58 745 ld e, b ; e = X 746 ; get the base offset 029D DD 21 04 06 747 ld ix, #(.acoffs) ; ix = offset table base 748 ; add in the y component. (BC) 02A1 06 00 749 ld b, #0x00 ; zero B (top of BC) 02A3 CB 01 750 rlc c ; y *= 2 02A5 DD 09 751 add ix, bc ; offset += index 752 ; retrieve that value into HL 02A7 DD 46 01 753 ld b, 1(ix) 02AA DD 4E 00 754 ld c, 0(ix) 02AD C5 755 push bc 02AE E1 756 pop hl ; hl = acroffs[x] 757 ; subtract out the X component. 02AF ED 52 758 sbc hl, de ; hl -= DE hl = acoffs[y]-x 759 ; restore registers 02B1 DD E1 760 pop ix 02B3 D1 761 pop de 02B4 C1 762 pop bc 763 ; return 02B5 C9 764 ret 765 766 767 ; putstr 768 ;; putstrA - get the vid/color buffer offset of the X Y coordinates 769 ; in hl pointer to the string (asciz) 770 ; in b x position 771 ; in c y position 772 ; in a color 773 ; out - 774 ; mod - 02B6 775 putstrA: 776 ; set aside registers 02B6 C5 777 push bc 02B7 778 .psChook: ; this is where putstrC joins in... 02B7 E5 779 push hl 02B8 D5 780 push de 02B9 DD E5 781 push ix 02BB FD E5 782 push iy 783 ; compute the offsets 02BD E5 784 push hl ; set aside the string pointer 02BE CD 96 02 785 call xy2offsAC 02C1 E5 786 push hl 02C2 DD E1 787 pop ix ; move the offset into ix (char ram) 02C4 E5 788 push hl 02C5 FD E1 789 pop iy ; move the offset into iy (color ram) 02C7 11 00 40 790 ld de, #(vidram) ; base of video ram 02CA DD 19 791 add ix, de ; set IX to appropriate location in vid ram 02CC 11 00 44 792 ld de, #(colram) ; base of color ram 02CF FD 19 793 add iy, de ; set IY to appropriate location in color ram 794 ; prep for the loop 02D1 E1 795 pop hl 02D2 46 796 ld b, (hl) ; b is the number of bytes (pascal string) 02D3 23 797 inc hl ; HL points to the text now 02D4 798 .pstra1: 799 ; loop for each character 02D4 4E 800 ld c, (hl) ; c = character 02D5 DD 71 00 801 ld (ix), c ; vidram[b+offs] = character 02D8 FD 77 00 802 ld (iy), a ; colram[b+offs] = color 803 ; adjust pointers 02DB 23 804 inc hl ; inc string location 02DC DD 2B 805 dec ix ; dec char ram pointer 02DE FD 2B 806 dec iy ; dec color ram pointer 02E0 10 F2 807 djnz .pstra1 ; dec b, jump back if not done 808 ; restore registers 02E2 FD E1 809 pop iy 02E4 DD E1 810 pop ix 02E6 D1 811 pop de 02E7 E1 812 pop hl 02E8 C1 813 pop bc 814 ; return 02E9 C9 815 ret 816 817 ;; putstrB - get the vid/color buffer offset of the X Y coordinates 818 ; in hl pointer to the string (asciz) 819 ; in b x position 820 ; in c y position 821 ; in a color 822 ; out - 823 ; mod - FFFFFFE0 824 offsadd = -32 02EA 825 putstrB: 826 ; set aside registers 02EA E5 827 push hl 02EB C5 828 push bc 02EC D5 829 push de 02ED DD E5 830 push ix 02EF FD E5 831 push iy 02F1 E5 832 push hl 833 ; compute the offsets 02F2 CD 71 02 834 call xy2offsB ; hl = core offset 02F5 E5 835 push hl 02F6 DD E1 836 pop ix ; move the offset into ix (char ram) 02F8 E5 837 push hl 02F9 FD E1 838 pop iy ; move the offset into iy (color ram) 02FB 11 00 40 839 ld de, #(vidram) ; base of video ram 02FE DD 19 840 add ix, de ; set IX to appropriate location in vid ram 0300 11 00 44 841 ld de, #(colram) ; base of color ram 0303 FD 19 842 add iy, de ; set IY to appropriate location in color ram 843 ; prep for the loop 0305 E1 844 pop hl 0306 46 845 ld b, (hl) ; b is the number of bytes (pascal string) 0307 23 846 inc hl ; HL points to the text now 0308 11 E0 FF 847 ld de, #offsadd ; set up the column offset 030B 848 .pstrb1: 849 ; loop for each character 030B 4E 850 ld c, (hl) ; c = character 030C DD 71 00 851 ld (ix), c ; vidram[b+offs] = character 030F FD 77 00 852 ld (iy), a ; colram[b+offs] = color 853 ; adjust pointers 0312 23 854 inc hl ; inc string location 0313 DD 19 855 add ix, de ; add in offset into char ram 0315 FD 19 856 add iy, de ; add in offset into color ram 0317 10 F2 857 djnz .pstrb1 ; dec b, jump back if not done 858 ; restore registers 0319 FD E1 859 pop iy 031B DD E1 860 pop ix 031D D1 861 pop de 031E C1 862 pop bc 031F E1 863 pop hl 864 ; return 0320 C9 865 ret 866 867 ;; putstrC - get the vid/color buffer offset of the X Y coordinates 868 ; in hl pointer to the string (asciz) 869 ; in b x position 870 ; in c y position 871 ; in a color 872 ; out - 873 ; mod - 0321 874 putstrC: 875 ; set aside registers 0321 C5 876 push bc 0322 0C 877 inc c ; just change indexing 0,1 into 2,3 0323 0C 878 inc c 0324 C3 B7 02 879 jp .psChook ; jump back into putstrA 880 881 882 883 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 884 ; semaphore control 885 886 ; lock semaphore 887 ;; semalock - lock a semaphore 888 ; in a which semaphore to lock 889 ; out - 890 ; mod - 0327 891 semalock: 892 ; set aside registers 0327 F5 893 push af 0328 C5 894 push bc 0329 E5 895 push hl 896 ; set up the address 032A E6 0F 897 and #0x0f ; limit A to 0..15 032C 4F 898 ld c, a ; c is the current semaphore number 032D 06 00 899 ld b, #0x00 ; make sure that b=0 (bc = 0x00SS) 032F 2A E0 58 900 ld hl, (semabase) ; hl = base address 0332 09 901 add hl, bc ; hl = address of this semaphore 0333 902 .sl2: 0333 CB 4E 903 bit 1, (hl) 0335 20 FC 904 jr NZ, .sl2 ; while it's set, loop 905 ; set the bit 0337 CB CE 906 set 1, (hl) ; lock the semaphore 907 ; restore registers 0339 E1 908 pop hl 033A C1 909 pop bc 033B F1 910 pop af 911 ; return 033C C9 912 ret 913 914 ; release semaphore 915 ;; semarel - release a semaphore 916 ; in a which semaphore to release 917 ; out - 918 ; mod - 033D 919 semarel: 920 ; set aside registers 033D F5 921 push af 033E C5 922 push bc 033F E5 923 push hl 924 ; set up the address 0340 E6 0F 925 and #0x0F ; limit A to 0..15 0342 4F 926 ld c, a ; c is the current semaphore number 0343 06 00 927 ld b, #0x00 ; b=0 (bc = 0x000S) 0345 2A E0 58 928 ld hl, (semabase) ; hl = base address 0348 09 929 add hl, bc ; hl = address of this semaphore 930 ; clear the semaphore 0349 CB 8E 931 res 1, (hl) ; clear the bit 932 ; restore registers 034B E1 933 pop hl 034C C1 934 pop bc 034D F1 935 pop af 936 ; return 034E C9 937 ret 938 939 940 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 941 ; task exec, kill, and sleep routines 942 943 ;; execstart - starts up a new task 944 ; in E task number to start 945 ; in D task slot to use (0..3) 946 ; out - 947 ; mod - 034F 948 execstart: 949 ; save registers we're using 034F F5 950 push af 0350 D5 951 push de 0351 C5 952 push bc 0352 E5 953 push hl 954 ; limit E (task) to 127 0353 CB BB 955 res 7, e ; limit task number to 127 956 ; limit D (slot) 0355 7A 957 ld a, d ; a=d 0356 E6 03 958 and #0x03 ; slot is 0,1,2, or 3 0358 4F 959 ld c, a ; c=a 0359 06 00 960 ld b, #0x00 ; b=0x00, bc = 0x000S 961 ; set the control value 035B 21 00 00 962 ld hl, #(taskctrl) ; set up the control register 035E 09 963 add hl, bc ; hl = base + offset 035F 73 964 ld (hl), e ; taskctrl[d] = e 965 ; restore the registers 0360 E1 966 pop hl 0361 C1 967 pop bc 0362 D1 968 pop de 0363 F1 969 pop af 970 ; return 0364 C9 971 ret 972 973 ;; execkill - kills a running task 974 ; in D task slot to kill 975 ; out - 976 ; mod - 0365 977 execkill: 978 ; save registers we're using 0365 F5 979 push af 0366 D5 980 push de 0367 C5 981 push bc 0368 E5 982 push hl 983 ; limit D (slot) and shove it into C 0369 7A 984 ld a, d ; a=d 036A E6 03 985 and #0x03 ; slot is 0,1,2, or 3 036C 4F 986 ld c, a ; c=a 036D 06 00 987 ld b, #0x00 ; b=0x00, bc = 0x000S 988 ; set the control value 036F 21 00 00 989 ld hl, #(taskctrl) ; set up the control register 0372 09 990 add hl, bc ; hl = base + offset 0373 36 00 991 ld (hl), #(killslot) ; taskctrl[d] = KILL! 992 ; restore the registers 0375 E1 993 pop hl 0376 C1 994 pop bc 0377 D1 995 pop de 0378 F1 996 pop af 997 ; return 0379 C9 998 ret 999 1000 1001 ;; sleep - wait a specified number of ticks 1002 ; in bc number of ticks to wait 1003 ; out - 1004 ; mod - 037A 1005 sleep: 1006 ; set side some registers 037A C5 1007 push bc 037B F5 1008 push af 037C E5 1009 push hl 1010 ;; this is where we would set the flag for 1011 ;; the exec system to relinquish the rest of our time. 1012 ; compute the timeout into BC 037D 2A 15 4C 1013 ld hl, (timer) ; hl = timer 0380 09 1014 add hl, bc ; hl += ticks to wait 0381 E5 1015 push hl ; bc = 0382 C1 1016 pop bc ; = hl 0383 1017 .slp: 1018 ; loop until the timeout comes 0383 2A 15 4C 1019 ld hl, (timer) ; hl = current time 0386 ED 42 1020 sbc hl, bc ; set flags 0388 FA 83 03 1021 jp M, .slp ; if (HL >= BC) then JP .slp2 1022 ; restore the registers 038B E1 1023 pop hl 038C F1 1024 pop af 038D C1 1025 pop bc 1026 ; return 038E C9 1027 ret 1028 1029 1030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1031 ; The tasks 1032 1033 ; task list -- list of all available tasks 1034 ; list of all tasks available, null terminated 038F 1035 tasklist: 038F 99 03 1036 .word t0header 0391 D7 03 1037 .word t1header 0393 01 04 1038 .word t2header 0395 3F 04 1039 .word t3header 0397 00 00 1040 .word 0x0000 1041 1042 1043 ;;;;;;;;;;;;;;;;;;;; 1044 ; task number 0 1045 ;; Task 0 - PTUI 1046 ; constants 1047 ; GUI constants 1048 ; cursor and wallpaper 0000 1049 PcursorS = 0 ; sprite 0 for the cursor 0009 1050 PcursorC = 9 ; color 9 for the cursor 1051 0001 1052 CrosshFS = 1 ; crosshair for window movement 0009 1053 CrosshC = 0x09 ; crosshair color 1054 00A2 1055 PwpS = 162 ; wallpaper sprite 0010 1056 PwpC = 0x10 ; wallpaper color 0x13- blues 1057 0010 1058 LlamaC = 0x10 ; llama color (might be the same as PwpC above) 007B 1059 LlamaS = 0x7b ; base of llama tile 0002 1060 LlamaFS = 2 ; llama floating sprite 0014 1061 CprtC = 0x14 ; copyright color 11 1062 ; flags 0001 1063 F_Noframe = 1 ; no frame in render (hard flag) 0002 1064 F_Frame = 2 ; frame in render (hard flag) 1065 0001 1066 F_Dirty = 1 ; frame needs redraw (soft flag) 0002 1067 F_Focus = 2 ; frame is capturing focus currently 1068 ; -- frame widgets -- 1069 ; close 0080 1070 PcloseS = 128 ; close widget sprite 0001 1071 PcloseCS = 1 ; close widget selected color (5) 001E 1072 PcloseCU = 0x1e ; close widget unselected color 1073 1074 ; raise 0083 1075 PraiseS = 131 ; raise widget sprite 0001 1076 PraiseCS = 1 ; raise widget selected color (5) 000C 1077 PraiseCU = 0xc ; raise widget unselected color 1078 1079 ; -- frame ornaments -- 0009 1080 PfrmTSel = 9 ; dragbar text selected color 0x14 0xb 0001 1081 PfrmTUns = 1 ; dragbar text unselected color 1082 0001 1083 PfrmCSel = 1 ; frame selected color 001E 1084 PfrmCUns = 0x1e ; frame unselected color 1085 1086 ; bottom corners 008A 1087 PSWcornS = 138 ; southwest corner 008B 1088 PSEcornS = 139 ; southeast corner 1089 1090 ; top corners 0001 1091 PNWcornS = 1 ; northwest corner 140 0001 1092 PNEcornS = 1 ; northeast corner 141 1093 1094 ; top bar 0081 1095 PfN_W = 129 ; top left (145 or 129) 0020 1096 PfN_N = 32 ; top center (146 or 32) 0082 1097 PfN_E = 130 ; top right (147 or 130) 1098 1099 ; left bar 0084 1100 PfW_N = 132 ; left top 0085 1101 PfW_W = 133 ; left center 0086 1102 PfW_S = 134 ; left bottom 1103 1104 ; right bar 0087 1105 PfE_N = 135 ; right top 0088 1106 PfE_E = 136 ; right center 0089 1107 PfE_S = 137 ; right bottom 1108 1109 ; bottom bar 008E 1110 PfS_W = 142 ; bottom left 008F 1111 PfS_S = 143 ; bottom center 0090 1112 PfS_E = 144 ; bottom right 1113 ; widgets 0001 1114 PwC = 1 ; generic widget color 007F 1115 PwBGS = 127 ; window background sprite 1116 1117 ; button 0094 1118 PwbLuS = 148 ; [ button left unselected sprite 0095 1119 PwbRuS = 149 ; ] button right unselected sprite 1120 1121 ; selected button 0096 1122 PwbLsS = 150 ; [[ button left selected sprite 0097 1123 PwbRsS = 151 ; ]] button right selected sprite 1124 1125 ; checkbox 0098 1126 PwcuS = 152 ; [ ] checkbox unselected sprite 0099 1127 PwcsS = 153 ; [X] checkbox selected sprite 1128 1129 ; radio box 009A 1130 PwruS = 154 ; ( ) radio unselected sprite 009B 1131 PwrsS = 155 ; (X) radio selected sprite 1132 1133 ; slider 009C 1134 PwsnS = 156 ; === slider notch sprite 009D 1135 PwsbS = 157 ; =|= slider bar sprite 1136 1137 ; progress bar 009E 1138 PwpoS = 158 ; progress bar open sprite 009F 1139 PwpfS = 159 ; ### progress bar filled sprite 1140 1141 ; spin 00A0 1142 PwHsS = 160 ; <> horizontal spin controller 00A1 1143 PwVsS = 161 ; ^v vertical spin controller 1144 ; Widget Types (for the frame-widget table) 1145 0000 1146 W_End = 0 ; end of the widget list 0001 1147 W_Frame = 1 ; window frame (needs to be first) 1148 1149 ; frame flags: 0001 1150 FF_Border = 1 ; use a border on the frame 0002 1151 FF_NClose = 2 ; no close button 0004 1152 FF_NRaise = 4 ; no raise button 1153 0002 1154 W_MButton = 2 ; momentary button 0003 1155 W_SButton = 3 ; sticky button 1156 0004 1157 W_Radio = 4 ; radio button (flags is the group number) 0005 1158 W_Check = 5 ; check button 1159 0006 1160 W_SText = 6 ; static text (text is the idx of a string) 0007 1161 W_DText = 7 ; dynamic text (data is idx of ram) 1162 0008 1163 W_DInt = 8 ; dynamic integer (data is idx in the ram) 1164 0009 1165 W_HSlider = 9 ; horizontal slider 000A 1166 W_VSlider = 10 ; vertical slider 1167 000B 1168 W_HSpin = 11 ; horizontal spin 000C 1169 W_VSpin = 12 ; vertical spin 1170 1171 ; header 0399 1172 t0header: 0399 C9 4A 73 4C 1173 .byte 0xc9, 0x4a, 0x73, 0x4c ; cookie 039D 01 1174 .byte 0x01 ; version 039E 04 1175 .byte 0x04 ; requested timeslices 039F A3 03 1176 .word t0name ; name 03A1 AB 03 1177 .word t0process ; process function 1178 03A3 1179 t0name: 03A3 06 1180 .byte 6 ; strlen 03A4 54 61 73 6B 20 30 1181 .asciz "Task 0" ; name 00 1182 1183 ; routines 03AB 1184 t0process: 03AB 21 00 44 1185 ld hl, #(colram) ; base of color ram 03AE 3E 01 1186 ld a, #0x01 ; clear the screen to 0x00 03B0 06 04 1187 ld b, #0x04 ; 256*4 = 1k 03B2 CD F2 01 1188 call memsetN ; do it. 1189 03B5 1190 t0p2: 03B5 21 00 40 1191 ld hl, #(vidram) ; base of video ram 03B8 3E 41 1192 ld a, #0x41 ; 'A' 03BA 06 04 1193 ld b, #0x04 ; 256*4 = 1k 03BC CD F2 01 1194 call memsetN 1195 03BF 21 00 40 1196 ld hl, #(vidram) ; base of video ram 03C2 3E 42 1197 ld a, #0x42 ; 'B' 03C4 06 04 1198 ld b, #0x04 ; 256*4 = 1k 03C6 CD F2 01 1199 call memsetN 1200 03C9 21 00 40 1201 ld hl, #(vidram) ; base of video ram 03CC 3E 43 1202 ld a, #0x43 ; 'C' 03CE 06 04 1203 ld b, #0x04 ; 256*4 = 1k 03D0 CD F2 01 1204 call memsetN 1205 03D3 C3 B5 03 1206 jp t0p2 03D6 76 1207 halt 1208 1209 1210 ;;;;;;;;;;;;;;;;;;;; 1211 ; task number 1 1212 ;; Task 1 - TBD 1213 ; header 03D7 1214 t1header: 03D7 C9 4A 73 4C 1215 .byte 0xc9, 0x4a, 0x73, 0x4c ; cookie 03DB 01 1216 .byte 0x01 ; version 03DC 04 1217 .byte 0x04 ; requested timeslices 03DD E1 03 1218 .word t1name ; name 03DF E9 03 1219 .word t1process ; process function 1220 03E1 1221 t1name: 03E1 06 1222 .byte 6 ; strlen 03E2 54 61 73 6B 20 31 1223 .asciz "Task 1" ; name 00 1224 1225 ; routines 03E9 1226 t1process: 03E9 21 00 44 1227 ld hl, #(colram) ; base of color ram 03EC 3E 01 1228 ld a, #0x01 ; clear the screen to blue 03EE 06 04 1229 ld b, #0x04 ; 256*4 = 1k 03F0 CD F2 01 1230 call memsetN 1231 03F3 21 00 44 1232 ld hl, #(colram) ; base of color ram 03F6 3E 09 1233 ld a, #0x09 ; clear the screen to red 03F8 06 04 1234 ld b, #0x04 ; 256*4 = 1k 03FA CD F2 01 1235 call memsetN 1236 03FD C3 E9 03 1237 jp t1process 0400 76 1238 halt 1239 1240 1241 ;;;;;;;;;;;;;;;;;;;; 1242 ; task number 2 1243 ;; Task 2 - TBD 1244 ; header 0401 1245 t2header: 0401 C9 4A 73 4C 1246 .byte 0xc9, 0x4a, 0x73, 0x4c ; cookie 0405 01 1247 .byte 0x01 ; version 0406 04 1248 .byte 0x04 ; requested timeslices 0407 0B 04 1249 .word t2name ; name 0409 13 04 1250 .word t2process ; process function 1251 040B 1252 t2name: 040B 06 1253 .byte 6 ; strlen 040C 54 61 73 6B 20 32 1254 .asciz "Task 2" ; name 00 1255 1256 ; routines 0413 1257 t2process: 0413 21 00 44 1258 ld hl, #(colram) ; base of color ram 0416 3E 01 1259 ld a, #0x01 ; clear the screen to 0x00 0418 06 04 1260 ld b, #0x04 ; 256*4 = 1k 041A CD F2 01 1261 call memsetN 1262 041D 21 00 40 1263 ld hl, #(vidram) ; base of video ram 0420 3E 61 1264 ld a, #0x61 ; 'a' 0422 06 04 1265 ld b, #0x04 ; 256*4 = 1k 0424 CD F2 01 1266 call memsetN 1267 0427 21 00 40 1268 ld hl, #(vidram) ; base of video ram 042A 3E 62 1269 ld a, #0x62 ; 'b' 042C 06 04 1270 ld b, #0x04 ; 256*4 = 1k 042E CD F2 01 1271 call memsetN 1272 0431 21 00 40 1273 ld hl, #(vidram) ; base of video ram 0434 3E 63 1274 ld a, #0x63 ; 'c' 0436 06 04 1275 ld b, #0x04 ; 256*4 = 1k 0438 CD F2 01 1276 call memsetN 1277 043B C3 13 04 1278 jp t2process 043E 76 1279 halt 1280 1281 1282 ;;;;;;;;;;;;;;;;;;;; 1283 ; task number 3 1284 ;; Task 3 - TBD 1285 ; header 043F 1286 t3header: 043F C9 4A 73 4C 1287 .byte 0xc9, 0x4a, 0x73, 0x4c ; cookie 0443 01 1288 .byte 0x01 ; version 0444 04 1289 .byte 0x04 ; requested timeslices 0445 49 04 1290 .word t3name ; name 0447 51 04 1291 .word t3process ; process function 1292 0449 1293 t3name: 0449 06 1294 .byte 6 ; strlen 044A 54 61 73 6B 20 33 1295 .asciz "Task 3" ; name 00 1296 1297 ; routines 0451 1298 t3process: 0451 21 00 44 1299 ld hl, #(colram) ; base of color ram 0454 3E 01 1300 ld a, #0x01 ; clear the screen to 0x00 0456 06 04 1301 ld b, #0x04 ; 256*4 = 1k 0458 CD F2 01 1302 call memsetN 1303 045B 21 00 40 1304 ld hl, #(vidram) ; base of video ram 045E 3E 78 1305 ld a, #0x78 ; 'X' 0460 06 04 1306 ld b, #0x04 ; 256*4 = 1k 0462 CD F2 01 1307 call memsetN 1308 0465 21 00 40 1309 ld hl, #(vidram) ; base of video ram 0468 3E 79 1310 ld a, #0x79 ; 'Y' 046A 06 04 1311 ld b, #0x04 ; 256*4 = 1k 046C CD F2 01 1312 call memsetN 1313 046F 21 00 40 1314 ld hl, #(vidram) ; base of video ram 0472 3E 7A 1315 ld a, #0x7a ; 'Z' 0474 06 04 1316 ld b, #0x04 ; 256*4 = 1k 0476 CD F2 01 1317 call memsetN 1318 0479 C3 51 04 1319 jp t3process 047C 76 1320 halt 1321 1322 1323 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1324 ; The Data 1325 1326 ; splash strings 047D 1327 llama1: 047D 02 7B 7C 1328 .byte 0x02, (LlamaS+0), (LlamaS+1) ; first row of llama 0480 1329 llama2: 0480 02 7D 7E 1330 .byte 0x02, (LlamaS+2), (LlamaS+3) ; second row of llama 0483 1331 cprt1: 0483 10 1332 .byte 0x10 0484 20 41 6C 70 61 63 1333 .ascii " Alpaca OS v0.8 " 61 20 4F 53 20 76 30 2E 38 20 0494 1334 cprt2: 0494 14 1335 .byte 0x14 0495 2F 32 30 30 33 20 1336 .ascii "/2003 Jerry Lawrence" 4A 65 72 72 79 20 4C 61 77 72 65 6E 63 65 04A9 1337 cprt3: 04A9 18 1338 .byte 0x18 04AA 61 6C 70 61 63 61 1339 .ascii "alpacaOS@umlautllama.com" 4F 53 40 75 6D 6C 61 75 74 6C 6C 61 6D 61 2E 63 6F 6D 1340 1341 ; Some tables for the Task Switcher 1342 ; table of stack/user RAM usage (stacks, ram) 04C2 1343 stacklist: 04C2 F0 4F 1344 .word stack0 04C4 30 4F 1345 .word stack1 04C6 70 4E 1346 .word stack2 04C8 B0 4D 1347 .word stack3 04CA F0 4C 1348 .word stackbottom 1349 1350 ; The sine table 04CC 1351 .sinetab: 04CC 80 83 86 89 8C 8F 1352 .byte 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95 92 95 04D4 99 9C 9F A2 A5 A8 1353 .byte 0x99, 0x9c, 0x9f, 0xa2, 0xa5, 0xa8, 0xab, 0xae AB AE 04DC B1 B4 B6 B9 BC BF 1354 .byte 0xb1, 0xb4, 0xb6, 0xb9, 0xbc, 0xbf, 0xc2, 0xc4 C2 C4 04E4 C7 C9 CC CF D1 D3 1355 .byte 0xc7, 0xc9, 0xcc, 0xcf, 0xd1, 0xd3, 0xd6, 0xd8 D6 D8 04EC DA DC DF E1 E3 E5 1356 .byte 0xda, 0xdc, 0xdf, 0xe1, 0xe3, 0xe5, 0xe7, 0xe8 E7 E8 04F4 EA EC EE EF F1 F2 1357 .byte 0xea, 0xec, 0xee, 0xef, 0xf1, 0xf2, 0xf3, 0xf5 F3 F5 04FC F6 F7 F8 F9 FA FB 1358 .byte 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd FC FD 0504 FD FE FE FF FF FF 1359 .byte 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff FF FF 050C FF FF FF FF FF FE 1360 .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfd FE FD 0514 FD FC FB FB FA F9 1361 .byte 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7 F8 F7 051C F5 F4 F3 F1 F0 EE 1362 .byte 0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xee, 0xed, 0xeb ED EB 0524 E9 E8 E6 E4 E2 E0 1363 .byte 0xe9, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdb DE DB 052C D9 D7 D5 D2 D0 CD 1364 .byte 0xd9, 0xd7, 0xd5, 0xd2, 0xd0, 0xcd, 0xcb, 0xc8 CB C8 0534 C6 C3 C0 BD BB B8 1365 .byte 0xc6, 0xc3, 0xc0, 0xbd, 0xbb, 0xb8, 0xb5, 0xb2 B5 B2 053C AF AC A9 A6 A3 A0 1366 .byte 0xaf, 0xac, 0xa9, 0xa6, 0xa3, 0xa0, 0x9d, 0x9a 9D 9A 0544 97 94 91 8E 8B 87 1367 .byte 0x97, 0x94, 0x91, 0x8e, 0x8b, 0x87, 0x84, 0x81 84 81 054C 7E 7B 78 74 71 6E 1368 .byte 0x7e, 0x7b, 0x78, 0x74, 0x71, 0x6e, 0x6b, 0x68 6B 68 0554 65 62 5F 5C 59 56 1369 .byte 0x65, 0x62, 0x5f, 0x5c, 0x59, 0x56, 0x53, 0x50 53 50 055C 4D 4A 47 44 42 3F 1370 .byte 0x4d, 0x4a, 0x47, 0x44, 0x42, 0x3f, 0x3c, 0x39 3C 39 0564 37 34 32 2F 2D 2A 1371 .byte 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2a, 0x28, 0x26 28 26 056C 24 21 1F 1D 1B 19 1372 .byte 0x24, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x16 17 16 0574 14 12 11 0F 0E 0C 1373 .byte 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a 0B 0A 057C 08 07 06 05 04 04 1374 .byte 0x08, 0x07, 0x06, 0x05, 0x04, 0x04, 0x03, 0x02 03 02 0584 02 01 01 00 00 00 1375 .byte 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 00 00 058C 00 00 00 00 00 01 1376 .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02 01 02 0594 02 03 04 05 06 07 1377 .byte 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 08 09 059C 0A 0C 0D 0E 10 11 1378 .byte 0x0a, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x15 13 15 05A4 17 18 1A 1C 1E 20 1379 .byte 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x23, 0x25 23 25 05AC 27 29 2C 2E 30 33 1380 .byte 0x27, 0x29, 0x2c, 0x2e, 0x30, 0x33, 0x36, 0x38 36 38 05B4 3B 3D 40 43 46 49 1381 .byte 0x3b, 0x3d, 0x40, 0x43, 0x46, 0x49, 0x4b, 0x4e 4B 4E 05BC 51 54 57 5A 5D 60 1382 .byte 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x60, 0x63, 0x66 63 66 05C4 6A 6D 70 73 76 79 1383 .byte 0x6a, 0x6d, 0x70, 0x73, 0x76, 0x79, 0x7c, 0x7f 7C 7F 1384 1385 ; The XY-offset table 05CC 1386 .scroffs: 05CC A0 03 80 03 60 03 1387 .word 0x03a0, 0x0380, 0x0360, 0x0340 40 03 05D4 20 03 00 03 E0 02 1388 .word 0x0320, 0x0300, 0x02e0, 0x02c0 C0 02 05DC A0 02 80 02 60 02 1389 .word 0x02a0, 0x0280, 0x0260, 0x0240 40 02 05E4 20 02 00 02 E0 01 1390 .word 0x0220, 0x0200, 0x01e0, 0x01c0 C0 01 05EC A0 01 80 01 60 01 1391 .word 0x01a0, 0x0180, 0x0160, 0x0140 40 01 05F4 20 01 00 01 E0 00 1392 .word 0x0120, 0x0100, 0x00e0, 0x00c0 C0 00 05FC A0 00 80 00 60 00 1393 .word 0x00a0, 0x0080, 0x0060, 0x0040 40 00 1394 1395 ; The Region A and C offset table 0604 1396 .acoffs: 0604 DD 03 1397 .word 0x03dd ; Region A row 'E' -> AC row 0 0606 FD 03 1398 .word 0x03fd ; Region A row 'F' -> AC row 1 0608 1D 00 1399 .word 0x001d ; Region C row 'A' -> AC row 2 060A 3D 00 1400 .word 0x003d ; Region C row 'B' -> AC row 3 1401 ASxxxx Assembler V01.50 (Zilog Z80 / Hitachi HD64180), page 1. alpaca Symbol Table 1 .acoffs 0604 R 1 .coretask 019B R 1 .doneTask 00EC R 1 .isr 0068 R 1 .loadInTheSP 00BB R 1 .nmi 0066 R 1 .noSwitch 00E6 R 1 .overslot1 00E1 R 1 .psChook 02B7 R 1 .pstra1 02D4 R 1 .pstrb1 030B R 1 .r01 0233 R 1 .r02 0237 R 1 .reset00 0000 R 1 .reset08 0008 R 1 .reset10 0010 R 1 .reset18 0018 R 1 .reset20 0020 R 1 .reset28 0028 R 1 .reset30 0030 R 1 .reset38 0038 R 1 .scroffs 05CC R 1 .setupVars 00CA R 1 .sinetab 04CC R 1 .sl2 0333 R 1 .slp 0383 R 1 .splash 0156 R 1 .start 00FC R 1 .storeTheSP 00A7 R 1 .tcrr 0262 R 1 .tsNext 0091 R 1 .tsloop1 0095 R C_EXT0 = 0004 C_InUse = 0007 CprtC = 0014 CrosshC = 0009 CrosshFS = 0001 FF_Border = 0001 FF_NClose = 0002 FF_NRaise = 0004 F_Dirty = 0001 F_Focus = 0002 F_Frame = 0002 F_Noframe = 0001 LlamaC = 0010 LlamaFS = 0002 LlamaS = 007B PNEcornS = 0001 PNWcornS = 0001 PSEcornS = 008B PSWcornS = 008A PcloseCS = 0001 PcloseCU = 001E PcloseS = 0080 PcursorC = 0009 PcursorS = 0000 PfE_E = 0088 PfE_N = 0087 PfE_S = 0089 PfN_E = 0082 PfN_N = 0020 PfN_W = 0081 PfS_E = 0090 PfS_S = 008F PfS_W = 008E PfW_N = 0084 PfW_S = 0086 PfW_W = 0085 PfrmCSel = 0001 PfrmCUns = 001E PfrmTSel = 0009 PfrmTUns = 0001 PraiseCS = 0001 PraiseCU = 000C PraiseS = 0083 PwBGS = 007F PwC = 0001 PwHsS = 00A0 PwVsS = 00A1 PwbLsS = 0096 PwbLuS = 0094 PwbRsS = 0097 PwbRuS = 0095 PwcsS = 0099 PwcuS = 0098 PwpC = 0010 PwpS = 00A2 PwpfS = 009F PwpoS = 009E PwrsS = 009B PwruS = 009A PwsbS = 009D PwsnS = 009C W_Check = 0005 W_DInt = 0008 W_DText = 0007 W_End = 0000 W_Frame = 0001 W_HSlider = 0009 W_HSpin = 000B W_MButton = 0002 W_Radio = 0004 W_SButton = 0003 W_SText = 0006 W_VSlider = 000A W_VSpin = 000C bitXFlip = 0000 bitYFlip = 0001 cab_port = 5040 cabinet = 0007 1 cls 01FC R coin1 = 0005 coin2 = 0006 coin3 = 0007 coin_port = 5000 coincount = 5007 colram = 4400 1 cosine 0252 R 1 cprt1 0483 R 1 cprt2 0494 R 1 cprt3 04A9 R dsw0 = 5080 execSlot = 0001 1 execkill 0365 R 1 execstart 034F R flipscreen = 5003 1 foo 01BD R 1 guicls 020D R hscrwide = 000E in0 = 5000 in1 = 5040 irqen = 5000 killSlot = 0000 killslot **** GX 1 llama1 047D R 1 llama2 0480 R 1 memset256 01ED R 1 memsetN 01F2 R msgbase = 58A0 msgmax = 58DF nsprites = 0008 offsadd = FFFFFFE0 p1_down = 0003 p1_left = 0001 p1_port = 5000 p1_right = 0002 p1_up = 0000 p2_down = 0003 p2_left = 0001 p2_port = 5040 p2_right = 0002 p2_up = 0000 1 putstrA 02B6 R 1 putstrB 02EA R 1 putstrC 0321 R rack_port = 5000 racktest = 0004 ram = 4C00 ramBase = 4C10 1 rand 0228 R randval = 4C17 semabase = 58E0 1 semalock 0327 R semamax = 58EF 1 semarel 033D R service = 0004 1 sine 0246 R 1 sleep 037A R sleepSlot = 0002 slot0Ctrl = 4C04 slot0use = 0000 slot1Ctrl = 4C05 slot1use = 0001 slot2Ctrl = 4C06 slot2use = 0002 slot3Ctrl = 4C07 slot3use = 0003 slotCtrl = 4C04 slotIdx = 4C00 slotIdx0 = 4C00 slotIdx1 = 4C01 slotIdx2 = 4C02 slotIdx3 = 4C03 slotMask **** GX slotOpen = 00FF slotSP = 4C08 slotSP0 = 4C08 slotSP1 = 4C0A slotSP2 = 4C0C slotSP3 = 4C0E slotTicks = 0004 slotTime = 4C14 sounden = 5001 speclen = 00C0 specreg = 5000 spritebase = 4FF0 spritecoords = 5060 sprtColor = 0001 sprtIndex = 0000 sprtMult = 0004 sprtXFlip = 0000 sprtYFlip = 0000 sprtbase = 4FF0 sprtlen = 0010 stack = 4FF0 stack0 = 4FF0 stack1 = 4F30 stack2 = 4E70 stack3 = 4DB0 stackList **** GX stackbottom = 4CF0 1 stacklist 04C2 R stacksize = 00C0 start1 = 0005 start2 = 0006 start_port = 5040 svc_port = 5040 1 t0header 0399 R 1 t0name 03A3 R 1 t0p2 03B5 R 1 t0process 03AB R 1 t1header 03D7 R 1 t1name 03E1 R 1 t1process 03E9 R 1 t2header 0401 R 1 t2name 040B R 1 t2process 0413 R 1 t3header 043F R 1 t3name 0449 R 1 t3process 0451 R taskActive = 0007 taskFlag = 4C12 taskSlot = 4C13 taskctrl **** GX 1 tasklist 038F R 1 textcenter 025C R 1 textright 026A R timer = 4C15 v1_acc = 5040 v1_freq = 5050 v1_vol = 5055 v1_wave = 5045 v2_acc = 5046 v2_freq = 5056 v2_vol = 505A v2_wave = 504A v3_acc = 504B v3_freq = 505B v3_vol = 505F v3_wave = 504F valXFlip = 0001 valYFlip = 0002 vidram = 4000 watchdog = 50C0 1 xy2offsAC 0296 R 1 xy2offsB 0271 R ASxxxx Assembler V01.50 (Zilog Z80 / Hitachi HD64180), page 2. alpaca Area Table 0 _CODE size 0 flags 0 1 .CODE size 60C flags C