Day 12: Hello World in Assembly

Yesterday proved I need to take a step back. So let me actually take my time and write a proper ‘Hello World’ program. I’m going to do this in VS Code, since it’s just nicer to type on a 21st century editor (no offense, ZDE, you were totally awesome for the early 80s).

First thing I need to figure out is where does the stack start? I was originally confused at putting the top of the stack at 00 (where there’s a bunch of BDOS vectors), but I think that really translates to 100H, the top of the TPA, which we set with the ORG pseudo-instruction.

In the following example, I’m using both the write character call, 2, and the write string call, 9. Write string is handy – it handles the looping for you, you just have to put the address of the beginning of the string in the DE register. The only downside is the string is terminated with ‘$’ so the string can’t contain that character. There’s a good overview of all the BDOS calls here.

A few other learnings:

  • ZDE has both hard and soft tabs. I think if it detects hard tabs in the file, it switches to that mode. Likewise, you should set VS Code to use hard tabs, 8 spaces.
  • I thought some other assembler had a label limit of 5 characters, but it’s more like 16 on Z80ASM. I’m trying to limit to 6 just for formatting (any longer and I need another tab)
  • Make sure to set your editor to use CR & LF. I don’t think the assembler had a problem with LF only, but you need both for proper formatting in ZDE, which is handy if you want to make a quick edit ‘on the box’.
;HELLO WORLD FOR Z80 ASSEMBLER ;Z80ASM BY SLR SYSTEMS ;SETUP BDOS EQU 5 ;CALL FOR BDOS FUNCTIONS WCHR EQU 2 ;WRITE CHARACTER, IN REG C WSTR EQU 9 ;WRITE STRING, IN REG C RCHR EQU 1 ;READ CHAR, IN REG C RBOOT EQU 0 ;RETURN TO CP/M TPA EQU 100H ;TRANSIENT PROGRAM AREA, START HERE CR EQU 0DH ;CARRAIGE RETURN LF EQU 0AH ;LINE FEED CTRLZ EQU 1AH ;CTRL Z ORG TPA START: LD SP,STACK ;SETUP STACK POINTER BANG: LD E,"#" CALL CHOUT CALL NEWLN LD HL,HELO ;LOADS THE ADDR OF BEGIN OF MESG IN HL HELLO: LD E,(HL) ;LOAD E W/ FIRST CHAR FROM STRING LD A,E CP 255 JP Z,STRNG INC HL CALL CHOUT JP HELLO STRNG: CALL NEWLN LD DE,MESG CALL STROUT JP EXIT EXIT: JP RBOOT ;RETURN TO CCP ;STROUT - OUTPUTS A STRING WHOS ADDRESS IS IN DE REGISTER STROUT: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD C,WSTR CALL BDOS POP HL POP DE POP BC RET ;CHOUT - OUTPUT A CHARACTER THATS IN E REGISTER CHOUT: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD C,WCHR ;PUT WCHR IN C FOR BDOS CALL CALL BDOS ;CALL BDOS POP HL POP DE POP BC RET ;NEWLN - DOES WHAT IT SAYS NEWLN: LD E,CR ;NOT SURE IF WE NEED CR & LF? CALL CHOUT ;YEP, WE SEEM TO LD E,LF CALL CHOUT RET HELO: DB "HELLO WORLD!",255 MESG: DB "THIS IS A TEST OF A STRING OUT$" DS 64 ;HOLD 64 BYTES FOR STACK STACK DB 0 ;TOP OF STACK END
Code language: PHP (php)
This entry was posted in Blinking Lights. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *