Now Reading
My drawing language developed at age 9

My drawing language developed at age 9

2024-03-12 16:17:22

LOCS in action

The Brand language created by Seymour Papert in 1967 was fairly well-known within the eighties as a software to show programming to children. Now in 2024, I can see it was nice to make good drawings on the display and study trigonometry, and a few very lucky children had an actual robotic turtle drawing on paper, however it wasn’t so good for instructing programming as a result of no house pc got here with Brand, it was costly, and its implementations differed drastically of their assist of necessary programming constructs.

For instance, there may be at the very least one Brand language for Commodore 64 that carried out assist for sprites, however it wasn’t transportable to different variations. I realized this the arduous approach as I wished to play a “Hunt the Dragon” sport made for C64 Brand printed within the Mi computer journal (the entire quantity comprises Brand tutorials that I used to study Brand), however Dr. Brand simply saved throwing me error messages that I didn’t perceive.

Anyway, I used to be in love with Brand, and being the daring child I used to be, I made a decision to make a Brand language for the coed’s pc developed by my father, and I might code it in Z80 machine code at age 9. Moreover, I might have forgotten this utterly if it wasn’t as a result of the handwritten program was saved away within the class folder that my father nonetheless saved and I discovered the pages the final Sunday, March 10, 2024, virtually 36 years later. I virtually could not consider it!

These are photos of the three pages composing this system. You’ll be able to see the machine code is considerably readable as a result of every instruction is separated. The ultimate web page comprises the guide!

I’m glad I put a date on the web page: Friday, September 9, 1988. It means it was written after my first Z80 machine code game, so that is my second massive machine code program.

LOCS means Lenguaje de Oscar Computadora eStudiantil (or Oscar’s language for college students’ computer systems). OTEK comes from my father’s initials (Oscar Toledo Esteva) which we used as a sort of firm identify.

My language instructions are fairly easy: BORRA clears the display, TORTUGA facilities the “turtle”, there are 4 instructions to attract (SM up, AM down, DM proper, IM left), and eventually we now have the PT command (Pone Tortuga) to position the turtle anyplace on the display.

Making it to work

This program relies upon closely on having a keyboard, so this time I gained’t port it to Colecovision to avoid wasting me time. I might assign a perform to every key within the keypad however it might require an enormous code chunk and I might find yourself rewriting this system utterly.

Anyway, right here we go analyzing it. We’ll begin by getting ready a easy MSX translation layer.


    ;
	; LOCS 
	;
	; by Oscar Toledo G.
	; (c) Copyright 1988 Oscar Toledo G.
	;
	; Creation date: Sep/09/1988. I used to be age 9.
	;

	;
	; Layer to adapt it to MSX computer systems.
	;
WRTVDP: EQU $0047       ; Set VDP handle HL.
WRTVRM: EQU $004D       ; Write byte A to VRAM handle HL.
FILVRM: EQU $0056       ; Fill VRAM handle HL with A repeated BC occasions.
SETWRT: EQU $0053       ; Set write handle HL for VDP.
CHGET:  EQU $009F       ; Learn character from keyboard into A.

VDP:    EQU $98         ; Base VDP port.

        ; MSX Cartridge header

        ORG $4000
        DB "AB"
        DW START
        DW 0
        DW 0
        DW 0
        DW 0

	;
	; Set a VDP handle to put in writing.
	;
L0100:  JP SETWRT

	;
	; Copy rapid knowledge to VRAM.
	;
L0169:  EX (SP),HL

.1:     LD A,(HL)
        OR A
        JR Z,.2
        OUT (VDP),a
        INC HL
        JR .1

.2:     EX (SP),HL
        RET

        ;
        ; Clear the display.
        ; Set display buffer to VRAM $3c00.
        ;
L04CC:
        LD BC,$0F02     ; VDP register 2 = $3c00.
        CALL WRTVDP
        LD HL,$3C00     ; Clear the display.
        LD BC,$0300     ; 32x24 grid.
        LD A,$20        ; Area character.
        JP FILVRM       ; Fill VRAM.

	;
	; Learn the keyboard.
	;
