title Spirograph Driver name ('SPIRO') ; This is the machine part of a BASIC-program written ; by Richard Cox, ; published in 8000 Plus, Februar 1989 ; Disassembled by W.Cirsovius ; Program will be called from BASIC by PLOT (PTS,XY(),M) ; Where ; PTS is the length of X,Y-coordinates ; XY() is the array with X,Y-coordinates ; M is the set/reset mode ROLLER equ 0b600h ; Start of roller RAM MAXCOL equ 90 ; Max line width in terms of characters RES.INI equ 086h ; Base of RES 0,(hl) SET.INI equ 0c6h ; Base of SET 0,(hl) ; ; Bank selections ; _SCBNK1 equ 81h ; Screen bank 1 _SCBNK2 equ 82h ; Screen bank 2 _TPBNK1 equ 85h ; TPA bank 1 _TPBNK2 equ 86h ; TPA bank 2 ; ; Bank I/O ports ; _SEL1 equ 0f1h ; Select memory bank 4000H-7FFFH _SEL2 equ 0f2h ; Select memory bank 8000H-BFFFH .phase 0c000h ld iy,BITexe ; Init pointer - why? ld a,(bc) ; Fetch M or a ; Test it ld a,RES.INI ; Init for reset jr z,ResPixel ld a,SET.INI ; Take set ResPixel: ld (BITbase),a ; Set base opcode for bit 0 ld c,(hl) ; Fetch PTS inc hl ld b,(hl) ex de,hl SpiroLoop: push bc ; Save count ld e,(hl) ; Fetch XY(0) - X-coordinate inc hl ld d,(hl) inc hl ld (XPos),de ; Save it ld e,(hl) ; Fetch XY(1) - Y-coordinate inc hl ld d,(hl) inc hl ld (YPos),de ; Save it push hl ; Save array pointer call AttachPix ; Set or reset pixel pop hl ; Get back array pointer pop bc ; Get back count dec bc ; Count down ld a,b or c ; Test all drawn jr nz,SpiroLoop ; Nope ret ; ; Set or reset pixel ; AttachPix: ld ix,Row ; Init coordinate address ld hl,(YPos) ; Get Y-coordinate ld a,h or a ; Verify 0..255 ret nz ; Nope ld a,l ; Get coordinate and 11111000b ; Mask it rra ; Shift into right place rra rra ld (ix+0),a ; Save row ld hl,(XPos) ; Get X-coordinate add hl,hl ; Shift into hi place add hl,hl ; (Divide HL by 8 -> add hl,hl ; HL/8 = HL*32/256 -> add hl,hl ; HIGH HL is HL/256) add hl,hl ld a,h cp MAXCOL ; Verify in range ret nc ; Nope ld (ix+1),h ; Save column call VidLine ; Get address of pixel line ld a,(YPos) ; Get Y-coordinate and 00000111b ; Mask bits ld c,a ld b,0 add hl,bc ; Position to pixel byte ld a,(XPos) ; Get X-coordinate cpl and 00000111b ; Mask bits add a,a ; Shift into right place add a,a ; Get bit position add a,a BITbase equ $+1 or SET.INI ld (BITexe),a ; Build bit position call SetReset ; Set or reset selected bit ret ; ; Get address of pixel line ; VidLine: ld l,(ix+0) ; Get row ld h,0 add hl,hl ; *16 add hl,hl add hl,hl add hl,hl ld de,ROLLER add hl,de ; Position in roller RAM call RollAddr ; Fetch address of current line ex de,hl ld a,l and 00000111b ; Mask bits ld e,a add hl,hl ld a,l and 11111000b or e ld l,a ex de,hl ld l,(ix+1) ; Get column ld h,0 add hl,hl ; *8 add hl,hl add hl,hl add hl,de ; Get address ret ; ; Set or reset selected bit ; ENTRY Reg HL points to byte to be attached ; (Pointer within screen bank) ; SetReset: di ld a,_SCBNK1 out (_SEL1),a ; Select screen bank ld a,_SCBNK2 out (_SEL2),a BITexe equ $+1 set $-$,(hl) ; Set or reset bit now ld a,_TPBNK1 out (_SEL1),a ; Select TPA bank ld a,_TPBNK2 out (_SEL2),a ei ret ; ; Fetch address of current line from roller RAM ; EXIT Reg HL points to address ; (Pointer within screen bank) ; RollAddr: di ld a,_SCBNK2 out (_SEL2),a ; Select screen bank ld e,(hl) inc hl ld d,(hl) ld a,_TPBNK2 out (_SEL2),a ; Select TPA bank ei ret ; XPos: ; X-coordinate dw 0 YPos: ; Y-coordinate dw 0 Row: db 0 ; Row db 0 ; Column ; ds 65,0 .dephase end