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