L04F5:
        CALL CHGET      ; Learn keyboard.
        CP $61          ; Is it lowercase?
        RET C
        CP $7B
        RET NC          ; No, return.
        SUB $20         ; Sure, make it uppercase.
        RET

	;
	; Learn a hexadecimal quantity in HL.
	;
READ_WORD:
        CALL READ_BYTE	; Learn a byte.
READ_BYTE:
        CALL READ_HEX	; Learn a hexadecimal digit.
READ_HEX:
        CALL L04F5	; Learn the keyboard.
        PUSH HL
        LD HL,(L87F0)	; Get cursor handle.
        CALL WRTVRM	; Show key on the display.
        INC HL
        LD (L87F0),HL	; Replace cursor handle.
        POP HL
        SUB $30		; Convert ASCII 0-9 to 0-9.
        CP $0A
        JR C,.1
        SUB $07		; Convert ASCII A-F to 10-15.
.1:     ADD HL,HL       ; Shift HL to the left 4 bits.
        ADD HL,HL
        ADD HL,HL
        ADD HL,HL
        OR L		; Add hexadecimal digit.
        LD L,A
        RET

This program calls the ROM of the educative pc. It makes use of 5 capabilities:

  1. L0100, Set VDP handle.
  2. L0169, Copy a message to VRAM.
  3. L04CC, Clear the display.
  4. L04F5, Learn the keyboard.
  5. RST $10, Learn a hexadecimal quantity into HL (4 digits).

It relies upon additionally on the display grid to be obtainable on the VRAM handle $3c00 (the MSX default is $1800) so in my translation layer for L04CC it writes the VDP register 2 to vary it.

This system begins like this:


START:
	LD SP,L87F0
	CALL L8114
	CALL L0100
	CALL L0169
	DB "LOCS OTEK",0
    IF 0
	LD HL,$3C41
	CALL L0100
	CALL L0169
	DB "32 BYTES",0
    ELSE
	DB 0,0,0
	DB 0,0,0
	DB 0,0,0
	DB 0,0,0,0
	DB 0,0,0,0
	DB 0
    ENDIF

It units the stack pointer on the preliminary handle for the 2K RAM college students pc, and instantly the code is patched earlier than exhibiting this system title.


L8114:	CALL L8075
	LD HL,$3C01
	RET

L8075:	LD HL,$3D50
	LD (L86F0),HL
	CALL L04CC
	RET

The patch units the “turtle” place to $3D50 (the middle of the display), this place is saved within the L86F0 handle, then it clears the display calling L04CC, after which hundreds HL with $3C01 to level to the highest left of the display. Discover it is not precisely $3C00 however $3c01 as a result of my Sony Trinitron TV of the time “ate” the primary column.

It took me most likely half an hour to find what I patched with tons of handwritten zero bytes (NOP directions), and it was merely an additional message saying “32 BYTES”. I feel that Dr. Brand confirmed the overall bytes obtainable for this system, and I feel that saying 32 bytes was my joke as a result of there is not such factor as a reminiscence supervisor.


L8028:
        CALL L81C1
        CALL L807F
        CALL L0169
        DB "GRAFICO",0
        LD HL,$3EE1
        CALL L8063
        LD A,$3E
        OUT (VDP),A
        LD (L86F2),HL
        LD DE,L8700
L8049:
        CALL L04F5
        LD (DE),A
        INC DE
        CP $0D
        JR Z,L8068
        LD HL,(L86F2)
        PUSH AF
        CALL L0100
        POP AF
        OUT (VDP),A
        INC HL
        LD (L86F2),HL
        JP L8049

L8063:
        CALL L0100
        INC HL
        RET

L807F:
        PUSH HL
        LD HL,(L86F0)
        CALL L0100
        LD A,$2A
        OUT (VDP),A
        POP HL
        CALL L0100
        RET

L81C1: 
        LD HL,$0118     ; Redefine the # character
        CALL L0100      ; as a strong block.
        LD B,$08
L81C9:
        LD A,$FF
        OUT (VDP),A
        DJNZ L81C9
L81CF: 
        LD HL,$0918
        CALL L0100
        LD B,$08
