Light pen driver
From CPCWiki - THE Amstrad CPC encyclopedia!
;; Dissassembled and commented from MCPEN.BIN org 09c40h sub_9c40h: call 0bd19h ;; mc wait flyback di ld bc,0f40eh ;; we want to select AY register 14 out (c),c ld b,0f6h in a,(c) and 030h ld c,a or 0c0h ;; AY control select register. out (c),a out (c),a ;; BUG. Should be out (c),c to be compatible with Plus. inc b ld a,092h out (c),a push bc ld bc,0f649h ;; AY control read from register and select keyboard line 9 (joystick) out (c),c out (c),c ;; BUG? No need to do this twice. ld b,0f4h ;; loop reading joystick until input seen or timeout ld hl,0fa66h ;; timeout is 0-FA66 because it counts up from this starting point. ;; timeout is 59A loops. l9c68: in a,(c) cp 0fdh ;; 11111101. Bits are '1' if 'no press', but '0' if pressed. checking joy 0 down. jr z,l9c79 inc l jr nz,l9c68 inc h jr nz,l9c68 ;; timeout. not detected ld hl,0ffffh jr l9cbdh l9c79: ;; detected. ld de,00420h add hl,de l9cbd: ld (0a410h),hl ;; detected 'position' or 'ffff' for not detected pop bc ld a,082h out (c),a dec b out (c),c ;; Set AY control inactive. ei ret sub_9c8ah: call sub_9da6h ;; screen to buffer call sub_9ce4h call sub_9db2h ;; buffer to screen ret ;; HL = HL/DE sub_9c94: ld a,h ld c,l ld b,010h ;; 16 bits. ld hl,00000h l9cdbh: rl c rla adc hl,hl sbc hl,de jr nc,l9ce5h add hl,de l9ce5h: ccf djnz l9cdbh rl c rla ld h,a ld l,c ret ;; HL = HL * DE sub_9caeh: ld a,l ld c,h ld b,010h ;; 16 bits ld hl,00000h l9cf5h: srl c rra jr nc,l9cfbh add hl,de l9cfbh: ex de,hl add hl,hl ex de,hl djnz l9cf5h ret sub_9cc1h: call sub_9c40h ;; detect ld a,0ffh cp h ret z ;; detected. ld de,00002h call sub_9c94h ;; HL = HL/DE ld de,00064h call sub_9caeh ;; HL = HL*DE ld de,00084h call sub_9c94h ;; HL = HL/DE ex de,hl ld hl,0018fh sbc hl,de ld (0a410h),hl ret sub_9ce4: ld a,000h ld bc,01a1ah call 0bc32h ;; scr set ink call 0bc14h ;; scr clear ld a,001h call 0bbdeh ;; gra set pen call sub_9cc1h ;; get position ld a,0ffh cp h ret z ld de,0000ah and a sbc hl,de ;; BUG? This is jumping just after 0x021 of LD HL and then executing two nops before LD DE,0000h ;;jr nc,$+2 jr nc,l9d06 ld hl,00000h l9d06: ld de,00000h call 0bbc0h ;; gra move absolute ld a,001h ld bc,01a1ah call 0bc32h ;; scr set ink ld a,000h ld bc,00000h call 0bc32h ;; scr set ink ld b,00ah l9d1e: call 0bd19h ;; mc wait flyback ;; BUG? this is jumping back to the 0x0a in LD B,0ah ;; djnz $-4 djnz l9d1e ld b,020h ;; number of lines l9d65h: push bc call sub_9d35h ;; draw lines call sub_9c40h ;;detect pop bc ld a,0ffh cp h jr nz,l9d91h djnz l9d65h ret sub_9d35h: ld bc,(0a418h) l9d79h: push bc ld de,00000h ld hl,00014h call 0bbf9h ;; gra line relative ld de,(0a416h) ld hl,0ffech call 0bbc3h ;; gra move relative pop bc djnz l9d79h ret l9d91h: ld de,0ffech ;; -20 ld hl,00000h call 0bbc3h ;; gra move relative l9d9ah: ld a,000h call 0bbdeh ;; gra set pen call sub_09d35h ;; lines ld a,001h call 0bbdeh ;; gra set pen ld de,0ffech ;; -20 ld hl,00000h call 0bbc3h ;; gra move relative ld bc,(0a420h) l9db4h: push bc call sub_9cc1h ;; get position ld a,0ffh cp h jr nz,sub_9d9ah ld de,00000h ld hl,00014h call 0bbf9h ;; gra line relative ld de,(0a416h) ld hl,0ffech ;; -20 call 0bbc3h ;; gra move relative pop bc djnz l9db4h ld hl,0ffffh ld (0a410h),hl ret sub_9d9ah: pop bc ld (0a410h),hl call 0bbc6h ;; gra ask cursor ld (0a412h),de ret ;; screen to buffer ;; c000->5bfe length 3fd0 sub_9da6h: ld bc,03fd0h ld hl,0c000h ld de,05bfeh ldir ret ;; buffer to screen ;; 5bfe->c000 length 3fd0 sub_9db2h: ld bc,03fd0h ld hl,05bfeh ld de,0c000h ldir ret sub_9dbeh: push hl push de call sub_09e08h ld (0a414h),hl ld de,05398h ld b,004h l9e0bh: push bc ld hl,(0a414h) ld c,b ld b,000h inc hl and a sbc hl,bc ld b,00bh l9e18h: ld a,(hl) ld (de),a inc de call 0bc29h ;; scr prev line djnz l9e18h pop bc djnz l9e0bh pop de pop hl ret sub_9de6h: push hl push de ld de,05398h ld b,004h l9e2dh: push bc ld hl,(0a414h) ld c,b ld b,000h inc hl and a sbc hl,bc ld b,00bh l9e3ah: ld a,(de) ld (hl),a inc de call 0bc29h ;; scr prev line djnz l9e3ah pop bc djnz l9e2dh pop de pop hl ret sub_9e08h: push de ld de,00002h call sub_9c94h ;; HL = HL/DE pop de push hl ex de,hl ld de,(0a416h) call sub_9c94h ;; HL = HL/DE ex de,hl pop hl call 0bc1dh ;; scr dot position ret sub_9e1fh: call sub_9c8ah ld hl,(0a418h) ld (0a420h),hl ld hl,(0a410h) ld a,0ffh cp h ret z ld (0a41ch),hl ld de,(0a412h) ld (0a41ah),de l9e7ah: ld de,0000ah and a sbc hl,de jr nc,l9e85h ld hl,00000h l9e85h: push hl ld hl,(0a412h) add hl,de ex de,hl pop hl call sub_09dbeh call 0bbc0h ;; gra move absolute sub_9e52h: call sub_09ed2h call sub_09de6h ld hl,(0a410h) ld a,0ffh cp h jr nz,l9ea9h ld a,02fh call 0bb1eh ;; km test key ret z jp sub_9e52h l9ea9h: call sub_09eb7h ld a,02fh call 0bb1eh ;; km test key ret z ld hl,(0a41ch) ld de,(0a41ah) call 0bbc0h ;; gra move absolute ld hl,(0a410h) ld de,(0a412h) ld a,(0a41eh) call 0bbdeh ;; gra set pen ld (0a41ch),hl ld (0a41ah),de call 0bbf6h ;; gra line absolute ld hl,(0a410h) jr l9e7ah sub_09e98h: ld de,0ffech ld hl,00000h call 0bbc3h ;; gra move relative ld a,001h call 0bbdeh ;; gra set pen call sub_09d35h ld a,000h call 0bbdeh ;; gra set pen call sub_9cc1h ;; get position ld a,0ffh cp h ret nz pop de ret sub_9eb7h: ld hl,(0a41ah) ld de,(0a412h) and a sbc hl,de ret z jp p,l9ecbh ld hl,l9f15h jp l09eceh l9ecbh: ld hl,sub_9ed2h l9eceh: ld (l9e52h+1),hl ret sub_9ed2h: call sub_9e98h ld de,0ffech ld hl,00000h call 0bbc3h ;; gra move relative ld bc,(0a420h) push bc ld de,00000h ld hl,00014h call 0bbf9h ;; gra line relative call sub_9cc1h ld a,0ffh cp h jp nz,sub_9efeh sub_9ef5h: ld hl,(0a422h) ld (0a410h),hl jp sub_9d9ah sub_9efeh: ld (0a422h),hl ld de,(0a416h) ld hl,0ffech call 0bbc3h ;; gra move relative pop bc djnz l9f22h ld hl,0ffffh ld (0a410h),hl ret sub_9f82h: call sub_9e98h ld bc,(0a420h) l9f5ch: push bc ld de,00000h ld hl,00014h call 0bbf9h ;; gra line relative call sub_9cc1h ld a,0ffh cp h jp z,sub_9ef5h ld (0a422h),hl ld de,(0a416h) ld hl,00000h and a sbc hl,de push hl pop de ld hl,0ffech call 0bbc3h ;; gra move relative pop bc djnz l9f5ch ld hl,00000h ld de,00014h call 0bbc3h ;; gra move relative jp l9f0eh db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; screen dump to printer. sub_0a028h: ld a,013h ld (0a124h),a ld a,00eh ld (0a0e2h),a ld a,(0a133h) bit 1,a jr z,la083h ld a,000h ld (0a124h),a ld a,007h ld (0a0e2h),a la083h: call 0bd28h ;; mc reset printer ld de,00000h ld hl,00000h ld (0a12dh),de sub_a050h: ld a,000h ld (0a12ch),a ;; accumulated pixels. ld de,(0a12dh) call sub_a10dh ;; store current graphics position call 0bbf0h ;; gra test absolute ld de,00001h call sub_a11dh ;; get pixel ld de,00002h call sub_a11dh ;; get pixel ld de,00004h call sub_a11dh ;; get pixel ld de,00008h call sub_a11dh ;; get pixel ld de,00010h call sub_a11dh ;; get pixel ld de,00020h call sub_a11dh ;; get pixel ld de,00040h call sub_a0ffh ;; get pixel la0c9h: call 0bd2eh ;; mc busy printer jr c,la0c9h call 0bd28h ;; mc reset printer ld a,01bh ;; ESC call 0bd2bh ;; mc print char ld a,04bh ;; K call 0bd2bh ;; mc print char ld a,000h ;; number of columns low byte call 0bd2bh ;; mc print char ld a,(0a133h) bit 0,a jr z,la0b4h ld a,002h ;; number of columns high byte? call 0bd2bh ;; mc print char ld a,(0a12ch) ;; pixel data call 0bd2bh ;; mc print char jr la0f9h la0b4h: ld a,001h ;; number of columns high byte? call 0bd2bh ;; mc print char la0f9h: ld a,(0a12ch) ;; pixel data call 0bd2bh ;; mc print char call sub_a115h inc hl inc hl call sub_a10dh ld a,h cp 001h jp nz,sub_a050h ld a,l cp 090h jp nz,sub_a050h ld a,00ah ;; next line call 0bd2bh ;; mc print char ld a,02fh ;; 47 - space call 0bb1eh ;; km test key ret nz ld hl,(0a12dh) ld de,0000eh add hl,de ld (0a12dh),hl ld hl,00000h call sub_a10dh ld de,(0a12dh) ld a,d cp 002h jp nz,sub_a050h ld a,e cp 084h jp nz,sub_a050h ret ;; accumulate pixels sub_a0ffh: ld b,a call 0bb99h ;; txt get paper cp b ;; was the colour read the same as the paper? ret z ;; any pixel which is not the same as the paper will be considered foreground ;; and the printer will draw a dot. Any pixel the same as the paper will ;; be considered background and no dot is drawn by the printer. ;; pixel is set to foreground. accumulate it into the pixel data so far ld hl,(0a12ch) add hl,de ld (0a12ch),hl ret sub_a10dh: ld (0a12fh),hl ld (0a131h),de ret sub_a115h: ld hl,(0a12fh) ld de,(0a131h) ret sub_a11dh: call sub_a0ffh ;; accumulate a pixel for printing. call sub_a115h ;; get current X/Y graphics position inc de ;; increment X to next pixel accross screen. inc de call sub_a10dh ;; set current X/Y graphics position call 0bbf0h ;; gra test absolute ret db 00h,84h,02h,00h,00h,0eh,00h,00h,00h db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 sub_a154h: call 0bc11h ;; scr get mode cp 000h jr nz,la19dh ld b,004h la19dh: cp 001h jr nz,la1a3h ld b,002h la1a3h: cp 002h jr nz,la1a9h ld b,001h la1a9h: ld a,b la1aah: ld (data_a254),a call 0bbc6h ;; gra ask cursor ld (data_a250),hl ld (data_a250+2),de la1b7h: call 0bb99h ;; txt get paper ld (0a1f9h),a ld bc,00000h ld (data_a24c),bc ld (data_a24e),bc call sub_a210 ld a,02fh ;; 47 - space call 0bb1eh ;; km test key ret nz ld hl,(data_a24e) inc hl inc hl ld a,004h cp h jr nz,la1deh ld hl,00000h la1deh: ld (data_a24e),hl ld bc,05398h add hl,bc ld (0a1aah),hl ld de,(055e0h) ld hl,(data_a24e) sub_a1efh: ld bc,057e4h add hl,bc ld (0a1b7h),hl ld hl,(05a2ch) la1f9h: ld (la257h),hl ld (data_a255),de ld bc,00000h ld a,(data_a254) ld c,a ex de,hl add hl,bc ex de,hl call sub_a1efh and a ex de,hl sbc hl,bc ex de,hl call sub_a1efh inc hl inc hl call sub_a1efh dec hl dec hl call sub_a1efh ld hl,(data_a24e) ld de,(data_a24c) inc hl inc hl and a sbc hl,de ret z jp la18bh sub_a1efh: push de push hl push bc call 0bbf0h ;; gra test absolute pop bc pop hl pop de cp 000h jr nz,la248h ld (data_a250),hl ld (data_a250+2),de push bc call sub_0a210h pop bc la248h: ld hl,(data_a257) ld de,(data_a255) ret sub_a210: ld hl,(data_a250) ld de,(data_a250+2) call 0bbeah ;; gra plot absolute ld hl,(data_a24c) inc hl inc hl ld a,004h cp h jr nz,la267h ld hl,00000h la267h: ld (data_a24c),hl ld bc,05398h add hl,bc ld de,(data_a250+2) ld (0a237h),hl ld (05648h),de ld hl,(data_a24c) ld bc,057e4h add hl,bc ld de,(data_a250) ld (0a249),hl ld (05a94h),de ret ;;Data area data_a24c: defw 02b0h data_a24e: defw 0248h data_a250: defw 0beh data_a252: defw 0120h data_a254: defb 04h data_a255: defw 0120h data_a257: defw 0bch end