L81D7:
        LD A,$FF
        OUT (VDP),A
        DJNZ L81D7
        LD HL,$1118
        CALL L0100
        LD B,$08
L81E5:
        LD A,$FF
        OUT (VDP),A
        DJNZ L81E5
        LD HL,$3EC1	; Level to command space.
        RET

The principle loop begins by calling L81C1, clearly a patch, as a result of it ends setting HL to $3EC1 (the command space on the display), however first it redefines the # character to be a strong block. The redefinition is finished in three areas of VRAM as a result of the educative pc was hardcoded to VDP mode 2, however the MSX begins in mode 0, so solely the primary loop is critical however I saved all of it.

The subsequent name jumps to L807F to attract the “turtle” within the present place. An asterisk, I am stunned I did not even attempt to attract a turtle. On the finish of the L807F it calls L0100 to level to the VRAM handle for the command space.

Now it exhibits a “GRAFICO” message (akin to a READY message), and within the subsequent row ($3EE1 in VRAM) it places a > signal to attend for the keyboard. Discover the L8063 patch as a result of I could not match an INC HL to avoid wasting the present handle in VRAM at L86F2.

There isn’t any cursor, it merely waits for the keyboard and shows the typed key on the display (L86F2 comprises the present handle in VRAM), and saves the important thing additionally within the RAM buffer situated at L8700. I’ve moved early the CP $0D comparability ready for the Enter key, so it does not present trash in MSX, as a result of within the educative pc that character wasn’t outlined so when displayed it was invisible.

It does not deal with the backspace key, so you must assume earlier than typing something.

In your command

At this level, it begins processing the language instructions:


L8068:
        LD A,(L8700)
	CP $42
	JR NZ,L808F
	CALL L04CC
	JP L8028

The primary carried out command is “BORRA”, however on the time I did not know the right way to evaluate entire phrases, so it merely checks for the primary letter “B” (ASCII $42), calls L04CC and jumps again to L8028.


L808F:
        CP $54
        JR NZ,L80BF
        LD HL,(L86F0)
        CALL L0100
        LD A,$20
        OUT (VDP),A
        LD HL,$3D50
        LD (L86F0),HL
        CALL L0100
        LD A,$2A
        OUT (VDP),A
        CALL L80B0
        JP L8028

L80B0: 
        LD HL,$3EC1
L80B3:
        CALL L0100
        LD B,$40
L80B8:
        LD A,$20
        OUT (VDP),A
        DJNZ L80B8
        RET

The second command is “TORTUGA” (T). It merely will get the present place of the turtle, places an area character to erase it, facilities it once more on the display, and attracts it once more. Apparently I forgot I had a turtle drawing subroutine at L807F, or that the L8028 bounce already attracts the turtle.


L80BF:
        CP $53		
        JR NZ,L80E6
        LD A,(L8700+3)
        SUB $30
        LD B,A
L80C9:
        LD HL,(L86F0)
        CALL L0100
        LD A,$23
        OUT (VDP),A
        LD DE,$0020
        SBC HL,DE
        LD (L86F0),HL
        DJNZ L80C9
        CALL L80B0
        CALL L807F
        JP L8028

The third command is “SM” (S). It expects the size within the fourth byte as a digit, so you should sort precisely SM adopted by an area and the digit.

It converts the digit to a price between 0-9 and saves it into B as counter. It takes the present place of the turtle and attracts a block, displaces the pointer, and repeats. It ends clearing the command space, redrawing the turtle, and leaping again to the principle loop.

Discover it by no means validates the size, zero will draw 256 blocks.

See Also

Did I say block? Proper, I did not know something about pixels, so when you do not have pixels, you’ve got blocks, proper? A really daring child.


L80E6:
        CP $44
        JR NZ,L811B
        LD A,(L8700+3)
        SUB $30
        LD B,A
L80F0:
        LD HL,(L86F0)
        CALL L0100
        LD A,$23
        OUT (VDP),A
        LD DE,$0001
        ADD HL,DE
        NOP
        LD (L86F0),HL
        DJNZ L80F0
        CALL L80B0
        CALL L807F
        JP L8028

The fourth command is “DM” (D). It’s precisely the identical code, I solely modified the displacement offset to go the precise.


L811B:
        CP $41
        JR NZ,L8142
        LD A,(L8700+3)
        SUB $30
        LD B,A
L8125:
        LD HL,(L86F0)
        CALL L0100
        LD A,$23
        OUT (VDP),A
        LD DE,$0020
        ADD HL,DE
        NOP
        LD (L86F0),HL
        DJNZ L8125
        CALL L80B0
        CALL L807F
        JP L8028

L8142:
        CP $49
        JR NZ,L8169
        LD A,(L8700+3)
        SUB $30
        LD B,A
L814C:
        LD HL,(L86F0)
        CALL L0100
        LD A,$23
        OUT (VDP),A
        LD DE,$0001
        SBC HL,DE
        LD (L86F0),HL
        DJNZ L814C      
        CALL L80B0 
        CALL L807F
        JP L8028

The fifth command is “AM” (A) for taking place, and the sixth command “IM” (I) for going to left. Once more, I solely modified the displacement offsets. I might have saved tons of bytes by having a generic drawing subroutine the place you can present an offset, however I used to be nonetheless studying, and doubtless afraid of juggling with registers.


L8169:
        CP $50
        JR NZ,L8194-1
        LD HL,$3EE5
        LD (L87F0),HL
        CALL READ_WORD  ; Modified from RST $10
        LD D,H
        LD E,L
        LD HL,(L86F0)
        CALL L0100
        LD A,$20
        OUT (VDP),A
        LD HL,$3C00
        ADD HL,DE
        LD (L86F0),HL
        CALL L0100
        LD A,$2A
        OUT (VDP),A
        CALL L80B0
        JP L8028

The seventh command is “PT”. It units a place for the inner cursor by studying a hexadecimal phrase into HL that’s saved instantly into DE. It deletes the turtle from the display, and repositions it on the DE place added $3c00 to place it into the precise VRAM handle. Nearly the identical code because the TORTUGA command, and once more I forgot I had a turtle redraw subroutine.

By the way in which, there’s a tiny bug right here. Within the machine code I calculated wrongly the relative bounce JR NZ and it jumps one byte earlier than the precise handle, because the opcode $81 is an ADD instruction, it does not have an effect on and it really works good ($41 in MSX, LD B,C)


L8194:
        LD HL,$3C01
        CALL L0100
        CALL L0169
        DB "* ERROR *",0
        LD B,$05
L81A9:
        PUSH BC
        LD BC,$0000
L81AD:
        DEC BC
        LD A,B
        OR C
        JR NZ,L81AD
        POP BC
        DJNZ L81A9
        LD HL,$3C00
        CALL L80B3
        CALL L80B0
        JP L8028

Lastly, my LOCS program ends with an error message for an unrecognized command. It does an enormous delay, erases it, and returns to the principle loop.

I’ve made a tiny video exhibiting my LOCS program in motion.

Downloads

You’ll be able to obtain the unique LOCS program (495 bytes), and the MSX tailored model (589 bytes with the interpretation layer), together with the unique assembler code for each.

  • Obtain locs.zip (4.33 kb) containing assembler supply code and binaries.
You’ll be able to assemble it with my all-new assembler Gasm80 (obtainable from https://github.com/nanochess/gasm80) or with TNIasm v0.45.

Epilogue

To be a whole language it might want variables, expressions, and at the very least a conditional loop. However does not matter, HTML is known as a language and does not have this!

I did not perceive precisely how angles labored on the time so there are none in any respect in my program. The usage of blocks as an alternative of pixels was loopy, additionally the dearth of validation of the consumer’s typing, however I can perceive I used to be fairly enthusiastic (detecting instructions with one single letter!) and I empirically found the precept of “it’s higher to have it working than having nothing”.

Through the years I saved engaged on compilers and interpreters for a number of languages going from BASIC to Pascal after which C, perhaps later I will speak about this. However it wasn’t till 2014 that I made once more my very own language: IntyBASIC, a dialect of BASIC with devoted statements for Intellivision consoles, and extra not too long ago CVBasic.

Associated hyperlinks

Final modified: Mar/12/2024

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top